From 556a4f3870bacf144dee4fc7993c336ee4f1cd06 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Fri, 9 Feb 2024 23:53:39 +0100 Subject: [PATCH 01/98] BCI-2525: check all responses on transaction submission (#11599) * sendTx: signal success if one of the nodes accepted transaction * fix logger * fix merge * fix race * fixed multinode tests race * improve test coverage * WIP: wait for 70% of nodes to reply on send TX * tests * Report invariant violation via prom metrics * fixed sendTx tests * address comments * polish PR * Describe implementation details in the comment to SendTransaction * nit fixes * more fixes * use softTimeOut default value * nit fix * ensure all goroutines are done before Close * refactor broadcast * use sendTxSuccessfulCodes slice to identify if result is successful --------- Co-authored-by: Prashant Yadav <34992934+prashantkumar1982@users.noreply.github.com> --- common/client/models.go | 7 + common/client/multi_node.go | 223 +++++++++++++++--- common/client/multi_node_test.go | 299 ++++++++++++++++++++----- core/chains/evm/client/chain_client.go | 5 +- core/chains/evm/client/errors.go | 28 ++- 5 files changed, 454 insertions(+), 108 deletions(-) diff --git a/common/client/models.go b/common/client/models.go index bd974f901fc..d0cf42a3844 100644 --- a/common/client/models.go +++ b/common/client/models.go @@ -18,8 +18,15 @@ const ( InsufficientFunds // Tx was rejected due to insufficient funds. ExceedsMaxFee // Attempt's fee was higher than the node's limit and got rejected. FeeOutOfValidRange // This error is returned when we use a fee price suggested from an RPC, but the network rejects the attempt due to an invalid range(mostly used by L2 chains). Retry by requesting a new suggested fee price. + sendTxReturnCodeLen // tracks the number of errors. Must always be last ) +// sendTxSevereErrors - error codes which signal that transaction would never be accepted in its current form by the node +var sendTxSevereErrors = []SendTxReturnCode{Fatal, Underpriced, Unsupported, ExceedsMaxFee, FeeOutOfValidRange, Unknown} + +// sendTxSuccessfulCodes - error codes which signal that transaction was accepted by the node +var sendTxSuccessfulCodes = []SendTxReturnCode{Successful, TransactionAlreadyKnown} + type NodeTier int const ( diff --git a/common/client/multi_node.go b/common/client/multi_node.go index 7d55784e68f..c03c3fbcd61 100644 --- a/common/client/multi_node.go +++ b/common/client/multi_node.go @@ -3,7 +3,9 @@ package client import ( "context" "fmt" + "math" "math/big" + "slices" "sync" "time" @@ -26,6 +28,11 @@ var ( Name: "multi_node_states", Help: "The number of RPC nodes currently in the given state for the given chain", }, []string{"network", "chainId", "state"}) + // PromMultiNodeInvariantViolations reports violation of our assumptions + PromMultiNodeInvariantViolations = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "multi_node_invariant_violations", + Help: "The number of invariant violations", + }, []string{"network", "chainId", "invariant"}) ErroringNodeError = fmt.Errorf("no live nodes available") ) @@ -94,6 +101,7 @@ type multiNode[ leaseTicker *time.Ticker chainFamily string reportInterval time.Duration + sendTxSoftTimeout time.Duration // defines max waiting time from first response til responses evaluation activeMu sync.RWMutex activeNode Node[CHAIN_ID, HEAD, RPC_CLIENT] @@ -101,7 +109,7 @@ type multiNode[ chStop services.StopChan wg sync.WaitGroup - sendOnlyErrorParser func(err error) SendTxReturnCode + classifySendTxError func(tx TX, err error) SendTxReturnCode } func NewMultiNode[ @@ -127,13 +135,16 @@ func NewMultiNode[ chainID CHAIN_ID, chainType config.ChainType, chainFamily string, - sendOnlyErrorParser func(err error) SendTxReturnCode, + classifySendTxError func(tx TX, err error) SendTxReturnCode, + sendTxSoftTimeout time.Duration, ) MultiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT] { nodeSelector := newNodeSelector(selectionMode, nodes) - // Prometheus' default interval is 15s, set this to under 7.5s to avoid // aliasing (see: https://en.wikipedia.org/wiki/Nyquist_frequency) const reportInterval = 6500 * time.Millisecond + if sendTxSoftTimeout == 0 { + sendTxSoftTimeout = QueryTimeout / 2 + } c := &multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]{ nodes: nodes, sendonlys: sendonlys, @@ -146,8 +157,9 @@ func NewMultiNode[ chStop: make(services.StopChan), leaseDuration: leaseDuration, chainFamily: chainFamily, - sendOnlyErrorParser: sendOnlyErrorParser, + classifySendTxError: classifySendTxError, reportInterval: reportInterval, + sendTxSoftTimeout: sendTxSoftTimeout, } c.lggr.Debugf("The MultiNode is configured to use NodeSelectionMode: %s", selectionMode) @@ -545,45 +557,188 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().SendEmptyTransaction(ctx, newTxAttempt, seq, gasLimit, fee, fromAddress) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SendTransaction(ctx context.Context, tx TX) error { - main, nodeError := c.selectNode() - var all []SendOnlyNode[CHAIN_ID, RPC_CLIENT] - for _, n := range c.nodes { - all = append(all, n) +type sendTxResult struct { + Err error + ResultCode SendTxReturnCode +} + +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) broadcastTxAsync(ctx context.Context, + n SendOnlyNode[CHAIN_ID, RPC_CLIENT], tx TX) sendTxResult { + txErr := n.RPC().SendTransaction(ctx, tx) + c.lggr.Debugw("Node sent transaction", "name", n.String(), "tx", tx, "err", txErr) + resultCode := c.classifySendTxError(tx, txErr) + if !slices.Contains(sendTxSuccessfulCodes, resultCode) { + c.lggr.Warnw("RPC returned error", "name", n.String(), "tx", tx, "err", txErr) } - all = append(all, c.sendonlys...) - for _, n := range all { - if n == main { - // main node is used at the end for the return value - continue + + return sendTxResult{Err: txErr, ResultCode: resultCode} +} + +// collectTxResults - refer to SendTransaction comment for implementation details, +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) collectTxResults(ctx context.Context, tx TX, txResults <-chan sendTxResult) error { + // combine context and stop channel to ensure we stop, when signal received + ctx, cancel := c.chStop.Ctx(ctx) + defer cancel() + requiredResults := int(math.Ceil(float64(len(c.nodes)) * sendTxQuorum)) + errorsByCode := map[SendTxReturnCode][]error{} + var softTimeoutChan <-chan time.Time + var resultsCount int +loop: + for { + select { + case <-ctx.Done(): + c.lggr.Debugw("Failed to collect of the results before context was done", "tx", tx, "errorsByCode", errorsByCode) + return ctx.Err() + case result := <-txResults: + errorsByCode[result.ResultCode] = append(errorsByCode[result.ResultCode], result.Err) + resultsCount++ + if slices.Contains(sendTxSuccessfulCodes, result.ResultCode) || resultsCount >= requiredResults { + break loop + } + case <-softTimeoutChan: + c.lggr.Debugw("Send Tx soft timeout expired - returning responses we've collected so far", "tx", tx, "resultsCount", resultsCount, "requiredResults", requiredResults) + break loop } - // Parallel send to all other nodes with ignored return value - // Async - we do not want to block the main thread with secondary nodes - // in case they are unreliable/slow. - // It is purely a "best effort" send. - // Resource is not unbounded because the default context has a timeout. - ok := c.IfNotStopped(func() { - // Must wrap inside IfNotStopped to avoid waitgroup racing with Close - c.wg.Add(1) + + if softTimeoutChan == nil { + tm := time.NewTimer(c.sendTxSoftTimeout) + softTimeoutChan = tm.C + // we are fine with stopping timer at the end of function + //nolint + defer tm.Stop() + } + } + + // ignore critical error as it's reported in reportSendTxAnomalies + result, _ := aggregateTxResults(errorsByCode) + return result + +} + +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) reportSendTxAnomalies(tx TX, txResults <-chan sendTxResult) { + defer c.wg.Done() + resultsByCode := map[SendTxReturnCode][]error{} + // txResults eventually will be closed + for txResult := range txResults { + resultsByCode[txResult.ResultCode] = append(resultsByCode[txResult.ResultCode], txResult.Err) + } + + _, criticalErr := aggregateTxResults(resultsByCode) + if criticalErr != nil { + c.lggr.Criticalw("observed invariant violation on SendTransaction", "tx", tx, "resultsByCode", resultsByCode, "err", criticalErr) + c.SvcErrBuffer.Append(criticalErr) + PromMultiNodeInvariantViolations.WithLabelValues(c.chainFamily, c.chainID.String(), criticalErr.Error()).Inc() + } +} + +func aggregateTxResults(resultsByCode map[SendTxReturnCode][]error) (txResult error, err error) { + severeErrors, hasSevereErrors := findFirstIn(resultsByCode, sendTxSevereErrors) + successResults, hasSuccess := findFirstIn(resultsByCode, sendTxSuccessfulCodes) + if hasSuccess { + // We assume that primary node would never report false positive txResult for a transaction. + // Thus, if such case occurs it's probably due to misconfiguration or a bug and requires manual intervention. + if hasSevereErrors { + const errMsg = "found contradictions in nodes replies on SendTransaction: got success and severe error" + // return success, since at least 1 node has accepted our broadcasted Tx, and thus it can now be included onchain + return successResults[0], fmt.Errorf(errMsg) + } + + // other errors are temporary - we are safe to return success + return successResults[0], nil + } + + if hasSevereErrors { + return severeErrors[0], nil + } + + // return temporary error + for _, result := range resultsByCode { + return result[0], nil + } + + err = fmt.Errorf("expected at least one response on SendTransaction") + return err, err +} + +const sendTxQuorum = 0.7 + +// SendTransaction - broadcasts transaction to all the send-only and primary nodes regardless of their health. +// A returned nil or error does not guarantee that the transaction will or won't be included. Additional checks must be +// performed to determine the final state. +// +// Send-only nodes' results are ignored as they tend to return false-positive responses. Broadcast to them is necessary +// to speed up the propagation of TX in the network. +// +// Handling of primary nodes' results consists of collection and aggregation. +// In the collection step, we gather as many results as possible while minimizing waiting time. This operation succeeds +// on one of the following conditions: +// * Received at least one success +// * Received at least one result and `sendTxSoftTimeout` expired +// * Received results from the sufficient number of nodes defined by sendTxQuorum. +// The aggregation is based on the following conditions: +// * If there is at least one success - returns success +// * If there is at least one terminal error - returns terminal error +// * If there is both success and terminal error - returns success and reports invariant violation +// * Otherwise, returns any (effectively random) of the errors. +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SendTransaction(ctx context.Context, tx TX) error { + if len(c.nodes) == 0 { + return ErroringNodeError + } + + txResults := make(chan sendTxResult, len(c.nodes)) + // Must wrap inside IfNotStopped to avoid waitgroup racing with Close + ok := c.IfNotStopped(func() { + c.wg.Add(len(c.sendonlys)) + // fire-n-forget, as sendOnlyNodes can not be trusted with result reporting + for _, n := range c.sendonlys { go func(n SendOnlyNode[CHAIN_ID, RPC_CLIENT]) { defer c.wg.Done() + c.broadcastTxAsync(ctx, n, tx) + }(n) + } - txErr := n.RPC().SendTransaction(ctx, tx) - c.lggr.Debugw("Sendonly node sent transaction", "name", n.String(), "tx", tx, "err", txErr) - sendOnlyError := c.sendOnlyErrorParser(txErr) - if sendOnlyError != Successful { - c.lggr.Warnw("RPC returned error", "name", n.String(), "tx", tx, "err", txErr) - } + var primaryBroadcastWg sync.WaitGroup + primaryBroadcastWg.Add(len(c.nodes)) + txResultsToReport := make(chan sendTxResult, len(c.nodes)) + for _, n := range c.nodes { + go func(n SendOnlyNode[CHAIN_ID, RPC_CLIENT]) { + defer primaryBroadcastWg.Done() + result := c.broadcastTxAsync(ctx, n, tx) + // both channels are sufficiently buffered, so we won't be locked + txResultsToReport <- result + txResults <- result }(n) - }) - if !ok { - c.lggr.Debug("Cannot send transaction on sendonly node; MultiNode is stopped", "node", n.String()) } + + c.wg.Add(1) + go func() { + // wait for primary nodes to finish the broadcast before closing the channel + primaryBroadcastWg.Wait() + close(txResultsToReport) + close(txResults) + c.wg.Done() + }() + + c.wg.Add(1) + go c.reportSendTxAnomalies(tx, txResultsToReport) + + }) + if !ok { + return fmt.Errorf("aborted while broadcasting tx - multiNode is stopped: %w", context.Canceled) } - if nodeError != nil { - return nodeError + + return c.collectTxResults(ctx, tx, txResults) +} + +// findFirstIn - returns first existing value for the slice of keys +func findFirstIn[K comparable, V any](set map[K]V, keys []K) (V, bool) { + for _, k := range keys { + if v, ok := set[k]; ok { + return v, true + } } - return main.RPC().SendTransaction(ctx, tx) + var v V + return v, false } func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SequenceAt(ctx context.Context, account ADDR, blockNumber *big.Int) (s SEQ, err error) { diff --git a/common/client/multi_node_test.go b/common/client/multi_node_test.go index 82af7411080..3ffc82572c2 100644 --- a/common/client/multi_node_test.go +++ b/common/client/multi_node_test.go @@ -1,9 +1,10 @@ package client import ( + "context" "errors" "fmt" - big "math/big" + "math/big" "math/rand" "testing" "time" @@ -38,7 +39,8 @@ type multiNodeOpts struct { chainID types.ID chainType config.ChainType chainFamily string - sendOnlyErrorParser func(err error) SendTxReturnCode + classifySendTxError func(tx any, err error) SendTxReturnCode + sendTxSoftTimeout time.Duration } func newTestMultiNode(t *testing.T, opts multiNodeOpts) testMultiNode { @@ -49,7 +51,7 @@ func newTestMultiNode(t *testing.T, opts multiNodeOpts) testMultiNode { result := NewMultiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient](opts.logger, opts.selectionMode, opts.leaseDuration, opts.noNewHeadsThreshold, opts.nodes, opts.sendonlys, - opts.chainID, opts.chainType, opts.chainFamily, opts.sendOnlyErrorParser) + opts.chainID, opts.chainType, opts.chainFamily, opts.classifySendTxError, opts.sendTxSoftTimeout) return testMultiNode{ result.(*multiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient]), @@ -559,77 +561,252 @@ func TestMultiNode_BatchCallContextAll(t *testing.T) { func TestMultiNode_SendTransaction(t *testing.T) { t.Parallel() - t.Run("Fails if failed to select active node", func(t *testing.T) { - chainID := types.RandomID() - mn := newTestMultiNode(t, multiNodeOpts{ + classifySendTxError := func(tx any, err error) SendTxReturnCode { + if err != nil { + return Fatal + } + + return Successful + } + newNode := func(t *testing.T, txErr error, sendTxRun func(args mock.Arguments)) *mockNode[types.ID, types.Head[Hashable], multiNodeRPCClient] { + rpc := newMultiNodeRPCClient(t) + rpc.On("SendTransaction", mock.Anything, mock.Anything).Return(txErr).Run(sendTxRun).Maybe() + node := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) + node.On("String").Return("node name").Maybe() + node.On("RPC").Return(rpc).Maybe() + node.On("Close").Return(nil).Once() + return node + } + newStartedMultiNode := func(t *testing.T, opts multiNodeOpts) testMultiNode { + mn := newTestMultiNode(t, opts) + err := mn.StartOnce("startedTestMultiNode", func() error { return nil }) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, mn.Close()) + }) + return mn + } + t.Run("Fails if there is no nodes available", func(t *testing.T) { + mn := newStartedMultiNode(t, multiNodeOpts{ selectionMode: NodeSelectionModeRoundRobin, - chainID: chainID, + chainID: types.RandomID(), }) - nodeSelector := newMockNodeSelector[types.ID, types.Head[Hashable], multiNodeRPCClient](t) - nodeSelector.On("Select").Return(nil).Once() - nodeSelector.On("Name").Return("MockedNodeSelector").Once() - mn.nodeSelector = nodeSelector err := mn.SendTransaction(tests.Context(t), nil) - require.EqualError(t, err, ErroringNodeError.Error()) + assert.EqualError(t, err, ErroringNodeError.Error()) }) - t.Run("Returns error if RPC call fails for active node", func(t *testing.T) { + t.Run("Transaction failure happy path", func(t *testing.T) { chainID := types.RandomID() - rpc := newMultiNodeRPCClient(t) - expectedError := errors.New("rpc failed to do the batch call") - rpc.On("SendTransaction", mock.Anything, mock.Anything).Return(expectedError).Once() - node := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) - node.On("RPC").Return(rpc) - nodeSelector := newMockNodeSelector[types.ID, types.Head[Hashable], multiNodeRPCClient](t) - nodeSelector.On("Select").Return(node).Once() - mn := newTestMultiNode(t, multiNodeOpts{ - selectionMode: NodeSelectionModeRoundRobin, - chainID: chainID, + expectedError := errors.New("transaction failed") + mainNode := newNode(t, expectedError, nil) + lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) + mn := newStartedMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: chainID, + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{mainNode}, + sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{newNode(t, errors.New("unexpected error"), nil)}, + classifySendTxError: classifySendTxError, + logger: lggr, }) - mn.nodeSelector = nodeSelector err := mn.SendTransaction(tests.Context(t), nil) require.EqualError(t, err, expectedError.Error()) + tests.AssertLogCountEventually(t, observedLogs, "Node sent transaction", 2) + tests.AssertLogCountEventually(t, observedLogs, "RPC returned error", 2) }) - t.Run("Returns result of main node and logs secondary nodes results", func(t *testing.T) { - // setup RPCs - failedRPC := newMultiNodeRPCClient(t) - failedRPC.On("SendTransaction", mock.Anything, mock.Anything). - Return(errors.New("rpc failed to do the batch call")).Once() - okRPC := newMultiNodeRPCClient(t) - okRPC.On("SendTransaction", mock.Anything, mock.Anything).Return(nil).Twice() - - // setup ok and failed auxiliary nodes - okNode := newMockSendOnlyNode[types.ID, multiNodeRPCClient](t) - okNode.On("RPC").Return(okRPC).Once() - okNode.On("String").Return("okNode") - failedNode := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) - failedNode.On("RPC").Return(failedRPC).Once() - failedNode.On("String").Return("failedNode") - - // setup main node - mainNode := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) - mainNode.On("RPC").Return(okRPC) - nodeSelector := newMockNodeSelector[types.ID, types.Head[Hashable], multiNodeRPCClient](t) - nodeSelector.On("Select").Return(mainNode).Once() + t.Run("Transaction success happy path", func(t *testing.T) { + chainID := types.RandomID() + mainNode := newNode(t, nil, nil) lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) + mn := newStartedMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: chainID, + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{mainNode}, + sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{newNode(t, errors.New("unexpected error"), nil)}, + classifySendTxError: classifySendTxError, + logger: lggr, + }) + err := mn.SendTransaction(tests.Context(t), nil) + require.NoError(t, err) + tests.AssertLogCountEventually(t, observedLogs, "Node sent transaction", 2) + tests.AssertLogCountEventually(t, observedLogs, "RPC returned error", 1) + }) + t.Run("Context expired before collecting sufficient results", func(t *testing.T) { + chainID := types.RandomID() + testContext, testCancel := context.WithCancel(tests.Context(t)) + defer testCancel() + mainNode := newNode(t, errors.New("unexpected error"), func(_ mock.Arguments) { + // block caller til end of the test + <-testContext.Done() + }) + mn := newStartedMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: chainID, + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{mainNode}, + classifySendTxError: classifySendTxError, + }) + requestContext, cancel := context.WithCancel(tests.Context(t)) + cancel() + err := mn.SendTransaction(requestContext, nil) + require.EqualError(t, err, "context canceled") + }) + t.Run("Soft timeout stops results collection", func(t *testing.T) { + chainID := types.RandomID() + expectedError := errors.New("tmp error") + fastNode := newNode(t, expectedError, nil) + // hold reply from the node till end of the test + testContext, testCancel := context.WithCancel(tests.Context(t)) + defer testCancel() + slowNode := newNode(t, errors.New("transaction failed"), func(_ mock.Arguments) { + // block caller til end of the test + <-testContext.Done() + }) + mn := newStartedMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: chainID, + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{fastNode, slowNode}, + classifySendTxError: classifySendTxError, + sendTxSoftTimeout: tests.TestInterval, + }) + err := mn.SendTransaction(tests.Context(t), nil) + require.EqualError(t, err, expectedError.Error()) + }) + t.Run("Returns success without waiting for the rest of the nodes", func(t *testing.T) { + chainID := types.RandomID() + fastNode := newNode(t, nil, nil) + // hold reply from the node till end of the test + testContext, testCancel := context.WithCancel(tests.Context(t)) + defer testCancel() + slowNode := newNode(t, errors.New("transaction failed"), func(_ mock.Arguments) { + // block caller til end of the test + <-testContext.Done() + }) + slowSendOnly := newNode(t, errors.New("send only failed"), func(_ mock.Arguments) { + // block caller til end of the test + <-testContext.Done() + }) + lggr, observedLogs := logger.TestObserved(t, zap.WarnLevel) mn := newTestMultiNode(t, multiNodeOpts{ - selectionMode: NodeSelectionModeRoundRobin, - chainID: types.RandomID(), - nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{failedNode, mainNode}, - sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{okNode}, - logger: lggr, - sendOnlyErrorParser: func(err error) SendTxReturnCode { - if err != nil { - return Fatal - } - - return Successful - }, + logger: lggr, + selectionMode: NodeSelectionModeRoundRobin, + chainID: chainID, + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{fastNode, slowNode}, + sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{slowSendOnly}, + classifySendTxError: classifySendTxError, + sendTxSoftTimeout: tests.TestInterval, }) - mn.nodeSelector = nodeSelector - + assert.NoError(t, mn.StartOnce("startedTestMultiNode", func() error { return nil })) err := mn.SendTransaction(tests.Context(t), nil) require.NoError(t, err) - tests.AssertLogEventually(t, observedLogs, "Sendonly node sent transaction") - tests.AssertLogEventually(t, observedLogs, "RPC returned error") + testCancel() + require.NoError(t, mn.Close()) + tests.AssertLogEventually(t, observedLogs, "observed invariant violation on SendTransaction") + }) + t.Run("Fails when closed", func(t *testing.T) { + mn := newTestMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: types.RandomID(), + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{newNode(t, nil, nil)}, + sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{newNode(t, nil, nil)}, + classifySendTxError: classifySendTxError, + }) + err := mn.StartOnce("startedTestMultiNode", func() error { return nil }) + require.NoError(t, err) + require.NoError(t, mn.Close()) + err = mn.SendTransaction(tests.Context(t), nil) + require.EqualError(t, err, "aborted while broadcasting tx - multiNode is stopped: context canceled") }) } + +func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { + t.Parallel() + // ensure failure on new SendTxReturnCode + codesToCover := map[SendTxReturnCode]struct{}{} + for code := Successful; code < sendTxReturnCodeLen; code++ { + codesToCover[code] = struct{}{} + } + + testCases := []struct { + Name string + ExpectedTxResult string + ExpectedCriticalErr string + ResultsByCode map[SendTxReturnCode][]error + }{ + { + Name: "Returns success and logs critical error on success and Fatal", + ExpectedTxResult: "success", + ExpectedCriticalErr: "found contradictions in nodes replies on SendTransaction: got success and severe error", + ResultsByCode: map[SendTxReturnCode][]error{ + Successful: {errors.New("success")}, + Fatal: {errors.New("fatal")}, + }, + }, + { + Name: "Returns TransactionAlreadyKnown and logs critical error on TransactionAlreadyKnown and Fatal", + ExpectedTxResult: "tx_already_known", + ExpectedCriticalErr: "found contradictions in nodes replies on SendTransaction: got success and severe error", + ResultsByCode: map[SendTxReturnCode][]error{ + TransactionAlreadyKnown: {errors.New("tx_already_known")}, + Unsupported: {errors.New("unsupported")}, + }, + }, + { + Name: "Prefers sever error to temporary", + ExpectedTxResult: "underpriced", + ExpectedCriticalErr: "", + ResultsByCode: map[SendTxReturnCode][]error{ + Retryable: {errors.New("retryable")}, + Underpriced: {errors.New("underpriced")}, + }, + }, + { + Name: "Returns temporary error", + ExpectedTxResult: "retryable", + ExpectedCriticalErr: "", + ResultsByCode: map[SendTxReturnCode][]error{ + Retryable: {errors.New("retryable")}, + }, + }, + { + Name: "Insufficient funds is treated as error", + ExpectedTxResult: "", + ExpectedCriticalErr: "", + ResultsByCode: map[SendTxReturnCode][]error{ + Successful: {nil}, + InsufficientFunds: {errors.New("insufficientFunds")}, + }, + }, + { + Name: "Logs critical error on empty ResultsByCode", + ExpectedTxResult: "expected at least one response on SendTransaction", + ExpectedCriticalErr: "expected at least one response on SendTransaction", + ResultsByCode: map[SendTxReturnCode][]error{}, + }, + } + + for _, testCase := range testCases { + for code := range testCase.ResultsByCode { + delete(codesToCover, code) + } + t.Run(testCase.Name, func(t *testing.T) { + txResult, err := aggregateTxResults(testCase.ResultsByCode) + if testCase.ExpectedTxResult == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, txResult, testCase.ExpectedTxResult) + } + + if testCase.ExpectedCriticalErr == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, testCase.ExpectedCriticalErr) + } + }) + } + + // explicitly signal that following codes are properly handled in aggregateTxResults, + //but dedicated test cases won't be beneficial + for _, codeToIgnore := range []SendTxReturnCode{Unknown, ExceedsMaxFee, FeeOutOfValidRange} { + delete(codesToCover, codeToIgnore) + } + assert.Empty(t, codesToCover, "all of the SendTxReturnCode must be covered by this test") + +} diff --git a/core/chains/evm/client/chain_client.go b/core/chains/evm/client/chain_client.go index 5dd70992382..2a5a37da47c 100644 --- a/core/chains/evm/client/chain_client.go +++ b/core/chains/evm/client/chain_client.go @@ -73,7 +73,10 @@ func NewChainClient( chainID, chainType, "EVM", - ClassifySendOnlyError, + func(tx *types.Transaction, err error) commonclient.SendTxReturnCode { + return ClassifySendError(err, logger.Sugared(logger.Nop()), tx, common.Address{}, chainType.IsL2()) + }, + 0, // use the default value provided by the implementation ) return &chainClient{ multiNode: multiNode, diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index bb748cb52fb..67197b764a0 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/logger" + commonclient "github.com/smartcontractkit/chainlink/v2/common/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/label" ) @@ -311,6 +312,17 @@ func (s *SendError) IsTimeout() bool { return errors.Is(s.err, context.DeadlineExceeded) } +// IsCanceled indicates if the error was caused by an context cancellation +func (s *SendError) IsCanceled() bool { + if s == nil { + return false + } + if s.err == nil { + return false + } + return errors.Is(s.err, context.Canceled) +} + func NewFatalSendError(e error) *SendError { if e == nil { return nil @@ -475,6 +487,10 @@ func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transacti lggr.Errorw("timeout while sending transaction %x", tx.Hash(), "err", sendError, "etx", tx) return commonclient.Retryable } + if sendError.IsCanceled() { + lggr.Errorw("context was canceled while sending transaction %x", tx.Hash(), "err", sendError, "etx", tx) + return commonclient.Retryable + } if sendError.IsTxFeeExceedsCap() { lggr.Criticalw(fmt.Sprintf("Sending transaction failed: %s", label.RPCTxFeeCapConfiguredIncorrectlyWarning), "etx", tx, @@ -486,15 +502,3 @@ func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transacti lggr.Errorw("Unknown error encountered when sending transaction", "err", err, "etx", tx) return commonclient.Unknown } - -// ClassifySendOnlyError handles SendOnly nodes error codes. In that case, we don't assume there is another transaction that will be correctly -// priced. -func ClassifySendOnlyError(err error) commonclient.SendTxReturnCode { - sendError := NewSendError(err) - if sendError == nil || sendError.IsNonceTooLowError() || sendError.IsTransactionAlreadyMined() || sendError.IsTransactionAlreadyInMempool() { - // Nonce too low or transaction known errors are expected since - // the primary SendTransaction may well have succeeded already - return commonclient.Successful - } - return commonclient.Fatal -} From 0e564cdb2b48fa073538a5fd7cb058524722381d Mon Sep 17 00:00:00 2001 From: Vyzaldy Sanchez Date: Sun, 11 Feb 2024 20:26:06 -0400 Subject: [PATCH 02/98] Add nightlyfuzz CI (#11934) * Adds nightlyfuzz CI * Runs nightly fuzz on the root directory * Gives proper permissions to fuzz script * Changes go_core_fuzz command * WIP * WIP * Fixes py script to point to chainlink files * Update fuzz/fuzz_all_native.py Co-authored-by: Jordan Krage * Logs failing fuzz inputs * Bumps actions versions on nightlyfuzz action * Sets fix secs amount on CI fuzz run * Adds comment on `--seconds` usage * Fixes sonar exclusion on fuzz * Fixes sonar exclusion on fuzz * Fixes sonar exclusion on fuzz --------- Co-authored-by: Jordan Krage --- .github/workflows/nightlyfuzz.yml | 53 +++++++++++++++++++++ fuzz/.gitignore | 1 + fuzz/fuzz_all_native.py | 78 +++++++++++++++++++++++++++++++ sonar-project.properties | 2 +- tools/bin/go_core_fuzz | 13 ++++-- 5 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/nightlyfuzz.yml create mode 100644 fuzz/.gitignore create mode 100755 fuzz/fuzz_all_native.py diff --git a/.github/workflows/nightlyfuzz.yml b/.github/workflows/nightlyfuzz.yml new file mode 100644 index 00000000000..7becbe73de5 --- /dev/null +++ b/.github/workflows/nightlyfuzz.yml @@ -0,0 +1,53 @@ +name: 'nightly/tag fuzz' +on: + schedule: + # Note: The schedule event can be delayed during periods of high + # loads of GitHub Actions workflow runs. High load times include + # the start of every hour. To decrease the chance of delay, + # schedule your workflow to run at a different time of the hour. + - cron: "25 0 * * *" # at 25 past midnight every day + push: + tags: + - '*' + workflow_dispatch: null +jobs: + fuzzrun: + name: "run native fuzzers" + runs-on: "ubuntu20.04-4cores-16GB" + steps: + - name: "Checkout" + uses: "actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11" # v4.1.1 + - name: "Setup go" + uses: "actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491" # v5.0.0 + with: + go-version-file: 'go.mod' + cache: true + cache-dependency-path: 'go.sum' + - name: "Get corpus directory" + id: "get-corpus-dir" + run: echo "corpus_dir=$(go env GOCACHE)/fuzz" >> $GITHUB_OUTPUT + shell: "bash" + - name: "Restore corpus" + uses: "actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2" # v4.0.0 + id: "restore-corpus" + with: + path: "${{ steps.get-corpus-dir.outputs.corpus_dir }}" + # We need to ensure uniqueness of the key, as saving to a key more than once will fail (see Save corpus step). + # We never expect a cache hit with the key but we do expect a hit with the restore-keys prefix that is going + # to match the latest cache that has that prefix. + key: "nightlyfuzz-corpus-${{ github.run_id }}-${{ github.run_attempt }}" + restore-keys: "nightlyfuzz-corpus-" + - name: "Run native fuzzers" + # Fuzz for 1 hour + run: "cd fuzz && ./fuzz_all_native.py --seconds 3600" + - name: "Print failing testcases" + if: failure() + run: find . -type f|fgrep '/testdata/fuzz/'|while read f; do echo $f; cat $f; done + - name: "Save corpus" + uses: "actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2" # v4.0.0 + # We save also on failure, so that we can keep the valuable corpus generated that led to finding a crash. + # If the corpus gets clobbered for any reason, we can remove the offending cache from the Github UI. + if: always() + with: + path: "${{ steps.get-corpus-dir.outputs.corpus_dir }}" + key: "${{ steps.restore-corpus.outputs.cache-primary-key }}" \ No newline at end of file diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 00000000000..600ab25dfaf --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1 @@ +*/fuzzer \ No newline at end of file diff --git a/fuzz/fuzz_all_native.py b/fuzz/fuzz_all_native.py new file mode 100755 index 00000000000..41588b090b7 --- /dev/null +++ b/fuzz/fuzz_all_native.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +import argparse +import itertools +import os +import re +import subprocess +import sys + +LIBROOT = "../" + +def main(): + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description="\n".join([ + "Fuzz helper to run all native go fuzzers in chainlink", + "", + ]), + ) + parser.add_argument("--ci", required=False, help="In CI mode we run each parser only briefly once", action="store_true") + parser.add_argument("--seconds", required=False, help="Run for this many seconds of total fuzz time before exiting") + args = parser.parse_args() + + # use float for remaining_seconds so we can represent infinity + if args.seconds: + remaining_seconds = float(args.seconds) + else: + remaining_seconds = float("inf") + + fuzzers = discover_fuzzers() + print(f"🐝 Discovered fuzzers:", file=sys.stderr) + for fuzzfn, path in fuzzers.items(): + print(f"{fuzzfn} in {path}", file=sys.stderr) + + if args.ci: + # only run each fuzzer once for 60 seconds in CI + durations_seconds = [60] + else: + # run forever or until --seconds, with increasingly longer durations per fuzz run + durations_seconds = itertools.chain([5, 10, 30, 90, 270], itertools.repeat(600)) + + for duration_seconds in durations_seconds: + print(f"🐝 Running each fuzzer for {duration_seconds}s before switching to next fuzzer", file=sys.stderr) + for fuzzfn, path in fuzzers.items(): + if remaining_seconds <= 0: + print(f"🐝 Time budget of {args.seconds}s is exhausted. Exiting.", file=sys.stderr) + return + + next_duration_seconds = min(remaining_seconds, duration_seconds) + remaining_seconds -= next_duration_seconds + + print(f"🐝 Running {fuzzfn} in {path} for {next_duration_seconds}s before switching to next fuzzer", file=sys.stderr) + run_fuzzer(fuzzfn, path, next_duration_seconds) + print(f"🐝 Completed running {fuzzfn} in {path} for {next_duration_seconds}s. Total remaining time is {remaining_seconds}s", file=sys.stderr) + +def discover_fuzzers(): + fuzzers = {} + for root, dirs, files in os.walk(LIBROOT): + for file in files: + if not file.endswith("test.go"): continue + with open(os.path.join(root, file), "r") as f: + text = f.read() + # ignore multiline comments + text = re.sub(r"(?s)/[*].*?[*]/", "", text) + # ignore single line comments *except* build tags + text = re.sub(r"//.*", "", text) + # Find every function with a name like FuzzXXX + for fuzzfn in re.findall(r"func\s+(Fuzz\w+)", text): + if fuzzfn in fuzzers: + raise Exception(f"Duplicate fuzz function: {fuzzfn}") + fuzzers[fuzzfn] = os.path.relpath(root, LIBROOT) + return fuzzers + +def run_fuzzer(fuzzfn, dir, duration_seconds): + subprocess.check_call(["go", "test", "-run=^$", f"-fuzz=^{fuzzfn}$", f"-fuzztime={duration_seconds}s", f"./{dir}"], cwd=LIBROOT) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/sonar-project.properties b/sonar-project.properties index 546f68abb32..8a215f6c0be 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,7 +3,7 @@ sonar.sources=. sonar.python.version=3.8 # Full exclusions from the static analysis -sonar.exclusions=**/node_modules/**/*,**/mocks/**/*, **/testdata/**/*, **/contracts/typechain/**/*, **/contracts/artifacts/**/*, **/contracts/cache/**/*, **/contracts/scripts/**/*, **/generated/**/*, **/fixtures/**/*, **/docs/**/*, **/tools/**/*, **/*.pb.go, **/*report.xml, **/*.config.ts, **/*.txt, **/*.abi, **/*.bin, **/*_codecgen.go, core/services/relay/evm/types/*_gen.go, core/services/relay/evm/types/gen/main.go, core/services/relay/evm/testfiles/*, **/core/web/assets**, core/scripts/chaincli/handler/debug.go +sonar.exclusions=**/node_modules/**/*,**/mocks/**/*, **/testdata/**/*, **/contracts/typechain/**/*, **/contracts/artifacts/**/*, **/contracts/cache/**/*, **/contracts/scripts/**/*, **/generated/**/*, **/fixtures/**/*, **/docs/**/*, **/tools/**/*, **/*.pb.go, **/*report.xml, **/*.config.ts, **/*.txt, **/*.abi, **/*.bin, **/*_codecgen.go, core/services/relay/evm/types/*_gen.go, core/services/relay/evm/types/gen/main.go, core/services/relay/evm/testfiles/*, **/core/web/assets**, core/scripts/chaincli/handler/debug.go, **/fuzz/**/* # Coverage exclusions sonar.coverage.exclusions=**/*.test.ts, **/*_test.go, **/contracts/test/**/*, **/contracts/**/tests/**/*, **/core/**/testutils/**/*, **/core/**/mocks/**/*, **/core/**/cltest/**/*, **/integration-tests/**/*, **/generated/**/*, **/core/scripts**/* , **/*.pb.go, ./plugins/**/*, **/main.go, **/0195_add_not_null_to_evm_chain_id_in_job_specs.go, **/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go # Duplication exclusions: mercury excluded because current MercuryProvider and Factory APIs are inherently duplicated due to embedded versioning diff --git a/tools/bin/go_core_fuzz b/tools/bin/go_core_fuzz index 3ea7d9bb0cb..2ee251b5ec5 100755 --- a/tools/bin/go_core_fuzz +++ b/tools/bin/go_core_fuzz @@ -6,9 +6,8 @@ SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"` OUTPUT_FILE=${OUTPUT_FILE:-"./output.txt"} USE_TEE="${USE_TEE:-true}" -echo "Failed tests and panics: ---------------------" +echo "Failed fuzz tests and panics: ---------------------" echo "" -GO_LDFLAGS=$(bash tools/bin/ldflags) use_tee() { if [ "$USE_TEE" = "true" ]; then tee "$@" @@ -16,7 +15,10 @@ use_tee() { cat > "$@" fi } -go test -json -ldflags "$GO_LDFLAGS" github.com/smartcontractkit/chainlink/v2/core/services/relay/evm -fuzz . -fuzztime 12s | use_tee $OUTPUT_FILE + +# the amount of --seconds here is subject to change based on how long the CI job takes in the future +# as we add more fuzz tests, we should take into consideration increasing this timelapse, so we can have enough coverage. +cd ./fuzz && ./fuzz_all_native.py --ci --seconds 420 | use_tee $OUTPUT_FILE EXITCODE=${PIPESTATUS[0]} # Assert no known sensitive strings present in test logger output @@ -29,8 +31,9 @@ fi echo "Exit code: $EXITCODE" if [[ $EXITCODE != 0 ]]; then - echo "Encountered test failures." + echo "Encountered fuzz test failures. Logging all failing fuzz inputs:" + find . -type f|fgrep '/testdata/fuzz/'|while read f; do echo $f; cat $f; done else - echo "All tests passed!" + echo "All fuzz tests passed!" fi exit $EXITCODE From 000149499a93fccd1cc5da9100cff233e7a53171 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 12 Feb 2024 09:51:51 -0500 Subject: [PATCH 03/98] OCR3 keyring support (#11956) * OCR3 keyring support - Needed for LLO - Only includes EVM implementation * Rename to ocr2plus key * Revert "Rename to ocr2plus key" This reverts commit 19a204cc81e0cda916293e0ba604834efb998ca4. * Add test * Fix lint --- core/internal/testutils/testutils.go | 9 +++ .../keystore/keys/ocr2key/cosmos_keyring.go | 59 ++++++++++------ .../keystore/keys/ocr2key/evm_keyring.go | 68 ++++++++++++++----- .../keystore/keys/ocr2key/evm_keyring_test.go | 36 ++++++++++ .../keys/ocr2key/generic_key_bundle.go | 9 +++ .../keystore/keys/ocr2key/key_bundle.go | 8 +++ .../keystore/keys/ocr2key/solana_keyring.go | 47 +++++++++---- .../keystore/keys/starkkey/ocr2key.go | 9 ++- 8 files changed, 193 insertions(+), 52 deletions(-) diff --git a/core/internal/testutils/testutils.go b/core/internal/testutils/testutils.go index 81c09b1c362..a38b4707179 100644 --- a/core/internal/testutils/testutils.go +++ b/core/internal/testutils/testutils.go @@ -446,3 +446,12 @@ func MustDecodeBase64(s string) (b []byte) { func SkipFlakey(t *testing.T, ticketURL string) { t.Skip("Flakey", ticketURL) } + +func MustRandBytes(n int) (b []byte) { + b = make([]byte, n) + _, err := rand.Read(b) + if err != nil { + panic(err) + } + return +} diff --git a/core/services/keystore/keys/ocr2key/cosmos_keyring.go b/core/services/keystore/keys/ocr2key/cosmos_keyring.go index 490fa0cbfcb..5f1b9b98198 100644 --- a/core/services/keystore/keys/ocr2key/cosmos_keyring.go +++ b/core/services/keystore/keys/ocr2key/cosmos_keyring.go @@ -7,6 +7,7 @@ import ( "github.com/hdevalence/ed25519consensus" "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "golang.org/x/crypto/blake2s" @@ -29,11 +30,11 @@ func newCosmosKeyring(material io.Reader) (*cosmosKeyring, error) { return &cosmosKeyring{pubKey: pubKey, privKey: privKey}, nil } -func (tk *cosmosKeyring) PublicKey() ocrtypes.OnchainPublicKey { - return []byte(tk.pubKey) +func (ckr *cosmosKeyring) PublicKey() ocrtypes.OnchainPublicKey { + return []byte(ckr.pubKey) } -func (tk *cosmosKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { +func (ckr *cosmosKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { rawReportContext := evmutil.RawReportContext(reportCtx) h, err := blake2s.New256(nil) if err != nil { @@ -49,48 +50,64 @@ func (tk *cosmosKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, repor return h.Sum(nil), nil } -func (tk *cosmosKeyring) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { - sigData, err := tk.reportToSigData(reportCtx, report) +func (ckr *cosmosKeyring) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { + sigData, err := ckr.reportToSigData(reportCtx, report) if err != nil { return nil, err } - signedMsg := ed25519.Sign(tk.privKey, sigData) + return ckr.signBlob(sigData) +} + +func (ckr *cosmosKeyring) Sign3(digest types.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) { + return nil, errors.New("not implemented") +} + +func (ckr *cosmosKeyring) signBlob(b []byte) ([]byte, error) { + signedMsg := ed25519.Sign(ckr.privKey, b) // match on-chain parsing (first 32 bytes are for pubkey, remaining are for signature) - return utils.ConcatBytes(tk.PublicKey(), signedMsg), nil + return utils.ConcatBytes(ckr.PublicKey(), signedMsg), nil +} + +func (ckr *cosmosKeyring) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { + hash, err := ckr.reportToSigData(reportCtx, report) + if err != nil { + return false + } + return ckr.verifyBlob(publicKey, hash, signature) +} + +func (ckr *cosmosKeyring) Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool { + return false } -func (tk *cosmosKeyring) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { +func (ckr *cosmosKeyring) verifyBlob(pubkey ocrtypes.OnchainPublicKey, b, sig []byte) bool { // Ed25519 signatures are always 64 bytes and the // public key (always prefixed, see Sign above) is always, // 32 bytes, so we always require the max signature length. - if len(signature) != tk.MaxSignatureLength() { + if len(sig) != ckr.MaxSignatureLength() { return false } - if len(publicKey) != ed25519.PublicKeySize { - return false - } - hash, err := tk.reportToSigData(reportCtx, report) - if err != nil { + if len(pubkey) != ed25519.PublicKeySize { return false } - return ed25519consensus.Verify(ed25519.PublicKey(publicKey), hash, signature[32:]) + return ed25519consensus.Verify(ed25519.PublicKey(pubkey), b, sig[32:]) } -func (tk *cosmosKeyring) MaxSignatureLength() int { +func (ckr *cosmosKeyring) MaxSignatureLength() int { // Reference: https://pkg.go.dev/crypto/ed25519 return ed25519.PublicKeySize + ed25519.SignatureSize // 32 + 64 } -func (tk *cosmosKeyring) Marshal() ([]byte, error) { - return tk.privKey.Seed(), nil +func (ckr *cosmosKeyring) Marshal() ([]byte, error) { + return ckr.privKey.Seed(), nil } -func (tk *cosmosKeyring) Unmarshal(in []byte) error { +func (ckr *cosmosKeyring) Unmarshal(in []byte) error { if len(in) != ed25519.SeedSize { return errors.Errorf("unexpected seed size, got %d want %d", len(in), ed25519.SeedSize) } privKey := ed25519.NewKeyFromSeed(in) - tk.privKey = privKey - tk.pubKey = privKey.Public().(ed25519.PublicKey) + ckr.privKey = privKey + ckr.pubKey = privKey.Public().(ed25519.PublicKey) return nil } diff --git a/core/services/keystore/keys/ocr2key/evm_keyring.go b/core/services/keystore/keys/ocr2key/evm_keyring.go index cc4076391b4..5d937e36a6e 100644 --- a/core/services/keystore/keys/ocr2key/evm_keyring.go +++ b/core/services/keystore/keys/ocr2key/evm_keyring.go @@ -3,10 +3,12 @@ package ocr2key import ( "bytes" "crypto/ecdsa" + "encoding/binary" "io" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) @@ -26,12 +28,16 @@ func newEVMKeyring(material io.Reader) (*evmKeyring, error) { } // XXX: PublicKey returns the address of the public key not the public key itself -func (ok *evmKeyring) PublicKey() ocrtypes.OnchainPublicKey { - address := ok.signingAddress() +func (ekr *evmKeyring) PublicKey() ocrtypes.OnchainPublicKey { + address := ekr.signingAddress() return address[:] } -func (ok *evmKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) []byte { +func (ekr *evmKeyring) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { + return ekr.signBlob(ekr.reportToSigData(reportCtx, report)) +} + +func (ekr *evmKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) []byte { rawReportContext := evmutil.RawReportContext(reportCtx) sigData := crypto.Keccak256(report) sigData = append(sigData, rawReportContext[0][:]...) @@ -40,38 +46,68 @@ func (ok *evmKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report o return crypto.Keccak256(sigData) } -func (ok *evmKeyring) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { - return crypto.Sign(ok.reportToSigData(reportCtx, report), &ok.privateKey) +func (ekr *evmKeyring) Sign3(digest types.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) { + return ekr.signBlob(ekr.reportToSigData3(digest, seqNr, r)) +} + +func (ekr *evmKeyring) reportToSigData3(digest types.ConfigDigest, seqNr uint64, r ocrtypes.Report) []byte { + rawReportContext := RawReportContext3(digest, seqNr) + sigData := crypto.Keccak256(r) + sigData = append(sigData, rawReportContext[0][:]...) + sigData = append(sigData, rawReportContext[1][:]...) + return crypto.Keccak256(sigData) +} + +func RawReportContext3(digest types.ConfigDigest, seqNr uint64) [2][32]byte { + seqNrBytes := [32]byte{} + binary.BigEndian.PutUint64(seqNrBytes[:], seqNr) + return [2][32]byte{ + digest, + seqNrBytes, + } +} + +func (ekr *evmKeyring) signBlob(b []byte) (sig []byte, err error) { + return crypto.Sign(b, &ekr.privateKey) +} + +func (ekr *evmKeyring) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { + hash := ekr.reportToSigData(reportCtx, report) + return ekr.verifyBlob(publicKey, hash, signature) +} +func (ekr *evmKeyring) Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool { + hash := ekr.reportToSigData3(cd, seqNr, r) + return ekr.verifyBlob(publicKey, hash, signature) } -func (ok *evmKeyring) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { - hash := ok.reportToSigData(reportCtx, report) - authorPubkey, err := crypto.SigToPub(hash, signature) +func (ekr *evmKeyring) verifyBlob(pubkey types.OnchainPublicKey, b, sig []byte) bool { + authorPubkey, err := crypto.SigToPub(b, sig) if err != nil { return false } authorAddress := crypto.PubkeyToAddress(*authorPubkey) - return bytes.Equal(publicKey[:], authorAddress[:]) + // no need for constant time compare since neither arg is sensitive + return bytes.Equal(pubkey[:], authorAddress[:]) } -func (ok *evmKeyring) MaxSignatureLength() int { +func (ekr *evmKeyring) MaxSignatureLength() int { return 65 } -func (ok *evmKeyring) signingAddress() common.Address { - return crypto.PubkeyToAddress(*(&ok.privateKey).Public().(*ecdsa.PublicKey)) +func (ekr *evmKeyring) signingAddress() common.Address { + return crypto.PubkeyToAddress(*(&ekr.privateKey).Public().(*ecdsa.PublicKey)) } -func (ok *evmKeyring) Marshal() ([]byte, error) { - return crypto.FromECDSA(&ok.privateKey), nil +func (ekr *evmKeyring) Marshal() ([]byte, error) { + return crypto.FromECDSA(&ekr.privateKey), nil } -func (ok *evmKeyring) Unmarshal(in []byte) error { +func (ekr *evmKeyring) Unmarshal(in []byte) error { privateKey, err := crypto.ToECDSA(in) if err != nil { return err } - ok.privateKey = *privateKey + ekr.privateKey = *privateKey return nil } diff --git a/core/services/keystore/keys/ocr2key/evm_keyring_test.go b/core/services/keystore/keys/ocr2key/evm_keyring_test.go index 5400b0df6a0..20ac197159a 100644 --- a/core/services/keystore/keys/ocr2key/evm_keyring_test.go +++ b/core/services/keystore/keys/ocr2key/evm_keyring_test.go @@ -3,12 +3,16 @@ package ocr2key import ( "bytes" cryptorand "crypto/rand" + "math/rand" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/libocr/offchainreporting2/types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" ) func TestEVMKeyring_SignVerify(t *testing.T) { @@ -43,6 +47,38 @@ func TestEVMKeyring_SignVerify(t *testing.T) { }) } +func TestEVMKeyring_Sign3Verify3(t *testing.T) { + kr1, err := newEVMKeyring(cryptorand.Reader) + require.NoError(t, err) + kr2, err := newEVMKeyring(cryptorand.Reader) + require.NoError(t, err) + + digest, err := types.BytesToConfigDigest(testutils.MustRandBytes(32)) + require.NoError(t, err) + seqNr := rand.Uint64() + r := ocrtypes.Report(testutils.MustRandBytes(rand.Intn(1024))) + + t.Run("can verify", func(t *testing.T) { + sig, err := kr1.Sign3(digest, seqNr, r) + require.NoError(t, err) + t.Log(len(sig)) + result := kr2.Verify3(kr1.PublicKey(), digest, seqNr, r, sig) + assert.True(t, result) + }) + + t.Run("invalid sig", func(t *testing.T) { + result := kr2.Verify3(kr1.PublicKey(), digest, seqNr, r, []byte{0x01}) + assert.False(t, result) + }) + + t.Run("invalid pubkey", func(t *testing.T) { + sig, err := kr1.Sign3(digest, seqNr, r) + require.NoError(t, err) + result := kr2.Verify3([]byte{0x01}, digest, seqNr, r, sig) + assert.False(t, result) + }) +} + func TestEVMKeyring_Marshalling(t *testing.T) { kr1, err := newEVMKeyring(cryptorand.Reader) require.NoError(t, err) diff --git a/core/services/keystore/keys/ocr2key/generic_key_bundle.go b/core/services/keystore/keys/ocr2key/generic_key_bundle.go index be401becfb3..2c5e4bd8559 100644 --- a/core/services/keystore/keys/ocr2key/generic_key_bundle.go +++ b/core/services/keystore/keys/ocr2key/generic_key_bundle.go @@ -18,6 +18,7 @@ import ( type ( keyring interface { ocrtypes.OnchainKeyring + OCR3SignerVerifier Marshal() ([]byte, error) Unmarshal(in []byte) error } @@ -92,10 +93,18 @@ func (kb *keyBundle[K]) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.R return kb.keyring.Sign(reportCtx, report) } +func (kb *keyBundle[K]) Sign3(digest ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) { + return kb.keyring.Sign3(digest, seqNr, r) +} + func (kb *keyBundle[K]) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { return kb.keyring.Verify(publicKey, reportCtx, report, signature) } +func (kb *keyBundle[K]) Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool { + return kb.keyring.Verify3(publicKey, cd, seqNr, r, signature) +} + // OnChainPublicKey returns public component of the keypair used on chain func (kb *keyBundle[K]) OnChainPublicKey() string { return hex.EncodeToString(kb.keyring.PublicKey()) diff --git a/core/services/keystore/keys/ocr2key/key_bundle.go b/core/services/keystore/keys/ocr2key/key_bundle.go index 79d8ad70d52..2c3a4bebeb0 100644 --- a/core/services/keystore/keys/ocr2key/key_bundle.go +++ b/core/services/keystore/keys/ocr2key/key_bundle.go @@ -14,12 +14,20 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/models" ) +type OCR3SignerVerifier interface { + Sign3(digest ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) + Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool +} + // nolint type KeyBundle interface { // OnchainKeyring is used for signing reports (groups of observations, verified onchain) ocrtypes.OnchainKeyring // OffchainKeyring is used for signing observations ocrtypes.OffchainKeyring + + OCR3SignerVerifier + ID() string ChainType() chaintype.ChainType Marshal() ([]byte, error) diff --git a/core/services/keystore/keys/ocr2key/solana_keyring.go b/core/services/keystore/keys/ocr2key/solana_keyring.go index aebe33e1d19..a5fa2f77dc0 100644 --- a/core/services/keystore/keys/ocr2key/solana_keyring.go +++ b/core/services/keystore/keys/ocr2key/solana_keyring.go @@ -7,6 +7,8 @@ import ( "io" "github.com/ethereum/go-ethereum/crypto" + "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) @@ -26,12 +28,12 @@ func newSolanaKeyring(material io.Reader) (*solanaKeyring, error) { } // XXX: PublicKey returns the evm-style address of the public key not the public key itself -func (ok *solanaKeyring) PublicKey() ocrtypes.OnchainPublicKey { - address := crypto.PubkeyToAddress(*(&ok.privateKey).Public().(*ecdsa.PublicKey)) +func (skr *solanaKeyring) PublicKey() ocrtypes.OnchainPublicKey { + address := crypto.PubkeyToAddress(*(&skr.privateKey).Public().(*ecdsa.PublicKey)) return address[:] } -func (ok *solanaKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) []byte { +func (skr *solanaKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) []byte { rawReportContext := evmutil.RawReportContext(reportCtx) h := sha256.New() h.Write([]byte{uint8(len(report))}) @@ -42,30 +44,47 @@ func (ok *solanaKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, repor return h.Sum(nil) } -func (ok *solanaKeyring) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { - return crypto.Sign(ok.reportToSigData(reportCtx, report), &ok.privateKey) +func (skr *solanaKeyring) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { + return skr.signBlob(skr.reportToSigData(reportCtx, report)) } -func (ok *solanaKeyring) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { - hash := ok.reportToSigData(reportCtx, report) - authorPubkey, err := crypto.SigToPub(hash, signature) +func (skr *solanaKeyring) Sign3(digest types.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) { + return nil, errors.New("not implemented") +} + +func (skr *solanaKeyring) signBlob(b []byte) (sig []byte, err error) { + return crypto.Sign(b, &skr.privateKey) +} + +func (skr *solanaKeyring) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { + hash := skr.reportToSigData(reportCtx, report) + return skr.verifyBlob(publicKey, hash, signature) +} + +func (skr *solanaKeyring) Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool { + return false +} + +func (skr *solanaKeyring) verifyBlob(pubkey types.OnchainPublicKey, b, sig []byte) bool { + authorPubkey, err := crypto.SigToPub(b, sig) if err != nil { return false } authorAddress := crypto.PubkeyToAddress(*authorPubkey) - return bytes.Equal(publicKey[:], authorAddress[:]) + // no need for constant time compare since neither arg is sensitive + return bytes.Equal(pubkey[:], authorAddress[:]) } -func (ok *solanaKeyring) MaxSignatureLength() int { +func (skr *solanaKeyring) MaxSignatureLength() int { return 65 } -func (ok *solanaKeyring) Marshal() ([]byte, error) { - return crypto.FromECDSA(&ok.privateKey), nil +func (skr *solanaKeyring) Marshal() ([]byte, error) { + return crypto.FromECDSA(&skr.privateKey), nil } -func (ok *solanaKeyring) Unmarshal(in []byte) error { +func (skr *solanaKeyring) Unmarshal(in []byte) error { privateKey, err := crypto.ToECDSA(in) - ok.privateKey = *privateKey + skr.privateKey = *privateKey return err } diff --git a/core/services/keystore/keys/starkkey/ocr2key.go b/core/services/keystore/keys/starkkey/ocr2key.go index 41ab3a4708d..417687b62a6 100644 --- a/core/services/keystore/keys/starkkey/ocr2key.go +++ b/core/services/keystore/keys/starkkey/ocr2key.go @@ -58,7 +58,6 @@ func (sk *OCR2Key) Sign(reportCtx types.ReportContext, report types.Report) ([]b if err != nil { return []byte{}, err } - r, s, err := caigo.Curve.Sign(hash, sk.priv) if err != nil { return []byte{}, err @@ -85,6 +84,10 @@ func (sk *OCR2Key) Sign(reportCtx types.ReportContext, report types.Report) ([]b return out, nil } +func (sk *OCR2Key) Sign3(digest types.ConfigDigest, seqNr uint64, r types.Report) (signature []byte, err error) { + return nil, errors.New("not implemented") +} + func (sk *OCR2Key) Verify(publicKey types.OnchainPublicKey, reportCtx types.ReportContext, report types.Report, signature []byte) bool { // check valid signature length if len(signature) != sk.MaxSignatureLength() { @@ -120,6 +123,10 @@ func (sk *OCR2Key) Verify(publicKey types.OnchainPublicKey, reportCtx types.Repo return caigo.Curve.Verify(hash, r, s, keys[0].X, keys[0].Y) || caigo.Curve.Verify(hash, r, s, keys[1].X, keys[1].Y) } +func (sk *OCR2Key) Verify3(publicKey types.OnchainPublicKey, cd types.ConfigDigest, seqNr uint64, r types.Report, signature []byte) bool { + return false +} + func (sk *OCR2Key) MaxSignatureLength() int { return 32 + 32 + 32 // publickey + r + s } From 8fd6226017aa63eecea4d66784cffaeea3eab863 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 12 Feb 2024 10:03:37 -0500 Subject: [PATCH 04/98] Add preliminary LLO contracts (#11990) * Add preliminary LLO contracts NOTE: These are not the final contracts (not even close). They do not implement any kind of blue/green deployment and will likely change a lot. What they are, is sufficient to run benchmarking. * Run prettier on new contracts * Revert "Run prettier on new contracts" This reverts commit 739ed422616242b565ea1b046027b33bdc14d6cc. * run prettier --- .../scripts/native_solc_compile_all_llo-feeds | 10 +- .../v0.8/llo-feeds/dev/ChannelConfigStore.sol | 104 ++ .../v0.8/llo-feeds/dev/ChannelVerifier.sol | 536 ++++++ .../dev/interfaces/IChannelConfigStore.sol | 32 + .../dev/interfaces/IChannelVerifier.sol | 111 ++ .../dev/test/mocks/ExposedChannelVerifier.sol | 66 + .../dev/test/mocks/ExposedVerifier.sol | 69 + .../channel_config_store.go | 1032 +++++++++++ .../channel_verifier/channel_verifier.go | 1583 +++++++++++++++++ .../exposed_channel_verifier.go | 202 +++ ...rapper-dependency-versions-do-not-edit.txt | 9 +- core/gethwrappers/llo-feeds/go_generate.go | 3 + 12 files changed, 3753 insertions(+), 4 deletions(-) create mode 100644 contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol create mode 100644 contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol create mode 100644 contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol create mode 100644 core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go create mode 100644 core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go create mode 100644 core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go diff --git a/contracts/scripts/native_solc_compile_all_llo-feeds b/contracts/scripts/native_solc_compile_all_llo-feeds index 2d97d06baea..eb17f93b0de 100755 --- a/contracts/scripts/native_solc_compile_all_llo-feeds +++ b/contracts/scripts/native_solc_compile_all_llo-feeds @@ -33,6 +33,12 @@ compileContract llo-feeds/VerifierProxy.sol compileContract llo-feeds/FeeManager.sol compileContract llo-feeds/RewardManager.sol -#Test | Mocks + +# Test | Mocks compileContract llo-feeds/test/mocks/ErroredVerifier.sol -compileContract llo-feeds/test/mocks/ExposedVerifier.sol \ No newline at end of file +compileContract llo-feeds/test/mocks/ExposedVerifier.sol + +# LLO +compileContract llo-feeds/dev/ChannelConfigStore.sol +compileContract llo-feeds/dev/ChannelVerifier.sol +compileContract llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol diff --git a/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol new file mode 100644 index 00000000000..ca24b775398 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IChannelConfigStore} from "./interfaces/IChannelConfigStore.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; + +contract ChannelConfigStore is ConfirmedOwner, IChannelConfigStore, TypeAndVersionInterface { + mapping(uint32 => ChannelDefinition) private s_channelDefinitions; + + // mapping(bytes32 => ChannelConfiguration) private s_channelProductionConfigurations; + // mapping(bytes32 => ChannelConfiguration) private s_channelStagingConfigurations; + + event NewChannelDefinition(uint32 channelId, ChannelDefinition channelDefinition); + event ChannelDefinitionRemoved(uint32 channelId); + // event NewProductionConfig(ChannelConfiguration channelConfig); + // event NewStagingConfig(ChannelConfiguration channelConfig); + event PromoteStagingConfig(uint32 channelId); + + error OnlyCallableByEOA(); + error StagingConfigAlreadyPromoted(); + error EmptyStreamIDs(); + error ZeroReportFormat(); + error ZeroChainSelector(); + error ChannelDefinitionNotFound(); + + constructor() ConfirmedOwner(msg.sender) {} + + // function setStagingConfig(bytes32 configDigest, ChannelConfiguration calldata channelConfig) external onlyOwner { + // s_channelStagingConfigurations[channelId] = channelConfig; + + // emit NewStagingConfig(channelConfig); + // } + + //// this will trigger the following: + //// - offchain ShouldRetireCache will start returning true for the old (production) + //// protocol instance + //// - once the old production instance retires it will generate a handover + //// retirement report + //// - the staging instance will become the new production instance once + //// any honest oracle that is on both instances forward the retirement + //// report from the old instance to the new instace via the + //// PredecessorRetirementReportCache + //// + //// Note: the promotion flow only works if the previous production instance + //// is working correctly & generating reports. If that's not the case, the + //// owner is expected to "setProductionConfig" directly instead. This will + //// cause "gaps" to be created, but that seems unavoidable in such a scenario. + // function promoteStagingConfig(bytes32 configDigest) external onlyOwner { + // ChannelConfiguration memory stagingConfig = s_channelStagingConfigurations[channelId]; + + // if(stagingConfig.channelConfigId.length == 0) { + // revert StagingConfigAlreadyPromoted(); + // } + + // s_channelProductionConfigurations[channelId] = s_channelStagingConfigurations[channelId]; + + // emit PromoteStagingConfig(channelId); + // } + + function addChannel(uint32 channelId, ChannelDefinition calldata channelDefinition) external onlyOwner { + if (channelDefinition.streamIDs.length == 0) { + revert EmptyStreamIDs(); + } + + if (channelDefinition.chainSelector == 0) { + revert ZeroChainSelector(); + } + + if (channelDefinition.reportFormat == 0) { + revert ZeroReportFormat(); + } + + s_channelDefinitions[channelId] = channelDefinition; + + emit NewChannelDefinition(channelId, channelDefinition); + } + + function removeChannel(uint32 channelId) external onlyOwner { + if (s_channelDefinitions[channelId].streamIDs.length == 0) { + revert ChannelDefinitionNotFound(); + } + + delete s_channelDefinitions[channelId]; + + emit ChannelDefinitionRemoved(channelId); + } + + function getChannelDefinitions(uint32 channelId) external view returns (ChannelDefinition memory) { + if (msg.sender != tx.origin) { + revert OnlyCallableByEOA(); + } + + return s_channelDefinitions[channelId]; + } + + function typeAndVersion() external pure override returns (string memory) { + return "ChannelConfigStore 0.0.0"; + } + + function supportsInterface(bytes4 interfaceId) external pure returns (bool) { + return interfaceId == type(IChannelConfigStore).interfaceId; + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol new file mode 100644 index 00000000000..424022dc441 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol @@ -0,0 +1,536 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; +import {IChannelVerifier} from "./interfaces/IChannelVerifier.sol"; + +// OCR2 standard +uint256 constant MAX_NUM_ORACLES = 31; + +/* + * The verifier contract is used to verify offchain reports signed + * by DONs. A report consists of a price, block number and feed Id. It + * represents the observed price of an asset at a specified block number for + * a feed. The verifier contract is used to verify that such reports have + * been signed by the correct signers. + **/ +contract ChannelVerifier is IChannelVerifier, ConfirmedOwner, TypeAndVersionInterface { + // The first byte of the mask can be 0, because we only ever have 31 oracles + uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101; + + enum Role { + // Default role for an oracle address. This means that the oracle address + // is not a signer + Unset, + // Role given to an oracle address that is allowed to sign feed data + Signer + } + + struct Signer { + // Index of oracle in a configuration + uint8 index; + // The oracle's role + Role role; + } + + struct Config { + // Fault tolerance + uint8 f; + // Marks whether or not a configuration is active + bool isActive; + // Map of signer addresses to oracles + mapping(address => Signer) oracles; + } + + struct VerifierState { + // The number of times a new configuration + /// has been set + uint32 configCount; + // The block number of the block the last time + /// the configuration was updated. + uint32 latestConfigBlockNumber; + // The latest epoch a report was verified for + uint32 latestEpoch; + /// The latest config digest set + bytes32 latestConfigDigest; + /// List of deactivated feeds + mapping(bytes32 => bool) deactivatedFeeds; + /// The historical record of all previously set configs by feedId + mapping(bytes32 => Config) s_verificationDataConfigs; + } + + /// @notice This event is emitted when a new report is verified. + /// It is used to keep a historical record of verified reports. + event ReportVerified(bytes32 indexed feedId, address requester); + + /// @notice This event is emitted whenever a new configuration is set. It triggers a new run of the offchain reporting protocol. + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + bytes32[] offchainTransmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + /// @notice This event is emitted whenever a configuration is deactivated + event ConfigDeactivated(bytes32 configDigest); + + /// @notice This event is emitted whenever a configuration is activated + event ConfigActivated(bytes32 configDigest); + + /// @notice This event is emitted whenever a feed is activated + event FeedActivated(bytes32 indexed feedId); + + /// @notice This event is emitted whenever a feed is deactivated + event FeedDeactivated(bytes32 indexed feedId); + + /// @notice This error is thrown whenever an address tries + /// to exeecute a transaction that it is not authorized to do so + error AccessForbidden(); + + /// @notice This error is thrown whenever a zero address is passed + error ZeroAddress(); + + /// @notice This error is thrown whenever the feed ID passed in + /// a signed report is empty + error FeedIdEmpty(); + + /// @notice This error is thrown whenever the config digest + /// is empty + error DigestEmpty(); + + /// @notice This error is thrown whenever the config digest + /// passed in has not been set in this verifier + /// @param configDigest The config digest that has not been set + error DigestNotSet(bytes32 configDigest); + + /// @notice This error is thrown whenever the config digest + /// has been deactivated + /// @param configDigest The config digest that is inactive + error DigestInactive(bytes32 configDigest); + + /// @notice This error is thrown whenever trying to set a config + /// with a fault tolerance of 0 + error FaultToleranceMustBePositive(); + + /// @notice This error is thrown whenever a report is signed + /// with more than the max number of signers + /// @param numSigners The number of signers who have signed the report + /// @param maxSigners The maximum number of signers that can sign a report + error ExcessSigners(uint256 numSigners, uint256 maxSigners); + + /// @notice This error is thrown whenever a report is signed + /// with less than the minimum number of signers + /// @param numSigners The number of signers who have signed the report + /// @param minSigners The minimum number of signers that need to sign a report + error InsufficientSigners(uint256 numSigners, uint256 minSigners); + + /// @notice This error is thrown whenever a report is signed + /// with an incorrect number of signers + /// @param numSigners The number of signers who have signed the report + /// @param expectedNumSigners The expected number of signers that need to sign + /// a report + error IncorrectSignatureCount(uint256 numSigners, uint256 expectedNumSigners); + + /// @notice This error is thrown whenever the R and S signer components + /// have different lengths + /// @param rsLength The number of r signature components + /// @param ssLength The number of s signature components + error MismatchedSignatures(uint256 rsLength, uint256 ssLength); + + /// @notice This error is thrown whenever setting a config with duplicate signatures + error NonUniqueSignatures(); + + /// @notice This error is thrown whenever a report fails to verify due to bad or duplicate signatures + error BadVerification(); + + /// @notice This error is thrown whenever the admin tries to deactivate + /// the latest config digest + /// @param configDigest The latest config digest + error CannotDeactivateLatestConfig(bytes32 configDigest); + + /// @notice This error is thrown whenever the feed ID passed in is deactivated + /// @param feedId The feed ID + error InactiveFeed(bytes32 feedId); + + /// @notice This error is thrown whenever the feed ID passed in is not found + /// @param feedId The feed ID + error InvalidFeed(bytes32 feedId); + + /// @notice The address of the verifier proxy + address private immutable i_verifierProxyAddr; + + /// @notice Verifier states keyed on Feed ID + VerifierState internal s_feedVerifierState; + + /// @param verifierProxyAddr The address of the VerifierProxy contract + constructor(address verifierProxyAddr) ConfirmedOwner(msg.sender) { + if (verifierProxyAddr == address(0)) revert ZeroAddress(); + i_verifierProxyAddr = verifierProxyAddr; + } + + modifier checkConfigValid(uint256 numSigners, uint256 f) { + if (f == 0) revert FaultToleranceMustBePositive(); + if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES); + if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1); + _; + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool isVerifier) { + return interfaceId == this.verify.selector; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "ChannelVerifier 0.0.0"; + } + + /// @inheritdoc IChannelVerifier + function verify( + bytes calldata signedReport, + address sender + ) external override returns (bytes memory verifierResponse) { + if (msg.sender != i_verifierProxyAddr) revert AccessForbidden(); + ( + bytes32[3] memory reportContext, + bytes memory reportData, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs + ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32)); + + // The feed ID is the first 32 bytes of the report data. + bytes32 feedId = bytes32(reportData); + + // If the feed has been deactivated, do not verify the report + if (s_feedVerifierState.deactivatedFeeds[feedId]) { + revert InactiveFeed(feedId); + } + + // reportContext consists of: + // reportContext[0]: ConfigDigest + // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round + // reportContext[2]: ExtraHash + bytes32 configDigest = reportContext[0]; + Config storage s_config = s_feedVerifierState.s_verificationDataConfigs[configDigest]; + + _validateReport(configDigest, rs, ss, s_config); + _updateEpoch(reportContext, s_feedVerifierState); + + bytes32 hashedReport = keccak256(reportData); + + _verifySignatures(hashedReport, reportContext, rs, ss, rawVs, s_config); + emit ReportVerified(feedId, sender); + + return reportData; + } + + /// @notice Validates parameters of the report + /// @param configDigest Config digest from the report + /// @param rs R components from the report + /// @param ss S components from the report + /// @param config Config for the given feed ID keyed on the config digest + function _validateReport( + bytes32 configDigest, + bytes32[] memory rs, + bytes32[] memory ss, + Config storage config + ) private view { + uint8 expectedNumSignatures = config.f + 1; + + if (!config.isActive) revert DigestInactive(configDigest); + if (rs.length != expectedNumSignatures) revert IncorrectSignatureCount(rs.length, expectedNumSignatures); + if (rs.length != ss.length) revert MismatchedSignatures(rs.length, ss.length); + } + + /** + * @notice Conditionally update the epoch for a feed + * @param reportContext Report context containing the epoch and round + * @param feedVerifierState Feed verifier state to conditionally update + */ + function _updateEpoch(bytes32[3] memory reportContext, VerifierState storage feedVerifierState) private { + uint40 epochAndRound = uint40(uint256(reportContext[1])); + uint32 epoch = uint32(epochAndRound >> 8); + if (epoch > feedVerifierState.latestEpoch) { + feedVerifierState.latestEpoch = epoch; + } + } + + /// @notice Verifies that a report has been signed by the correct + /// signers and that enough signers have signed the reports. + /// @param hashedReport The keccak256 hash of the raw report's bytes + /// @param reportContext The context the report was signed in + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + /// @param s_config The config digest the report was signed for + function _verifySignatures( + bytes32 hashedReport, + bytes32[3] memory reportContext, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs, + Config storage s_config + ) private view { + bytes32 h = keccak256(abi.encodePacked(hashedReport, reportContext)); + // i-th byte counts number of sigs made by i-th signer + uint256 signedCount; + + Signer memory o; + address signerAddress; + uint256 numSigners = rs.length; + for (uint256 i; i < numSigners; ++i) { + signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); + o = s_config.oracles[signerAddress]; + if (o.role != Role.Signer) revert BadVerification(); + unchecked { + signedCount += 1 << (8 * o.index); + } + } + + if (signedCount & ORACLE_MASK != signedCount) revert BadVerification(); + } + + /// @inheritdoc IChannelVerifier + function setConfig( + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig( + block.chainid, + address(this), + 0, // 0 defaults to feedConfig.configCount + 1 + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + recipientAddressesAndWeights + ); + } + + /// @inheritdoc IChannelVerifier + function setConfigFromSource( + uint256 sourceChainId, + address sourceAddress, + uint32 newConfigCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig( + sourceChainId, + sourceAddress, + newConfigCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + recipientAddressesAndWeights + ); + } + + /// @notice Sets config based on the given arguments + /// @param sourceChainId Chain ID of source config + /// @param sourceAddress Address of source config Verifier + /// @param newConfigCount Optional param to force the new config count + /// @param signers addresses with which oracles sign the reports + /// @param offchainTransmitters CSA key for the ith Oracle + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + /// @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + function _setConfig( + uint256 sourceChainId, + address sourceAddress, + uint32 newConfigCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) internal { + // Increment the number of times a config has been set first + if (newConfigCount > 0) s_feedVerifierState.configCount = newConfigCount; + else s_feedVerifierState.configCount++; + + bytes32 configDigest = _configDigestFromConfigData( + sourceChainId, + sourceAddress, + s_feedVerifierState.configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + s_feedVerifierState.s_verificationDataConfigs[configDigest].f = f; + s_feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; + for (uint8 i; i < signers.length; ++i) { + address signerAddr = signers[i]; + if (signerAddr == address(0)) revert ZeroAddress(); + + // All signer roles are unset by default for a new config digest. + // Here the contract checks to see if a signer's address has already + // been set to ensure that the group of signer addresses that will + // sign reports with the config digest are unique. + bool isSignerAlreadySet = s_feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr].role != + Role.Unset; + if (isSignerAlreadySet) revert NonUniqueSignatures(); + s_feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr] = Signer({ + role: Role.Signer, + index: i + }); + } + + recipientAddressesAndWeights; // silence unused var warning + // IVerifierProxy(i_verifierProxyAddr).setVerifier( + // feedVerifierState.latestConfigDigest, + // configDigest, + // recipientAddressesAndWeights + // ); + + emit ConfigSet( + s_feedVerifierState.latestConfigBlockNumber, + configDigest, + s_feedVerifierState.configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + s_feedVerifierState.latestEpoch = 0; + s_feedVerifierState.latestConfigBlockNumber = uint32(block.number); + s_feedVerifierState.latestConfigDigest = configDigest; + } + + /// @notice Generates the config digest from config data + /// @param sourceChainId Chain ID of source config + /// @param sourceAddress Address of source config Verifier + /// @param configCount ordinal number of this config setting among all config settings over the life of this contract + /// @param signers ith element is address ith oracle uses to sign a report + /// @param offchainTransmitters ith element is address ith oracle used to transmit reports (in this case used for flexible additional field, such as CSA pub keys) + /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + /// @dev This function is a modified version of the method from OCR2Abstract + function _configDigestFromConfigData( + uint256 sourceChainId, + address sourceAddress, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + sourceChainId, + sourceAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + // 0x0009 corresponds to ConfigDigestPrefixLLO in libocr + uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + /// @inheritdoc IChannelVerifier + function activateConfig(bytes32 configDigest) external onlyOwner { + if (configDigest == bytes32("")) revert DigestEmpty(); + if (s_feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(configDigest); + s_feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; + emit ConfigActivated(configDigest); + } + + /// @inheritdoc IChannelVerifier + function deactivateConfig(bytes32 configDigest) external onlyOwner { + if (configDigest == bytes32("")) revert DigestEmpty(); + if (s_feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(configDigest); + if (configDigest == s_feedVerifierState.latestConfigDigest) { + revert CannotDeactivateLatestConfig(configDigest); + } + s_feedVerifierState.s_verificationDataConfigs[configDigest].isActive = false; + emit ConfigDeactivated(configDigest); + } + + /// @inheritdoc IChannelVerifier + function activateFeed(bytes32 feedId) external onlyOwner { + if (s_feedVerifierState.deactivatedFeeds[feedId]) return; + + s_feedVerifierState.deactivatedFeeds[feedId] = false; + emit FeedActivated(feedId); + } + + /// @inheritdoc IChannelVerifier + function deactivateFeed(bytes32 feedId) external onlyOwner { + if (s_feedVerifierState.deactivatedFeeds[feedId] == false) return; + + s_feedVerifierState.deactivatedFeeds[feedId] = true; + emit FeedDeactivated(feedId); + } + + /// @inheritdoc IChannelVerifier + function latestConfigDigestAndEpoch() + external + view + override + returns (bool scanLogs, bytes32 configDigest, uint32 epoch) + { + return (false, s_feedVerifierState.latestConfigDigest, s_feedVerifierState.latestEpoch); + } + + /// @inheritdoc IChannelVerifier + function latestConfigDetails() + external + view + override + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) + { + return ( + s_feedVerifierState.configCount, + s_feedVerifierState.latestConfigBlockNumber, + s_feedVerifierState.latestConfigDigest + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol new file mode 100644 index 00000000000..97fafc2cb5c --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; + +interface IChannelConfigStore is IERC165 { + // function setStagingConfig(bytes32 configDigest, ChannelConfiguration calldata channelConfig) external; + + // function promoteStagingConfig(bytes32 configDigest) external; + + function addChannel(uint32 channelId, ChannelDefinition calldata channelDefinition) external; + + function removeChannel(uint32 channelId) external; + + function getChannelDefinitions(uint32 channelId) external view returns (ChannelDefinition memory); + + // struct ChannelConfiguration { + // bytes32 configDigest; + // } + + struct ChannelDefinition { + // e.g. evm, solana, CosmWasm, kalechain, etc... + bytes8 reportFormat; + // Specifies the chain on which this channel can be verified. Currently uses + // CCIP chain selectors, but lots of other schemes are possible as well. + uint64 chainSelector; + // We assume that StreamIDs is always non-empty and that the 0-th stream + // contains the verification price in LINK and the 1-st stream contains the + // verification price in the native coin. + uint32[] streamIDs; + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol new file mode 100644 index 00000000000..6bab5912a70 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IChannelVerifier is IERC165 { + /** + * @notice Verifies that the data encoded has been signed + * correctly by routing to the correct verifier. + * @param signedReport The encoded data to be verified. + * @param sender The address that requested to verify the contract. + * This is only used for logging purposes. + * @dev Verification is typically only done through the proxy contract so + * we can't just use msg.sender to log the requester as the msg.sender + * contract will always be the proxy. + * @return verifierResponse The encoded verified response. + */ + function verify(bytes calldata signedReport, address sender) external returns (bytes memory verifierResponse); + + /** + * @notice sets offchain reporting protocol configuration incl. participating oracles + * @param signers addresses with which oracles sign the reports + * @param offchainTransmitters CSA key for the ith Oracle + * @param f number of faulty oracles the system can tolerate + * @param onchainConfig serialized configuration used by the contract (and possibly oracles) + * @param offchainConfigVersion version number for offchainEncoding schema + * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + */ + function setConfig( + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external; + + /** + * @notice identical to `setConfig` except with args for sourceChainId and sourceAddress + * @param sourceChainId Chain ID of source config + * @param sourceAddress Address of source config Verifier + * @param newConfigCount Param to force the new config count + * @param signers addresses with which oracles sign the reports + * @param offchainTransmitters CSA key for the ith Oracle + * @param f number of faulty oracles the system can tolerate + * @param onchainConfig serialized configuration used by the contract (and possibly oracles) + * @param offchainConfigVersion version number for offchainEncoding schema + * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + */ + function setConfigFromSource( + uint256 sourceChainId, + address sourceAddress, + uint32 newConfigCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external; + + /** + * @notice Activates the configuration for a config digest + * @param configDigest The config digest to activate + * @dev This function can be called by the contract admin to activate a configuration. + */ + function activateConfig(bytes32 configDigest) external; + + /** + * @notice Deactivates the configuration for a config digest + * @param configDigest The config digest to deactivate + * @dev This function can be called by the contract admin to deactivate an incorrect configuration. + */ + function deactivateConfig(bytes32 configDigest) external; + + /** + * @notice Activates the given feed + * @param feedId Feed ID to activated + * @dev This function can be called by the contract admin to activate a feed + */ + function activateFeed(bytes32 feedId) external; + + /** + * @notice Deactivates the given feed + * @param feedId Feed ID to deactivated + * @dev This function can be called by the contract admin to deactivate a feed + */ + function deactivateFeed(bytes32 feedId) external; + + /** + * @notice returns the latest config digest and epoch + * @return scanLogs indicates whether to rely on the configDigest and epoch + * returned or whether to scan logs for the Transmitted event instead. + * @return configDigest + * @return epoch + */ + function latestConfigDigestAndEpoch() external view returns (bool scanLogs, bytes32 configDigest, uint32 epoch); + + /** + * @notice information about current offchain reporting protocol configuration + * @return configCount ordinal number of current config, out of all configs applied to this contract so far + * @return blockNumber block at which this config was set + * @return configDigest domain-separation tag for current config + */ + function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); +} diff --git a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol new file mode 100644 index 00000000000..650b3b4a81e --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +// ExposedChannelVerifier exposes certain internal Verifier +// methods/structures so that golang code can access them, and we get +// reliable type checking on their usage +contract ExposedChannelVerifier { + constructor() {} + + function _configDigestFromConfigData( + uint256 chainId, + address contractAddress, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + chainId, + contractAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + // 0x0009 corresponds to ConfigDigestPrefixLLO in libocr + uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + function exposedConfigDigestFromConfigData( + uint256 _chainId, + address _contractAddress, + uint64 _configCount, + address[] memory _signers, + bytes32[] memory _offchainTransmitters, + uint8 _f, + bytes calldata _onchainConfig, + uint64 _encodedConfigVersion, + bytes memory _encodedConfig + ) public pure returns (bytes32) { + return + _configDigestFromConfigData( + _chainId, + _contractAddress, + _configCount, + _signers, + _offchainTransmitters, + _f, + _onchainConfig, + _encodedConfigVersion, + _encodedConfig + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol new file mode 100644 index 00000000000..1c004bf3846 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +// ExposedVerifier exposes certain internal Verifier +// methods/structures so that golang code can access them, and we get +// reliable type checking on their usage +contract ExposedVerifier { + constructor() {} + + function _configDigestFromConfigData( + bytes32 feedId, + uint256 chainId, + address contractAddress, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + feedId, + chainId, + contractAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + function exposedConfigDigestFromConfigData( + bytes32 _feedId, + uint256 _chainId, + address _contractAddress, + uint64 _configCount, + address[] memory _signers, + bytes32[] memory _offchainTransmitters, + uint8 _f, + bytes calldata _onchainConfig, + uint64 _encodedConfigVersion, + bytes memory _encodedConfig + ) public pure returns (bytes32) { + return + _configDigestFromConfigData( + _feedId, + _chainId, + _contractAddress, + _configCount, + _signers, + _offchainTransmitters, + _f, + _onchainConfig, + _encodedConfigVersion, + _encodedConfig + ); + } +} diff --git a/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go b/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go new file mode 100644 index 00000000000..d6874fed1f7 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go @@ -0,0 +1,1032 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package channel_config_store + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type IChannelConfigStoreChannelDefinition struct { + ReportFormat [8]byte + ChainSelector uint64 + StreamIDs []uint32 +} + +var ChannelConfigStoreMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ChannelDefinitionNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyStreamIDs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByEOA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StagingConfigAlreadyPromoted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroReportFormat\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"ChannelDefinitionRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes8\",\"name\":\"reportFormat\",\"type\":\"bytes8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"NewChannelDefinition\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"PromoteStagingConfig\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes8\",\"name\":\"reportFormat\",\"type\":\"bytes8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"addChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"getChannelDefinitions\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes8\",\"name\":\"reportFormat\",\"type\":\"bytes8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"removeChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610f1e806101576000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80637e37e7191161005b5780637e37e719146101535780638da5cb5b14610166578063f2fde38b1461018e578063f5810719146101a157600080fd5b806301ffc9a71461008d578063181f5a77146100f757806322d9780c1461013657806379ba50971461014b575b600080fd5b6100e261009b366004610816565b7fffffffff00000000000000000000000000000000000000000000000000000000167fa96f980c000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4368616e6e656c436f6e66696753746f726520302e302e300000000000000000602082015290516100ee919061085f565b6101496101443660046108dd565b6101c1565b005b61014961032d565b610149610161366004610934565b61042f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ee565b61014961019c366004610951565b61050f565b6101b46101af366004610934565b610523565b6040516100ee9190610987565b6101c9610665565b6101d66040820182610a1f565b9050600003610211576040517f4b620e2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102216040820160208301610aa4565b67ffffffffffffffff16600003610264576040517ff89d762900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102716020820182610aef565b7fffffffffffffffff000000000000000000000000000000000000000000000000166000036102cc576040517febd3ef0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8216600090815260026020526040902081906102ed8282610ce5565b9050507fbf2cd44714205d633d3f888ac72ea66d53cd12d4c4e8723a80d9c0bc36484a548282604051610321929190610e2e565b60405180910390a15050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610437610665565b63ffffffff81166000908152600260205260408120600101549003610488576040517fd1a751e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8116600090815260026020526040812080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000168155906104d160018301826107dd565b505060405163ffffffff821681527f334e877e9691ecae0660510061973bebaa8b4fb37332ed6090052e630c9798619060200160405180910390a150565b610517610665565b610520816106e8565b50565b60408051606080820183526000808352602083015291810191909152333214610578576040517f74e2cd5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff82166000908152600260209081526040918290208251606081018452815460c081901b7fffffffffffffffff00000000000000000000000000000000000000000000000016825268010000000000000000900467ffffffffffffffff16818401526001820180548551818602810186018752818152929593949386019383018282801561065557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116106185790505b5050505050815250509050919050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103aa565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610767576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103aa565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b50805460008255600701600890049060005260206000209081019061052091905b8082111561081257600081556001016107fe565b5090565b60006020828403121561082857600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461085857600080fd5b9392505050565b600060208083528351808285015260005b8181101561088c57858101830151858201604001528201610870565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b63ffffffff8116811461052057600080fd5b600080604083850312156108f057600080fd5b82356108fb816108cb565b9150602083013567ffffffffffffffff81111561091757600080fd5b83016060818603121561092957600080fd5b809150509250929050565b60006020828403121561094657600080fd5b8135610858816108cb565b60006020828403121561096357600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461085857600080fd5b60006020808352608083017fffffffffffffffff0000000000000000000000000000000000000000000000008551168285015267ffffffffffffffff82860151166040850152604085015160608086015281815180845260a0870191508483019350600092505b80831015610a1457835163ffffffff1682529284019260019290920191908401906109ee565b509695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610a5457600080fd5b83018035915067ffffffffffffffff821115610a6f57600080fd5b6020019150600581901b3603821315610a8757600080fd5b9250929050565b67ffffffffffffffff8116811461052057600080fd5b600060208284031215610ab657600080fd5b813561085881610a8e565b7fffffffffffffffff0000000000000000000000000000000000000000000000008116811461052057600080fd5b600060208284031215610b0157600080fd5b813561085881610ac1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b68010000000000000000821115610b5457610b54610b0c565b805482825580831015610bd9576000828152602081206007850160031c81016007840160031c82019150601c8660021b168015610bc0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8083018054828460200360031b1c16815550505b505b81811015610bd557828155600101610bc2565b5050505b505050565b60008135610beb816108cb565b92915050565b67ffffffffffffffff831115610c0957610c09610b0c565b610c138382610b3b565b60008181526020902082908460031c60005b81811015610c7e576000805b6008811015610c7157610c60610c4687610bde565b63ffffffff908116600584901b90811b91901b1984161790565b602096909601959150600101610c31565b5083820155600101610c25565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88616808703818814610cdb576000805b82811015610cd557610cc4610c4688610bde565b602097909701969150600101610cb0565b50848401555b5050505050505050565b8135610cf081610ac1565b8060c01c90508154817fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000082161783556020840135610d2d81610a8e565b6fffffffffffffffff00000000000000008160401b16837fffffffffffffffffffffffffffffffff0000000000000000000000000000000084161717845550505060408201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112610da357600080fd5b8201803567ffffffffffffffff811115610dbc57600080fd5b6020820191508060051b3603821315610dd457600080fd5b610de2818360018601610bf1565b50505050565b8183526000602080850194508260005b85811015610e23578135610e0b816108cb565b63ffffffff1687529582019590820190600101610df8565b509495945050505050565b63ffffffff831681526040602082015260008235610e4b81610ac1565b7fffffffffffffffff0000000000000000000000000000000000000000000000001660408301526020830135610e8081610a8e565b67ffffffffffffffff8082166060850152604085013591507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1853603018212610ec857600080fd5b6020918501918201913581811115610edf57600080fd5b8060051b3603831315610ef157600080fd5b60606080860152610f0660a086018285610de8565b97965050505050505056fea164736f6c6343000813000a", +} + +var ChannelConfigStoreABI = ChannelConfigStoreMetaData.ABI + +var ChannelConfigStoreBin = ChannelConfigStoreMetaData.Bin + +func DeployChannelConfigStore(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ChannelConfigStore, error) { + parsed, err := ChannelConfigStoreMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ChannelConfigStoreBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ChannelConfigStore{address: address, abi: *parsed, ChannelConfigStoreCaller: ChannelConfigStoreCaller{contract: contract}, ChannelConfigStoreTransactor: ChannelConfigStoreTransactor{contract: contract}, ChannelConfigStoreFilterer: ChannelConfigStoreFilterer{contract: contract}}, nil +} + +type ChannelConfigStore struct { + address common.Address + abi abi.ABI + ChannelConfigStoreCaller + ChannelConfigStoreTransactor + ChannelConfigStoreFilterer +} + +type ChannelConfigStoreCaller struct { + contract *bind.BoundContract +} + +type ChannelConfigStoreTransactor struct { + contract *bind.BoundContract +} + +type ChannelConfigStoreFilterer struct { + contract *bind.BoundContract +} + +type ChannelConfigStoreSession struct { + Contract *ChannelConfigStore + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ChannelConfigStoreCallerSession struct { + Contract *ChannelConfigStoreCaller + CallOpts bind.CallOpts +} + +type ChannelConfigStoreTransactorSession struct { + Contract *ChannelConfigStoreTransactor + TransactOpts bind.TransactOpts +} + +type ChannelConfigStoreRaw struct { + Contract *ChannelConfigStore +} + +type ChannelConfigStoreCallerRaw struct { + Contract *ChannelConfigStoreCaller +} + +type ChannelConfigStoreTransactorRaw struct { + Contract *ChannelConfigStoreTransactor +} + +func NewChannelConfigStore(address common.Address, backend bind.ContractBackend) (*ChannelConfigStore, error) { + abi, err := abi.JSON(strings.NewReader(ChannelConfigStoreABI)) + if err != nil { + return nil, err + } + contract, err := bindChannelConfigStore(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ChannelConfigStore{address: address, abi: abi, ChannelConfigStoreCaller: ChannelConfigStoreCaller{contract: contract}, ChannelConfigStoreTransactor: ChannelConfigStoreTransactor{contract: contract}, ChannelConfigStoreFilterer: ChannelConfigStoreFilterer{contract: contract}}, nil +} + +func NewChannelConfigStoreCaller(address common.Address, caller bind.ContractCaller) (*ChannelConfigStoreCaller, error) { + contract, err := bindChannelConfigStore(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ChannelConfigStoreCaller{contract: contract}, nil +} + +func NewChannelConfigStoreTransactor(address common.Address, transactor bind.ContractTransactor) (*ChannelConfigStoreTransactor, error) { + contract, err := bindChannelConfigStore(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ChannelConfigStoreTransactor{contract: contract}, nil +} + +func NewChannelConfigStoreFilterer(address common.Address, filterer bind.ContractFilterer) (*ChannelConfigStoreFilterer, error) { + contract, err := bindChannelConfigStore(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ChannelConfigStoreFilterer{contract: contract}, nil +} + +func bindChannelConfigStore(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ChannelConfigStoreMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ChannelConfigStore *ChannelConfigStoreRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ChannelConfigStore.Contract.ChannelConfigStoreCaller.contract.Call(opts, result, method, params...) +} + +func (_ChannelConfigStore *ChannelConfigStoreRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.ChannelConfigStoreTransactor.contract.Transfer(opts) +} + +func (_ChannelConfigStore *ChannelConfigStoreRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.ChannelConfigStoreTransactor.contract.Transact(opts, method, params...) +} + +func (_ChannelConfigStore *ChannelConfigStoreCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ChannelConfigStore.Contract.contract.Call(opts, result, method, params...) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.contract.Transfer(opts) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.contract.Transact(opts, method, params...) +} + +func (_ChannelConfigStore *ChannelConfigStoreCaller) GetChannelDefinitions(opts *bind.CallOpts, channelId uint32) (IChannelConfigStoreChannelDefinition, error) { + var out []interface{} + err := _ChannelConfigStore.contract.Call(opts, &out, "getChannelDefinitions", channelId) + + if err != nil { + return *new(IChannelConfigStoreChannelDefinition), err + } + + out0 := *abi.ConvertType(out[0], new(IChannelConfigStoreChannelDefinition)).(*IChannelConfigStoreChannelDefinition) + + return out0, err + +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) GetChannelDefinitions(channelId uint32) (IChannelConfigStoreChannelDefinition, error) { + return _ChannelConfigStore.Contract.GetChannelDefinitions(&_ChannelConfigStore.CallOpts, channelId) +} + +func (_ChannelConfigStore *ChannelConfigStoreCallerSession) GetChannelDefinitions(channelId uint32) (IChannelConfigStoreChannelDefinition, error) { + return _ChannelConfigStore.Contract.GetChannelDefinitions(&_ChannelConfigStore.CallOpts, channelId) +} + +func (_ChannelConfigStore *ChannelConfigStoreCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ChannelConfigStore.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) Owner() (common.Address, error) { + return _ChannelConfigStore.Contract.Owner(&_ChannelConfigStore.CallOpts) +} + +func (_ChannelConfigStore *ChannelConfigStoreCallerSession) Owner() (common.Address, error) { + return _ChannelConfigStore.Contract.Owner(&_ChannelConfigStore.CallOpts) +} + +func (_ChannelConfigStore *ChannelConfigStoreCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _ChannelConfigStore.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ChannelConfigStore.Contract.SupportsInterface(&_ChannelConfigStore.CallOpts, interfaceId) +} + +func (_ChannelConfigStore *ChannelConfigStoreCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ChannelConfigStore.Contract.SupportsInterface(&_ChannelConfigStore.CallOpts, interfaceId) +} + +func (_ChannelConfigStore *ChannelConfigStoreCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ChannelConfigStore.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) TypeAndVersion() (string, error) { + return _ChannelConfigStore.Contract.TypeAndVersion(&_ChannelConfigStore.CallOpts) +} + +func (_ChannelConfigStore *ChannelConfigStoreCallerSession) TypeAndVersion() (string, error) { + return _ChannelConfigStore.Contract.TypeAndVersion(&_ChannelConfigStore.CallOpts) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChannelConfigStore.contract.Transact(opts, "acceptOwnership") +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) AcceptOwnership() (*types.Transaction, error) { + return _ChannelConfigStore.Contract.AcceptOwnership(&_ChannelConfigStore.TransactOpts) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _ChannelConfigStore.Contract.AcceptOwnership(&_ChannelConfigStore.TransactOpts) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactor) AddChannel(opts *bind.TransactOpts, channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) { + return _ChannelConfigStore.contract.Transact(opts, "addChannel", channelId, channelDefinition) +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) AddChannel(channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.AddChannel(&_ChannelConfigStore.TransactOpts, channelId, channelDefinition) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) AddChannel(channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.AddChannel(&_ChannelConfigStore.TransactOpts, channelId, channelDefinition) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactor) RemoveChannel(opts *bind.TransactOpts, channelId uint32) (*types.Transaction, error) { + return _ChannelConfigStore.contract.Transact(opts, "removeChannel", channelId) +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) RemoveChannel(channelId uint32) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.RemoveChannel(&_ChannelConfigStore.TransactOpts, channelId) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) RemoveChannel(channelId uint32) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.RemoveChannel(&_ChannelConfigStore.TransactOpts, channelId) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _ChannelConfigStore.contract.Transact(opts, "transferOwnership", to) +} + +func (_ChannelConfigStore *ChannelConfigStoreSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.TransferOwnership(&_ChannelConfigStore.TransactOpts, to) +} + +func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.TransferOwnership(&_ChannelConfigStore.TransactOpts, to) +} + +type ChannelConfigStoreChannelDefinitionRemovedIterator struct { + Event *ChannelConfigStoreChannelDefinitionRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelConfigStoreChannelDefinitionRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreChannelDefinitionRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreChannelDefinitionRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelConfigStoreChannelDefinitionRemovedIterator) Error() error { + return it.fail +} + +func (it *ChannelConfigStoreChannelDefinitionRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelConfigStoreChannelDefinitionRemoved struct { + ChannelId uint32 + Raw types.Log +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterChannelDefinitionRemoved(opts *bind.FilterOpts) (*ChannelConfigStoreChannelDefinitionRemovedIterator, error) { + + logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "ChannelDefinitionRemoved") + if err != nil { + return nil, err + } + return &ChannelConfigStoreChannelDefinitionRemovedIterator{contract: _ChannelConfigStore.contract, event: "ChannelDefinitionRemoved", logs: logs, sub: sub}, nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchChannelDefinitionRemoved(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreChannelDefinitionRemoved) (event.Subscription, error) { + + logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "ChannelDefinitionRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelConfigStoreChannelDefinitionRemoved) + if err := _ChannelConfigStore.contract.UnpackLog(event, "ChannelDefinitionRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParseChannelDefinitionRemoved(log types.Log) (*ChannelConfigStoreChannelDefinitionRemoved, error) { + event := new(ChannelConfigStoreChannelDefinitionRemoved) + if err := _ChannelConfigStore.contract.UnpackLog(event, "ChannelDefinitionRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelConfigStoreNewChannelDefinitionIterator struct { + Event *ChannelConfigStoreNewChannelDefinition + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelConfigStoreNewChannelDefinitionIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreNewChannelDefinition) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreNewChannelDefinition) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelConfigStoreNewChannelDefinitionIterator) Error() error { + return it.fail +} + +func (it *ChannelConfigStoreNewChannelDefinitionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelConfigStoreNewChannelDefinition struct { + ChannelId uint32 + ChannelDefinition IChannelConfigStoreChannelDefinition + Raw types.Log +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterNewChannelDefinition(opts *bind.FilterOpts) (*ChannelConfigStoreNewChannelDefinitionIterator, error) { + + logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "NewChannelDefinition") + if err != nil { + return nil, err + } + return &ChannelConfigStoreNewChannelDefinitionIterator{contract: _ChannelConfigStore.contract, event: "NewChannelDefinition", logs: logs, sub: sub}, nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchNewChannelDefinition(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreNewChannelDefinition) (event.Subscription, error) { + + logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "NewChannelDefinition") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelConfigStoreNewChannelDefinition) + if err := _ChannelConfigStore.contract.UnpackLog(event, "NewChannelDefinition", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParseNewChannelDefinition(log types.Log) (*ChannelConfigStoreNewChannelDefinition, error) { + event := new(ChannelConfigStoreNewChannelDefinition) + if err := _ChannelConfigStore.contract.UnpackLog(event, "NewChannelDefinition", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelConfigStoreOwnershipTransferRequestedIterator struct { + Event *ChannelConfigStoreOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelConfigStoreOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelConfigStoreOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *ChannelConfigStoreOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelConfigStoreOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelConfigStoreOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &ChannelConfigStoreOwnershipTransferRequestedIterator{contract: _ChannelConfigStore.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelConfigStoreOwnershipTransferRequested) + if err := _ChannelConfigStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParseOwnershipTransferRequested(log types.Log) (*ChannelConfigStoreOwnershipTransferRequested, error) { + event := new(ChannelConfigStoreOwnershipTransferRequested) + if err := _ChannelConfigStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelConfigStoreOwnershipTransferredIterator struct { + Event *ChannelConfigStoreOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelConfigStoreOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelConfigStoreOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *ChannelConfigStoreOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelConfigStoreOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelConfigStoreOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &ChannelConfigStoreOwnershipTransferredIterator{contract: _ChannelConfigStore.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelConfigStoreOwnershipTransferred) + if err := _ChannelConfigStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParseOwnershipTransferred(log types.Log) (*ChannelConfigStoreOwnershipTransferred, error) { + event := new(ChannelConfigStoreOwnershipTransferred) + if err := _ChannelConfigStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelConfigStorePromoteStagingConfigIterator struct { + Event *ChannelConfigStorePromoteStagingConfig + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelConfigStorePromoteStagingConfigIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStorePromoteStagingConfig) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelConfigStorePromoteStagingConfig) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelConfigStorePromoteStagingConfigIterator) Error() error { + return it.fail +} + +func (it *ChannelConfigStorePromoteStagingConfigIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelConfigStorePromoteStagingConfig struct { + ChannelId uint32 + Raw types.Log +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterPromoteStagingConfig(opts *bind.FilterOpts) (*ChannelConfigStorePromoteStagingConfigIterator, error) { + + logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "PromoteStagingConfig") + if err != nil { + return nil, err + } + return &ChannelConfigStorePromoteStagingConfigIterator{contract: _ChannelConfigStore.contract, event: "PromoteStagingConfig", logs: logs, sub: sub}, nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchPromoteStagingConfig(opts *bind.WatchOpts, sink chan<- *ChannelConfigStorePromoteStagingConfig) (event.Subscription, error) { + + logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "PromoteStagingConfig") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelConfigStorePromoteStagingConfig) + if err := _ChannelConfigStore.contract.UnpackLog(event, "PromoteStagingConfig", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParsePromoteStagingConfig(log types.Log) (*ChannelConfigStorePromoteStagingConfig, error) { + event := new(ChannelConfigStorePromoteStagingConfig) + if err := _ChannelConfigStore.contract.UnpackLog(event, "PromoteStagingConfig", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_ChannelConfigStore *ChannelConfigStore) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ChannelConfigStore.abi.Events["ChannelDefinitionRemoved"].ID: + return _ChannelConfigStore.ParseChannelDefinitionRemoved(log) + case _ChannelConfigStore.abi.Events["NewChannelDefinition"].ID: + return _ChannelConfigStore.ParseNewChannelDefinition(log) + case _ChannelConfigStore.abi.Events["OwnershipTransferRequested"].ID: + return _ChannelConfigStore.ParseOwnershipTransferRequested(log) + case _ChannelConfigStore.abi.Events["OwnershipTransferred"].ID: + return _ChannelConfigStore.ParseOwnershipTransferred(log) + case _ChannelConfigStore.abi.Events["PromoteStagingConfig"].ID: + return _ChannelConfigStore.ParsePromoteStagingConfig(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ChannelConfigStoreChannelDefinitionRemoved) Topic() common.Hash { + return common.HexToHash("0x334e877e9691ecae0660510061973bebaa8b4fb37332ed6090052e630c979861") +} + +func (ChannelConfigStoreNewChannelDefinition) Topic() common.Hash { + return common.HexToHash("0xbf2cd44714205d633d3f888ac72ea66d53cd12d4c4e8723a80d9c0bc36484a54") +} + +func (ChannelConfigStoreOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (ChannelConfigStoreOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (ChannelConfigStorePromoteStagingConfig) Topic() common.Hash { + return common.HexToHash("0xbdd8ee023f9979bf23e8af6fd7241f484024e83fb0fabd11bb7fd5e9bed7308a") +} + +func (_ChannelConfigStore *ChannelConfigStore) Address() common.Address { + return _ChannelConfigStore.address +} + +type ChannelConfigStoreInterface interface { + GetChannelDefinitions(opts *bind.CallOpts, channelId uint32) (IChannelConfigStoreChannelDefinition, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddChannel(opts *bind.TransactOpts, channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) + + RemoveChannel(opts *bind.TransactOpts, channelId uint32) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterChannelDefinitionRemoved(opts *bind.FilterOpts) (*ChannelConfigStoreChannelDefinitionRemovedIterator, error) + + WatchChannelDefinitionRemoved(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreChannelDefinitionRemoved) (event.Subscription, error) + + ParseChannelDefinitionRemoved(log types.Log) (*ChannelConfigStoreChannelDefinitionRemoved, error) + + FilterNewChannelDefinition(opts *bind.FilterOpts) (*ChannelConfigStoreNewChannelDefinitionIterator, error) + + WatchNewChannelDefinition(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreNewChannelDefinition) (event.Subscription, error) + + ParseNewChannelDefinition(log types.Log) (*ChannelConfigStoreNewChannelDefinition, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelConfigStoreOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*ChannelConfigStoreOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelConfigStoreOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*ChannelConfigStoreOwnershipTransferred, error) + + FilterPromoteStagingConfig(opts *bind.FilterOpts) (*ChannelConfigStorePromoteStagingConfigIterator, error) + + WatchPromoteStagingConfig(opts *bind.WatchOpts, sink chan<- *ChannelConfigStorePromoteStagingConfig) (event.Subscription, error) + + ParsePromoteStagingConfig(log types.Log) (*ChannelConfigStorePromoteStagingConfig, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go b/core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go new file mode 100644 index 00000000000..104cab61040 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go @@ -0,0 +1,1583 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package channel_verifier + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +var ChannelVerifierMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxyAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CannotDeactivateLatestConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DigestEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestNotSet\",\"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\":[],\"name\":\"FeedIdEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InactiveFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expectedNumSigners\",\"type\":\"uint256\"}],\"name\":\"IncorrectSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedDeactivated\",\"type\":\"event\"},{\"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\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"sourceChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sourceAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"newConfigCount\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifierResponse\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620020ed380380620020ed8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611ef9620001f4600039600061051a0152611ef96000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063564a0a7a1161008c5780638da5cb5b116100665780638da5cb5b14610247578063afcb95d71461026f578063eb1dc803146102a4578063f2fde38b146102b757600080fd5b8063564a0a7a146101fc57806379ba50971461020f57806381ff70481461021757600080fd5b8063181f5a77116100c8578063181f5a77146101815780633d3ac1b5146101c35780633dd86430146101d657806354e68a81146101e957600080fd5b806301ffc9a7146100ef5780630d1d79af146101595780630f672ef41461016e575b600080fd5b6101446100fd3660046113d0565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61016c610167366004611419565b6102ca565b005b61016c61017c366004611419565b6103d0565b60408051808201909152601581527f4368616e6e656c566572696669657220302e302e30000000000000000000000060208201525b6040516101509190611496565b6101b66101d13660046114d2565b610500565b61016c6101e4366004611419565b610680565b61016c6101f7366004611866565b6106fd565b61016c61020a366004611419565b61080d565b61016c61088d565b6002546003546040805163ffffffff80851682526401000000009094049093166020840152820152606001610150565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610150565b600354600254604080516000815260208101939093526801000000000000000090910463ffffffff1690820152606001610150565b61016c6102b2366004611986565b61098a565b61016c6102c5366004611a79565b610a52565b6102d2610a63565b80610309576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604081205460ff16900361035b576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6000818152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055517fa543797a0501218bba8a3daf75a71c8df8d1a7f791f4e44d40e43b6450183cea906103c59083815260200190565b60405180910390a150565b6103d8610a63565b8061040f576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604081205460ff16900361045c576040517f74eb4b9300000000000000000000000000000000000000000000000000000000815260048101829052602401610352565b600354810361049a576040517f67863f4400000000000000000000000000000000000000000000000000000000815260048101829052602401610352565b6000818152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055517f5bfaab86edc1b932e3c334327a591c9ded067cb521abae19b95ca927d6076579906103c59083815260200190565b60603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610571576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080610583888a018a611a94565b9450945094509450945060008461059990611b6f565b60008181526004602052604090205490915060ff16156105e8576040517f36dbe74800000000000000000000000000000000000000000000000000000000815260048101829052602401610352565b8551600081815260056020526040902061060482878784610ae6565b61060f886002610bda565b86516020880120610624818a89898987610c42565b60405173ffffffffffffffffffffffffffffffffffffffff8c16815284907f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250959b9a5050505050505050505050565b610688610a63565b60008181526004602052604090205460ff166106fa5760008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555182917ff438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b491a25b50565b86518560ff168060000361073d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610782576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610352565b61078d816003611c12565b82116107e5578161079f826003611c12565b6107aa906001611c2f565b6040517f9dd9e6d800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610352565b6107ed610a63565b6107ff8c8c8c8c8c8c8c8c8c8c610ebe565b505050505050505050505050565b610815610a63565b60008181526004602052604090205460ff16156106fa5760008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917ffc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd06191a250565b60015473ffffffffffffffffffffffffffffffffffffffff16331461090e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610352565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b86518560ff16806000036109ca576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610a0f576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610352565b610a1a816003611c12565b8211610a2c578161079f826003611c12565b610a34610a63565b610a47463060008c8c8c8c8c8c8c610ebe565b505050505050505050565b610a5a610a63565b6106fa81611230565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610352565b565b8054600090610af99060ff166001611c42565b8254909150610100900460ff16610b3f576040517fd990d62100000000000000000000000000000000000000000000000000000000815260048101869052602401610352565b8060ff16845114610b8b5783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff82166024820152604401610352565b8251845114610bd357835183516040517ff0d3140800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610352565b5050505050565b6020820151815463ffffffff600883901c81169168010000000000000000900416811115610c3c5782547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8316021783555b50505050565b60008686604051602001610c57929190611c5b565b6040516020818303038152906040528051906020012090506000610c8b604080518082019091526000808252602082015290565b8651600090815b81811015610e5657600186898360208110610caf57610caf611bb4565b610cbc91901a601b611c42565b8c8481518110610cce57610cce611bb4565b60200260200101518c8581518110610ce857610ce8611bb4565b602002602001015160405160008152602001604052604051610d26949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610d48573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff808216865293995093955090850192610100900490911690811115610dcd57610dcd611c97565b6001811115610dde57610dde611c97565b9052509350600184602001516001811115610dfb57610dfb611c97565b14610e32576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b8501945080610e4f90611cc6565b9050610c92565b50837e01010101010101010101010101010101010101010101010101010101010101851614610eb1576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b63ffffffff881615610eff57600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8a16179055610f35565b6002805463ffffffff16906000610f1583611cfe565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b600254600090610f54908c908c9063ffffffff168b8b8b8b8b8b611325565b600081815260056020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8a16176101001790559091505b88518160ff16101561118f576000898260ff1681518110610fb857610fb8611bb4565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611028576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600085815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452600190810190925290912054610100900460ff169081111561107957611079611c97565b14801591506110b4576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff841681526020810160019052600085815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684526001908101835292208351815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00821681178355928501519193919284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216179061010090849081111561117457611174611c97565b021790555090505050508061118890611d21565b9050610f95565b506002546040517f1074b4b9a073f79bd1f7f5c808348125ce0f25c27188df7efcaa7a08276051b3916111e29163ffffffff640100000000830481169286929116908d908d908d908d908d908d90611dc1565b60405180910390a1600280547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff1664010000000063ffffffff43160217905560035550505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036112af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610352565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808a8a8a8a8a8a8a8a8a60405160200161134999989796959493929190611e57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e09000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6000602082840312156113e257600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461141257600080fd5b9392505050565b60006020828403121561142b57600080fd5b5035919050565b6000815180845260005b818110156114585760208185018101518683018201520161143c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006114126020830184611432565b803573ffffffffffffffffffffffffffffffffffffffff811681146114cd57600080fd5b919050565b6000806000604084860312156114e757600080fd5b833567ffffffffffffffff808211156114ff57600080fd5b818601915086601f83011261151357600080fd5b81358181111561152257600080fd5b87602082850101111561153457600080fd5b60209283019550935061154a91860190506114a9565b90509250925092565b803563ffffffff811681146114cd57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156115b9576115b9611567565b60405290565b6040516060810167ffffffffffffffff811182821017156115b9576115b9611567565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561162957611629611567565b604052919050565b600067ffffffffffffffff82111561164b5761164b611567565b5060051b60200190565b600082601f83011261166657600080fd5b8135602061167b61167683611631565b6115e2565b82815260059290921b8401810191818101908684111561169a57600080fd5b8286015b848110156116bc576116af816114a9565b835291830191830161169e565b509695505050505050565b600082601f8301126116d857600080fd5b813560206116e861167683611631565b82815260059290921b8401810191818101908684111561170757600080fd5b8286015b848110156116bc578035835291830191830161170b565b803560ff811681146114cd57600080fd5b600082601f83011261174457600080fd5b813567ffffffffffffffff81111561175e5761175e611567565b61178f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016115e2565b8181528460208386010111156117a457600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146114cd57600080fd5b600082601f8301126117ea57600080fd5b813560206117fa61167683611631565b82815260069290921b8401810191818101908684111561181957600080fd5b8286015b848110156116bc57604081890312156118365760008081fd5b61183e611596565b611847826114a9565b81526118548583016117c1565b8186015283529183019160400161181d565b6000806000806000806000806000806101408b8d03121561188657600080fd5b8a35995061189660208c016114a9565b98506118a460408c01611553565b975060608b013567ffffffffffffffff808211156118c157600080fd5b6118cd8e838f01611655565b985060808d01359150808211156118e357600080fd5b6118ef8e838f016116c7565b97506118fd60a08e01611722565b965060c08d013591508082111561191357600080fd5b61191f8e838f01611733565b955061192d60e08e016117c1565b94506101008d013591508082111561194457600080fd5b6119508e838f01611733565b93506101208d013591508082111561196757600080fd5b506119748d828e016117d9565b9150509295989b9194979a5092959850565b600080600080600080600060e0888a0312156119a157600080fd5b873567ffffffffffffffff808211156119b957600080fd5b6119c58b838c01611655565b985060208a01359150808211156119db57600080fd5b6119e78b838c016116c7565b97506119f560408b01611722565b965060608a0135915080821115611a0b57600080fd5b611a178b838c01611733565b9550611a2560808b016117c1565b945060a08a0135915080821115611a3b57600080fd5b611a478b838c01611733565b935060c08a0135915080821115611a5d57600080fd5b50611a6a8a828b016117d9565b91505092959891949750929550565b600060208284031215611a8b57600080fd5b611412826114a9565b600080600080600060e08688031215611aac57600080fd5b86601f870112611abb57600080fd5b611ac36115bf565b806060880189811115611ad557600080fd5b885b81811015611aef578035845260209384019301611ad7565b5090965035905067ffffffffffffffff80821115611b0c57600080fd5b611b1889838a01611733565b95506080880135915080821115611b2e57600080fd5b611b3a89838a016116c7565b945060a0880135915080821115611b5057600080fd5b50611b5d888289016116c7565b9598949750929560c001359392505050565b80516020808301519190811015611bae577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611c2957611c29611be3565b92915050565b80820180821115611c2957611c29611be3565b60ff8181168382160190811115611c2957611c29611be3565b828152600060208083018460005b6003811015611c8657815183529183019190830190600101611c69565b505050506080820190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611cf757611cf7611be3565b5060010190565b600063ffffffff808316818103611d1757611d17611be3565b6001019392505050565b600060ff821660ff8103611d3757611d37611be3565b60010192915050565b600081518084526020808501945080840160005b83811015611d8657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611d54565b509495945050505050565b600081518084526020808501945080840160005b83811015611d8657815187529582019590820190600101611da5565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152611df18184018a611d40565b90508281036080840152611e058189611d91565b905060ff871660a084015282810360c0840152611e228187611432565b905067ffffffffffffffff851660e0840152828103610100840152611e478185611432565b9c9b505050505050505050505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152611e9e8285018b611d40565b91508382036080850152611eb2828a611d91565b915060ff881660a085015283820360c0850152611ecf8288611432565b90861660e08501528381036101008501529050611e47818561143256fea164736f6c6343000813000a", +} + +var ChannelVerifierABI = ChannelVerifierMetaData.ABI + +var ChannelVerifierBin = ChannelVerifierMetaData.Bin + +func DeployChannelVerifier(auth *bind.TransactOpts, backend bind.ContractBackend, verifierProxyAddr common.Address) (common.Address, *types.Transaction, *ChannelVerifier, error) { + parsed, err := ChannelVerifierMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ChannelVerifierBin), backend, verifierProxyAddr) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ChannelVerifier{address: address, abi: *parsed, ChannelVerifierCaller: ChannelVerifierCaller{contract: contract}, ChannelVerifierTransactor: ChannelVerifierTransactor{contract: contract}, ChannelVerifierFilterer: ChannelVerifierFilterer{contract: contract}}, nil +} + +type ChannelVerifier struct { + address common.Address + abi abi.ABI + ChannelVerifierCaller + ChannelVerifierTransactor + ChannelVerifierFilterer +} + +type ChannelVerifierCaller struct { + contract *bind.BoundContract +} + +type ChannelVerifierTransactor struct { + contract *bind.BoundContract +} + +type ChannelVerifierFilterer struct { + contract *bind.BoundContract +} + +type ChannelVerifierSession struct { + Contract *ChannelVerifier + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ChannelVerifierCallerSession struct { + Contract *ChannelVerifierCaller + CallOpts bind.CallOpts +} + +type ChannelVerifierTransactorSession struct { + Contract *ChannelVerifierTransactor + TransactOpts bind.TransactOpts +} + +type ChannelVerifierRaw struct { + Contract *ChannelVerifier +} + +type ChannelVerifierCallerRaw struct { + Contract *ChannelVerifierCaller +} + +type ChannelVerifierTransactorRaw struct { + Contract *ChannelVerifierTransactor +} + +func NewChannelVerifier(address common.Address, backend bind.ContractBackend) (*ChannelVerifier, error) { + abi, err := abi.JSON(strings.NewReader(ChannelVerifierABI)) + if err != nil { + return nil, err + } + contract, err := bindChannelVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ChannelVerifier{address: address, abi: abi, ChannelVerifierCaller: ChannelVerifierCaller{contract: contract}, ChannelVerifierTransactor: ChannelVerifierTransactor{contract: contract}, ChannelVerifierFilterer: ChannelVerifierFilterer{contract: contract}}, nil +} + +func NewChannelVerifierCaller(address common.Address, caller bind.ContractCaller) (*ChannelVerifierCaller, error) { + contract, err := bindChannelVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ChannelVerifierCaller{contract: contract}, nil +} + +func NewChannelVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*ChannelVerifierTransactor, error) { + contract, err := bindChannelVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ChannelVerifierTransactor{contract: contract}, nil +} + +func NewChannelVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*ChannelVerifierFilterer, error) { + contract, err := bindChannelVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ChannelVerifierFilterer{contract: contract}, nil +} + +func bindChannelVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ChannelVerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ChannelVerifier *ChannelVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ChannelVerifier.Contract.ChannelVerifierCaller.contract.Call(opts, result, method, params...) +} + +func (_ChannelVerifier *ChannelVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChannelVerifier.Contract.ChannelVerifierTransactor.contract.Transfer(opts) +} + +func (_ChannelVerifier *ChannelVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ChannelVerifier.Contract.ChannelVerifierTransactor.contract.Transact(opts, method, params...) +} + +func (_ChannelVerifier *ChannelVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ChannelVerifier.Contract.contract.Call(opts, result, method, params...) +} + +func (_ChannelVerifier *ChannelVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChannelVerifier.Contract.contract.Transfer(opts) +} + +func (_ChannelVerifier *ChannelVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ChannelVerifier.Contract.contract.Transact(opts, method, params...) +} + +func (_ChannelVerifier *ChannelVerifierCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _ChannelVerifier.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_ChannelVerifier *ChannelVerifierSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _ChannelVerifier.Contract.LatestConfigDetails(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _ChannelVerifier.Contract.LatestConfigDetails(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _ChannelVerifier.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_ChannelVerifier *ChannelVerifierSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _ChannelVerifier.Contract.LatestConfigDigestAndEpoch(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _ChannelVerifier.Contract.LatestConfigDigestAndEpoch(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ChannelVerifier.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ChannelVerifier *ChannelVerifierSession) Owner() (common.Address, error) { + return _ChannelVerifier.Contract.Owner(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierCallerSession) Owner() (common.Address, error) { + return _ChannelVerifier.Contract.Owner(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _ChannelVerifier.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ChannelVerifier *ChannelVerifierSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ChannelVerifier.Contract.SupportsInterface(&_ChannelVerifier.CallOpts, interfaceId) +} + +func (_ChannelVerifier *ChannelVerifierCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ChannelVerifier.Contract.SupportsInterface(&_ChannelVerifier.CallOpts, interfaceId) +} + +func (_ChannelVerifier *ChannelVerifierCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ChannelVerifier.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_ChannelVerifier *ChannelVerifierSession) TypeAndVersion() (string, error) { + return _ChannelVerifier.Contract.TypeAndVersion(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierCallerSession) TypeAndVersion() (string, error) { + return _ChannelVerifier.Contract.TypeAndVersion(&_ChannelVerifier.CallOpts) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "acceptOwnership") +} + +func (_ChannelVerifier *ChannelVerifierSession) AcceptOwnership() (*types.Transaction, error) { + return _ChannelVerifier.Contract.AcceptOwnership(&_ChannelVerifier.TransactOpts) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _ChannelVerifier.Contract.AcceptOwnership(&_ChannelVerifier.TransactOpts) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) ActivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "activateConfig", configDigest) +} + +func (_ChannelVerifier *ChannelVerifierSession) ActivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.ActivateConfig(&_ChannelVerifier.TransactOpts, configDigest) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) ActivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.ActivateConfig(&_ChannelVerifier.TransactOpts, configDigest) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "activateFeed", feedId) +} + +func (_ChannelVerifier *ChannelVerifierSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.ActivateFeed(&_ChannelVerifier.TransactOpts, feedId) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.ActivateFeed(&_ChannelVerifier.TransactOpts, feedId) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) DeactivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "deactivateConfig", configDigest) +} + +func (_ChannelVerifier *ChannelVerifierSession) DeactivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.DeactivateConfig(&_ChannelVerifier.TransactOpts, configDigest) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) DeactivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.DeactivateConfig(&_ChannelVerifier.TransactOpts, configDigest) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "deactivateFeed", feedId) +} + +func (_ChannelVerifier *ChannelVerifierSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.DeactivateFeed(&_ChannelVerifier.TransactOpts, feedId) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _ChannelVerifier.Contract.DeactivateFeed(&_ChannelVerifier.TransactOpts, feedId) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "setConfig", signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_ChannelVerifier *ChannelVerifierSession) SetConfig(signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _ChannelVerifier.Contract.SetConfig(&_ChannelVerifier.TransactOpts, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) SetConfig(signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _ChannelVerifier.Contract.SetConfig(&_ChannelVerifier.TransactOpts, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) SetConfigFromSource(opts *bind.TransactOpts, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "setConfigFromSource", sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_ChannelVerifier *ChannelVerifierSession) SetConfigFromSource(sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _ChannelVerifier.Contract.SetConfigFromSource(&_ChannelVerifier.TransactOpts, sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) SetConfigFromSource(sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _ChannelVerifier.Contract.SetConfigFromSource(&_ChannelVerifier.TransactOpts, sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "transferOwnership", to) +} + +func (_ChannelVerifier *ChannelVerifierSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ChannelVerifier.Contract.TransferOwnership(&_ChannelVerifier.TransactOpts, to) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ChannelVerifier.Contract.TransferOwnership(&_ChannelVerifier.TransactOpts, to) +} + +func (_ChannelVerifier *ChannelVerifierTransactor) Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _ChannelVerifier.contract.Transact(opts, "verify", signedReport, sender) +} + +func (_ChannelVerifier *ChannelVerifierSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _ChannelVerifier.Contract.Verify(&_ChannelVerifier.TransactOpts, signedReport, sender) +} + +func (_ChannelVerifier *ChannelVerifierTransactorSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _ChannelVerifier.Contract.Verify(&_ChannelVerifier.TransactOpts, signedReport, sender) +} + +type ChannelVerifierConfigActivatedIterator struct { + Event *ChannelVerifierConfigActivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierConfigActivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierConfigActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierConfigActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierConfigActivatedIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierConfigActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierConfigActivated struct { + ConfigDigest [32]byte + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterConfigActivated(opts *bind.FilterOpts) (*ChannelVerifierConfigActivatedIterator, error) { + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ConfigActivated") + if err != nil { + return nil, err + } + return &ChannelVerifierConfigActivatedIterator{contract: _ChannelVerifier.contract, event: "ConfigActivated", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigActivated) (event.Subscription, error) { + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ConfigActivated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierConfigActivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseConfigActivated(log types.Log) (*ChannelVerifierConfigActivated, error) { + event := new(ChannelVerifierConfigActivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelVerifierConfigDeactivatedIterator struct { + Event *ChannelVerifierConfigDeactivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierConfigDeactivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierConfigDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierConfigDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierConfigDeactivatedIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierConfigDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierConfigDeactivated struct { + ConfigDigest [32]byte + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterConfigDeactivated(opts *bind.FilterOpts) (*ChannelVerifierConfigDeactivatedIterator, error) { + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ConfigDeactivated") + if err != nil { + return nil, err + } + return &ChannelVerifierConfigDeactivatedIterator{contract: _ChannelVerifier.contract, event: "ConfigDeactivated", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigDeactivated) (event.Subscription, error) { + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ConfigDeactivated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierConfigDeactivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseConfigDeactivated(log types.Log) (*ChannelVerifierConfigDeactivated, error) { + event := new(ChannelVerifierConfigDeactivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelVerifierConfigSetIterator struct { + Event *ChannelVerifierConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierConfigSetIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + OffchainTransmitters [][32]byte + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterConfigSet(opts *bind.FilterOpts) (*ChannelVerifierConfigSetIterator, error) { + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &ChannelVerifierConfigSetIterator{contract: _ChannelVerifier.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigSet) (event.Subscription, error) { + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierConfigSet) + if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseConfigSet(log types.Log) (*ChannelVerifierConfigSet, error) { + event := new(ChannelVerifierConfigSet) + if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelVerifierFeedActivatedIterator struct { + Event *ChannelVerifierFeedActivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierFeedActivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierFeedActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierFeedActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierFeedActivatedIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierFeedActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierFeedActivated struct { + FeedId [32]byte + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedActivatedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "FeedActivated", feedIdRule) + if err != nil { + return nil, err + } + return &ChannelVerifierFeedActivatedIterator{contract: _ChannelVerifier.contract, event: "FeedActivated", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "FeedActivated", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierFeedActivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "FeedActivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseFeedActivated(log types.Log) (*ChannelVerifierFeedActivated, error) { + event := new(ChannelVerifierFeedActivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "FeedActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelVerifierFeedDeactivatedIterator struct { + Event *ChannelVerifierFeedDeactivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierFeedDeactivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierFeedDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierFeedDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierFeedDeactivatedIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierFeedDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierFeedDeactivated struct { + FeedId [32]byte + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedDeactivatedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "FeedDeactivated", feedIdRule) + if err != nil { + return nil, err + } + return &ChannelVerifierFeedDeactivatedIterator{contract: _ChannelVerifier.contract, event: "FeedDeactivated", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "FeedDeactivated", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierFeedDeactivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "FeedDeactivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseFeedDeactivated(log types.Log) (*ChannelVerifierFeedDeactivated, error) { + event := new(ChannelVerifierFeedDeactivated) + if err := _ChannelVerifier.contract.UnpackLog(event, "FeedDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelVerifierOwnershipTransferRequestedIterator struct { + Event *ChannelVerifierOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &ChannelVerifierOwnershipTransferRequestedIterator{contract: _ChannelVerifier.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierOwnershipTransferRequested) + if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseOwnershipTransferRequested(log types.Log) (*ChannelVerifierOwnershipTransferRequested, error) { + event := new(ChannelVerifierOwnershipTransferRequested) + if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelVerifierOwnershipTransferredIterator struct { + Event *ChannelVerifierOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &ChannelVerifierOwnershipTransferredIterator{contract: _ChannelVerifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierOwnershipTransferred) + if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseOwnershipTransferred(log types.Log) (*ChannelVerifierOwnershipTransferred, error) { + event := new(ChannelVerifierOwnershipTransferred) + if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ChannelVerifierReportVerifiedIterator struct { + Event *ChannelVerifierReportVerified + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChannelVerifierReportVerifiedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierReportVerified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChannelVerifierReportVerified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChannelVerifierReportVerifiedIterator) Error() error { + return it.fail +} + +func (it *ChannelVerifierReportVerifiedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChannelVerifierReportVerified struct { + FeedId [32]byte + Requester common.Address + Raw types.Log +} + +func (_ChannelVerifier *ChannelVerifierFilterer) FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierReportVerifiedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return &ChannelVerifierReportVerifiedIterator{contract: _ChannelVerifier.contract, event: "ReportVerified", logs: logs, sub: sub}, nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) WatchReportVerified(opts *bind.WatchOpts, sink chan<- *ChannelVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChannelVerifierReportVerified) + if err := _ChannelVerifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChannelVerifier *ChannelVerifierFilterer) ParseReportVerified(log types.Log) (*ChannelVerifierReportVerified, error) { + event := new(ChannelVerifierReportVerified) + if err := _ChannelVerifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_ChannelVerifier *ChannelVerifier) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ChannelVerifier.abi.Events["ConfigActivated"].ID: + return _ChannelVerifier.ParseConfigActivated(log) + case _ChannelVerifier.abi.Events["ConfigDeactivated"].ID: + return _ChannelVerifier.ParseConfigDeactivated(log) + case _ChannelVerifier.abi.Events["ConfigSet"].ID: + return _ChannelVerifier.ParseConfigSet(log) + case _ChannelVerifier.abi.Events["FeedActivated"].ID: + return _ChannelVerifier.ParseFeedActivated(log) + case _ChannelVerifier.abi.Events["FeedDeactivated"].ID: + return _ChannelVerifier.ParseFeedDeactivated(log) + case _ChannelVerifier.abi.Events["OwnershipTransferRequested"].ID: + return _ChannelVerifier.ParseOwnershipTransferRequested(log) + case _ChannelVerifier.abi.Events["OwnershipTransferred"].ID: + return _ChannelVerifier.ParseOwnershipTransferred(log) + case _ChannelVerifier.abi.Events["ReportVerified"].ID: + return _ChannelVerifier.ParseReportVerified(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ChannelVerifierConfigActivated) Topic() common.Hash { + return common.HexToHash("0xa543797a0501218bba8a3daf75a71c8df8d1a7f791f4e44d40e43b6450183cea") +} + +func (ChannelVerifierConfigDeactivated) Topic() common.Hash { + return common.HexToHash("0x5bfaab86edc1b932e3c334327a591c9ded067cb521abae19b95ca927d6076579") +} + +func (ChannelVerifierConfigSet) Topic() common.Hash { + return common.HexToHash("0x1074b4b9a073f79bd1f7f5c808348125ce0f25c27188df7efcaa7a08276051b3") +} + +func (ChannelVerifierFeedActivated) Topic() common.Hash { + return common.HexToHash("0xf438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b4") +} + +func (ChannelVerifierFeedDeactivated) Topic() common.Hash { + return common.HexToHash("0xfc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd061") +} + +func (ChannelVerifierOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (ChannelVerifierOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (ChannelVerifierReportVerified) Topic() common.Hash { + return common.HexToHash("0x58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc5") +} + +func (_ChannelVerifier *ChannelVerifier) Address() common.Address { + return _ChannelVerifier.address +} + +type ChannelVerifierInterface interface { + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ActivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) + + DeactivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + SetConfigFromSource(opts *bind.TransactOpts, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) + + FilterConfigActivated(opts *bind.FilterOpts) (*ChannelVerifierConfigActivatedIterator, error) + + WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigActivated) (event.Subscription, error) + + ParseConfigActivated(log types.Log) (*ChannelVerifierConfigActivated, error) + + FilterConfigDeactivated(opts *bind.FilterOpts) (*ChannelVerifierConfigDeactivatedIterator, error) + + WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigDeactivated) (event.Subscription, error) + + ParseConfigDeactivated(log types.Log) (*ChannelVerifierConfigDeactivated, error) + + FilterConfigSet(opts *bind.FilterOpts) (*ChannelVerifierConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*ChannelVerifierConfigSet, error) + + FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedActivatedIterator, error) + + WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) + + ParseFeedActivated(log types.Log) (*ChannelVerifierFeedActivated, error) + + FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedDeactivatedIterator, error) + + WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) + + ParseFeedDeactivated(log types.Log) (*ChannelVerifierFeedDeactivated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*ChannelVerifierOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*ChannelVerifierOwnershipTransferred, error) + + FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierReportVerifiedIterator, error) + + WatchReportVerified(opts *bind.WatchOpts, sink chan<- *ChannelVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) + + ParseReportVerified(log types.Log) (*ChannelVerifierReportVerified, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go b/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go new file mode 100644 index 00000000000..e516b9a247f --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go @@ -0,0 +1,202 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package exposed_channel_verifier + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ExposedChannelVerifierMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_configCount\",\"type\":\"uint64\"},{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_encodedConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_encodedConfig\",\"type\":\"bytes\"}],\"name\":\"exposedConfigDigestFromConfigData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061067e806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063b05a355014610030575b600080fd5b61004361003e3660046103f2565b610055565b60405190815260200160405180910390f35b60006100a08b8b8b8b8b8b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508c91506100af9050565b9b9a5050505050505050505050565b6000808a8a8a8a8a8a8a8a8a6040516020016100d399989796959493929190610594565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e09000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461017e57600080fd5b919050565b803567ffffffffffffffff8116811461017e57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156102115761021161019b565b604052919050565b600067ffffffffffffffff8211156102335761023361019b565b5060051b60200190565b600082601f83011261024e57600080fd5b8135602061026361025e83610219565b6101ca565b82815260059290921b8401810191818101908684111561028257600080fd5b8286015b848110156102a4576102978161015a565b8352918301918301610286565b509695505050505050565b600082601f8301126102c057600080fd5b813560206102d061025e83610219565b82815260059290921b840181019181810190868411156102ef57600080fd5b8286015b848110156102a457803583529183019183016102f3565b803560ff8116811461017e57600080fd5b60008083601f84011261032d57600080fd5b50813567ffffffffffffffff81111561034557600080fd5b60208301915083602082850101111561035d57600080fd5b9250929050565b600082601f83011261037557600080fd5b813567ffffffffffffffff81111561038f5761038f61019b565b6103c060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016101ca565b8181528460208386010111156103d557600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806000806000806000806101208b8d03121561041257600080fd5b8a35995061042260208c0161015a565b985061043060408c01610183565b975060608b013567ffffffffffffffff8082111561044d57600080fd5b6104598e838f0161023d565b985060808d013591508082111561046f57600080fd5b61047b8e838f016102af565b975061048960a08e0161030a565b965060c08d013591508082111561049f57600080fd5b6104ab8e838f0161031b565b90965094508491506104bf60e08e01610183565b93506101008d01359150808211156104d657600080fd5b506104e38d828e01610364565b9150509295989b9194979a5092959850565b600081518084526020808501945080840160005b8381101561052557815187529582019590820190600101610509565b509495945050505050565b6000815180845260005b818110156105565760208185018101518683018201520161053a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60006101208083018c8452602073ffffffffffffffffffffffffffffffffffffffff808e168287015267ffffffffffffffff8d1660408701528360608701528293508b5180845261014087019450828d01935060005b818110156106085784518316865294830194938301936001016105ea565b5050505050828103608084015261061f81896104f5565b60ff881660a0850152905082810360c084015261063c8187610530565b67ffffffffffffffff861660e085015290508281036101008401526106618185610530565b9c9b50505050505050505050505056fea164736f6c6343000813000a", +} + +var ExposedChannelVerifierABI = ExposedChannelVerifierMetaData.ABI + +var ExposedChannelVerifierBin = ExposedChannelVerifierMetaData.Bin + +func DeployExposedChannelVerifier(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ExposedChannelVerifier, error) { + parsed, err := ExposedChannelVerifierMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ExposedChannelVerifierBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ExposedChannelVerifier{address: address, abi: *parsed, ExposedChannelVerifierCaller: ExposedChannelVerifierCaller{contract: contract}, ExposedChannelVerifierTransactor: ExposedChannelVerifierTransactor{contract: contract}, ExposedChannelVerifierFilterer: ExposedChannelVerifierFilterer{contract: contract}}, nil +} + +type ExposedChannelVerifier struct { + address common.Address + abi abi.ABI + ExposedChannelVerifierCaller + ExposedChannelVerifierTransactor + ExposedChannelVerifierFilterer +} + +type ExposedChannelVerifierCaller struct { + contract *bind.BoundContract +} + +type ExposedChannelVerifierTransactor struct { + contract *bind.BoundContract +} + +type ExposedChannelVerifierFilterer struct { + contract *bind.BoundContract +} + +type ExposedChannelVerifierSession struct { + Contract *ExposedChannelVerifier + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ExposedChannelVerifierCallerSession struct { + Contract *ExposedChannelVerifierCaller + CallOpts bind.CallOpts +} + +type ExposedChannelVerifierTransactorSession struct { + Contract *ExposedChannelVerifierTransactor + TransactOpts bind.TransactOpts +} + +type ExposedChannelVerifierRaw struct { + Contract *ExposedChannelVerifier +} + +type ExposedChannelVerifierCallerRaw struct { + Contract *ExposedChannelVerifierCaller +} + +type ExposedChannelVerifierTransactorRaw struct { + Contract *ExposedChannelVerifierTransactor +} + +func NewExposedChannelVerifier(address common.Address, backend bind.ContractBackend) (*ExposedChannelVerifier, error) { + abi, err := abi.JSON(strings.NewReader(ExposedChannelVerifierABI)) + if err != nil { + return nil, err + } + contract, err := bindExposedChannelVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ExposedChannelVerifier{address: address, abi: abi, ExposedChannelVerifierCaller: ExposedChannelVerifierCaller{contract: contract}, ExposedChannelVerifierTransactor: ExposedChannelVerifierTransactor{contract: contract}, ExposedChannelVerifierFilterer: ExposedChannelVerifierFilterer{contract: contract}}, nil +} + +func NewExposedChannelVerifierCaller(address common.Address, caller bind.ContractCaller) (*ExposedChannelVerifierCaller, error) { + contract, err := bindExposedChannelVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ExposedChannelVerifierCaller{contract: contract}, nil +} + +func NewExposedChannelVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*ExposedChannelVerifierTransactor, error) { + contract, err := bindExposedChannelVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ExposedChannelVerifierTransactor{contract: contract}, nil +} + +func NewExposedChannelVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*ExposedChannelVerifierFilterer, error) { + contract, err := bindExposedChannelVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ExposedChannelVerifierFilterer{contract: contract}, nil +} + +func bindExposedChannelVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ExposedChannelVerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExposedChannelVerifier.Contract.ExposedChannelVerifierCaller.contract.Call(opts, result, method, params...) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExposedChannelVerifier.Contract.ExposedChannelVerifierTransactor.contract.Transfer(opts) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExposedChannelVerifier.Contract.ExposedChannelVerifierTransactor.contract.Transact(opts, method, params...) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExposedChannelVerifier.Contract.contract.Call(opts, result, method, params...) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExposedChannelVerifier.Contract.contract.Transfer(opts) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExposedChannelVerifier.Contract.contract.Transact(opts, method, params...) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierCaller) ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + var out []interface{} + err := _ExposedChannelVerifier.contract.Call(opts, &out, "exposedConfigDigestFromConfigData", _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierSession) ExposedConfigDigestFromConfigData(_chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + return _ExposedChannelVerifier.Contract.ExposedConfigDigestFromConfigData(&_ExposedChannelVerifier.CallOpts, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifierCallerSession) ExposedConfigDigestFromConfigData(_chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + return _ExposedChannelVerifier.Contract.ExposedConfigDigestFromConfigData(&_ExposedChannelVerifier.CallOpts, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) +} + +func (_ExposedChannelVerifier *ExposedChannelVerifier) Address() common.Address { + return _ExposedChannelVerifier.address +} + +type ExposedChannelVerifierInterface interface { + ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt index b5bae4fd4bb..31333e92ebf 100644 --- a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,10 +1,15 @@ GETH_VERSION: 1.13.8 +channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin 4ae3e6ca866fdf48850d67c0c7a4bdaf4905c81a4e3ce5efb9ef9613a55d8454 +channel_config_verifier_proxy: ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.abi ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.bin 655658e5f61dfadfe3268de04f948b7e690ad03ca45676e645d6cd6018154661 +channel_verifier: ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin e6020553bd8e3e6b250fcaffe7efd22aea955c8c1a0eb05d282fdeb0ab6550b7 errored_verifier: ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.bin a3e5a77262e13ee30fe8d35551b32a3452d71929e43fd780bbfefeaf4aa62e43 +exposed_channel_verifier: ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.abi ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.bin c21cde078900241c06de69e2bc5d906c5ef558b52db66caa68bed065940a2253 exposed_verifier: ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.bin 00816ab345f768e522c79abadeadf9155c2c688067e18f8f73e5d6ab71037663 fee_manager: ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.bin edc85f34294ae7c90d45c4c71eb5c105c60a4842dfbbf700c692870ffcc403a1 -llo_feeds: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin cb71e018f67e49d7bc0e194c822204dfd59f79ff42e4fc8fd8ab63f3acd71361 -llo_feeds_test: ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 +llo_feeds: ../../../contracts/solc/v0.8.19/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager.bin cb71e018f67e49d7bc0e194c822204dfd59f79ff42e4fc8fd8ab63f3acd71361 +llo_feeds_test: ../../../contracts/solc/v0.8.19/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 reward_manager: ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.bin 7996cbc89a7f9af85b1ca4079ecf782d7138626b3f4bdb3bfa996248c9ccb9f4 +stream_config_store: ../../../contracts/solc/v0.8.19/StreamConfigStore/StreamConfigStore.abi ../../../contracts/solc/v0.8.19/StreamConfigStore/StreamConfigStore.bin 45ae1b0a45a90b3dee076023052aef73c212c8ef8825b829397f751f6b0a1598 verifier: ../../../contracts/solc/v0.8.19/Verifier/Verifier.abi ../../../contracts/solc/v0.8.19/Verifier/Verifier.bin 413406be1578e9fb73e664ceb1967e6aedf5cf7c4701a2b81fe7c42b03f13573 verifier_proxy: ../../../contracts/solc/v0.8.19/VerifierProxy/VerifierProxy.abi ../../../contracts/solc/v0.8.19/VerifierProxy/VerifierProxy.bin aca18e93b0129114f20c4c0fbaeb61c86bc0ca0724bc438ec7ae11c158038ea7 werc20_mock: ../../../contracts/solc/v0.8.19/WERC20Mock.abi ../../../contracts/solc/v0.8.19/WERC20Mock.bin ff2ca3928b2aa9c412c892cb8226c4d754c73eeb291bb7481c32c48791b2aa94 diff --git a/core/gethwrappers/llo-feeds/go_generate.go b/core/gethwrappers/llo-feeds/go_generate.go index d43f21e0230..5e5b841b72d 100644 --- a/core/gethwrappers/llo-feeds/go_generate.go +++ b/core/gethwrappers/llo-feeds/go_generate.go @@ -9,3 +9,6 @@ package gethwrappers //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.bin ExposedVerifier exposed_verifier //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.bin RewardManager reward_manager //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.bin FeeManager fee_manager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin ChannelConfigStore channel_config_store +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin ChannelVerifier channel_verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.abi ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.bin ExposedChannelVerifier exposed_channel_verifier From 2784f9b194217bd78571cfc7dad407a0e7e51e2b Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 12 Feb 2024 10:18:53 -0500 Subject: [PATCH 05/98] Generate protobufs for mercury (#11989) --- .../relay/evm/mercury/wsrpc/pb/mercury.pb.go | 147 ++++++++++-------- 1 file changed, 79 insertions(+), 68 deletions(-) diff --git a/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go b/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go index 4ffe41860e6..2f421931a18 100644 --- a/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go +++ b/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.32.0 +// protoc v4.23.2 // source: mercury.proto package pb @@ -25,7 +25,8 @@ type TransmitRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + ReportFormat string `protobuf:"bytes,2,opt,name=reportFormat,proto3" json:"reportFormat,omitempty"` } func (x *TransmitRequest) Reset() { @@ -67,6 +68,13 @@ func (x *TransmitRequest) GetPayload() []byte { return nil } +func (x *TransmitRequest) GetReportFormat() string { + if x != nil { + return x.ReportFormat + } + return "" +} + type TransmitResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -442,73 +450,76 @@ var File_mercury_proto protoreflect.FileDescriptor var file_mercury_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x02, 0x70, 0x62, 0x22, 0x2b, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, + 0x02, 0x70, 0x62, 0x22, 0x4f, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x22, 0x3c, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2d, - 0x0a, 0x13, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x22, 0x50, 0x0a, - 0x14, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x22, 0x0a, 0x06, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, - 0xa1, 0x04, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x65, - 0x65, 0x64, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x65, 0x65, 0x64, - 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, - 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x12, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, - 0x73, 0x68, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x15, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x15, 0x6f, 0x62, 0x73, 0x65, - 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x22, - 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, - 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x22, - 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x22, 0x3b, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, - 0x6e, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, - 0x32, 0x83, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x12, 0x35, 0x0a, 0x08, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, - 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, - 0x62, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, - 0x76, 0x32, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6c, 0x61, - 0x79, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x2f, 0x77, 0x73, - 0x72, 0x70, 0x63, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3c, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x22, 0x2d, 0x0a, 0x13, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x65, 0x65, + 0x64, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x65, 0x65, 0x64, 0x49, + 0x64, 0x22, 0x50, 0x0a, 0x14, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x22, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0a, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x06, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x22, 0xa1, 0x04, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x46, + 0x72, 0x6f, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x15, + 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, + 0x69, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x09, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x70, 0x62, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x3b, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, + 0x61, 0x6e, 0x6f, 0x73, 0x32, 0x83, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, + 0x12, 0x35, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x12, 0x13, 0x2e, 0x70, + 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x4c, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x61, 0x74, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, + 0x79, 0x2f, 0x77, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( From c84f1b5b3a135bc22f5da81f6c65d83d5f152af9 Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Mon, 12 Feb 2024 18:55:21 +0200 Subject: [PATCH 06/98] Node API OCR3 delegate support (#11993) * OCR3 delegate support * -Move adapters -Convert if statement to switch * - Add adapters tests - Pin to new version of chainlink-common * - Pin to new version of chainlink-common * Fix go sum * Pin to latest version of chainlink-common --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/ocr2/delegate.go | 121 +++++++++++------- core/services/ocr2/validate/validate.go | 2 +- core/services/ocrcommon/adapters.go | 73 +++++++++++ core/services/ocrcommon/adapters_test.go | 153 +++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- 10 files changed, 312 insertions(+), 55 deletions(-) create mode 100644 core/services/ocrcommon/adapters.go create mode 100644 core/services/ocrcommon/adapters_test.go diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 1cecd5699cf..f03f0276ae6 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,7 +19,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f9ae572c858..d9c4c4aad16 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1169,8 +1169,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca h1:Vtu+x4788S9stmuioWtfyxCKro7dwnqJFy96IuMRB7k= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 h1:XZ5A3s+DyRSnPisks6scNRGrW6Egb0wsFreVb/UEdP8= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 h1:DuSQLuq+Ilm3Q+2zn5agLrAi9UvFQmOUdKwZQKX0AFA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62/go.mod h1:Ny6kBD8Houh5yZRmGiB0ovsLHdb4qOHHwBno9JZUT+Y= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index b20f95d129f..870dfb6463c 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -25,6 +25,7 @@ import ( ocr2keepers20runner "github.com/smartcontractkit/chainlink-automation/pkg/v2/runner" ocr2keepers21config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" ocr2keepers21 "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin" + "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink-vrf/altbn_128" @@ -519,33 +520,33 @@ func (d *Delegate) newServicesGenericPlugin( // NOTE: we don't need to validate this config, since that happens as part of creating the job. // See: validate/validate.go's `validateSpec`. - p := validate.OCR2GenericPluginConfig{} - err = json.Unmarshal(spec.PluginConfig.Bytes(), &p) + pCfg := validate.OCR2GenericPluginConfig{} + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pCfg) if err != nil { return nil, err } - plugEnv := env.NewPlugin(p.PluginName) + plugEnv := env.NewPlugin(pCfg.PluginName) - command := p.Command + command := pCfg.Command if command == "" { command = plugEnv.Cmd.Get() } // Add the default pipeline to the pluginConfig - p.Pipelines = append( - p.Pipelines, + pCfg.Pipelines = append( + pCfg.Pipelines, validate.PipelineSpec{Name: "__DEFAULT_PIPELINE__", Spec: jb.Pipeline.Source}, ) rid, err := spec.RelayID() if err != nil { - return nil, ErrJobSpecNoRelayer{PluginName: p.PluginName, Err: err} + return nil, ErrJobSpecNoRelayer{PluginName: pCfg.PluginName, Err: err} } relayer, err := d.RelayGetter.Get(rid) if err != nil { - return nil, ErrRelayNotEnabled{Err: err, Relay: spec.Relay, PluginName: p.PluginName} + return nil, ErrRelayNotEnabled{Err: err, Relay: spec.Relay, PluginName: pCfg.PluginName} } provider, err := relayer.NewPluginProvider(ctx, types.RelayArgs{ @@ -554,7 +555,7 @@ func (d *Delegate) newServicesGenericPlugin( ContractID: spec.ContractID, New: d.isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), - ProviderType: p.ProviderType, + ProviderType: pCfg.ProviderType, }, types.PluginArgs{ TransmitterID: spec.TransmitterID.String, PluginConfig: spec.PluginConfig.Bytes(), @@ -564,39 +565,19 @@ func (d *Delegate) newServicesGenericPlugin( } srvs = append(srvs, provider) - oracleEndpoint := d.monitoringEndpointGen.GenMonitoringEndpoint( - rid.Network, - rid.ChainID, - spec.ContractID, - synchronization.TelemetryType(p.TelemetryType), - ) - oracleArgs := libocr2.OCR2OracleArgs{ - BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, - V2Bootstrappers: bootstrapPeers, - Database: ocrDB, - LocalConfig: lc, - Logger: ocrLogger, - MonitoringEndpoint: oracleEndpoint, - OffchainKeyring: kb, - OnchainKeyring: kb, - ContractTransmitter: provider.ContractTransmitter(), - ContractConfigTracker: provider.ContractConfigTracker(), - OffchainConfigDigester: provider.OffchainConfigDigester(), - } - envVars, err := plugins.ParseEnvFile(plugEnv.Env.Get()) if err != nil { return nil, fmt.Errorf("failed to parse median env file: %w", err) } - if len(p.EnvVars) > 0 { - for k, v := range p.EnvVars { + if len(pCfg.EnvVars) > 0 { + for k, v := range pCfg.EnvVars { envVars = append(envVars, k+"="+v) } } - pluginLggr := lggr.Named(p.PluginName).Named(spec.ContractID).Named(spec.GetID()) + pluginLggr := lggr.Named(pCfg.PluginName).Named(spec.ContractID).Named(spec.GetID()) cmdFn, grpcOpts, err := d.cfg.RegisterLOOP(plugins.CmdConfig{ - ID: fmt.Sprintf("%s-%s-%s", p.PluginName, spec.ContractID, spec.GetID()), + ID: fmt.Sprintf("%s-%s-%s", pCfg.PluginName, spec.ContractID, spec.GetID()), Cmd: command, Env: envVars, }) @@ -616,7 +597,7 @@ func (d *Delegate) newServicesGenericPlugin( //TODO: remove this workaround when the EVM relayer is running inside of an LOOPP d.lggr.Info("provider is not a LOOPP provider, switching to provider server") - ps, err2 := relay.NewProviderServer(provider, types.OCR2PluginType(p.ProviderType), d.lggr) + ps, err2 := relay.NewProviderServer(provider, types.OCR2PluginType(pCfg.ProviderType), d.lggr) if err2 != nil { return nil, fmt.Errorf("cannot start EVM provider server: %s", err) } @@ -627,32 +608,82 @@ func (d *Delegate) newServicesGenericPlugin( srvs = append(srvs, ps) } - pc, err := json.Marshal(p.Config) + pc, err := json.Marshal(pCfg.Config) if err != nil { return nil, fmt.Errorf("cannot dump plugin config to string before sending to plugin: %s", err) } pluginConfig := types.ReportingPluginServiceConfig{ - PluginName: p.PluginName, + PluginName: pCfg.PluginName, Command: command, - ProviderType: p.ProviderType, - TelemetryType: p.TelemetryType, + ProviderType: pCfg.ProviderType, + TelemetryType: pCfg.TelemetryType, PluginConfig: string(pc), } pr := generic.NewPipelineRunnerAdapter(pluginLggr, jb, d.pipelineRunner) ta := generic.NewTelemetryAdapter(d.monitoringEndpointGen) - plugin := reportingplugins.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog) - oracleArgs.ReportingPluginFactory = plugin - srvs = append(srvs, plugin) + oracleEndpoint := d.monitoringEndpointGen.GenMonitoringEndpoint( + rid.Network, + rid.ChainID, + spec.ContractID, + synchronization.TelemetryType(pCfg.TelemetryType), + ) - oracle, err := libocr2.NewOracle(oracleArgs) - if err != nil { - return nil, err + switch pCfg.OCRVersion { + case 2: + plugin := reportingplugins.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog) + oracleArgs := libocr2.OCR2OracleArgs{ + BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, + V2Bootstrappers: bootstrapPeers, + Database: ocrDB, + LocalConfig: lc, + Logger: ocrLogger, + MonitoringEndpoint: oracleEndpoint, + OffchainKeyring: kb, + OnchainKeyring: kb, + ContractTransmitter: provider.ContractTransmitter(), + ContractConfigTracker: provider.ContractConfigTracker(), + OffchainConfigDigester: provider.OffchainConfigDigester(), + } + oracleArgs.ReportingPluginFactory = plugin + srvs = append(srvs, plugin) + oracle, err := libocr2.NewOracle(oracleArgs) + if err != nil { + return nil, err + } + srvs = append(srvs, job.NewServiceAdapter(oracle)) + + case 3: + //OCR3 with OCR2 OnchainKeyring and ContractTransmitter + plugin := ocr3.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog) + contractTransmitter := ocrcommon.NewOCR3ContractTransmitterAdapter(provider.ContractTransmitter()) + oracleArgs := libocr2.OCR3OracleArgs[any]{ + BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, + V2Bootstrappers: bootstrapPeers, + ContractConfigTracker: provider.ContractConfigTracker(), + ContractTransmitter: contractTransmitter, + Database: ocrDB, + LocalConfig: lc, + Logger: ocrLogger, + MonitoringEndpoint: oracleEndpoint, + OffchainConfigDigester: provider.OffchainConfigDigester(), + OffchainKeyring: kb, + OnchainKeyring: ocrcommon.NewOCR3OnchainKeyringAdapter(kb), + } + oracleArgs.ReportingPluginFactory = plugin + srvs = append(srvs, plugin) + oracle, err := libocr2.NewOracle(oracleArgs) + if err != nil { + return nil, err + } + srvs = append(srvs, job.NewServiceAdapter(oracle)) + + default: + return nil, fmt.Errorf("unknown OCR version: %d", pCfg.OCRVersion) } - srvs = append(srvs, job.NewServiceAdapter(oracle)) return srvs, nil } diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index ad54ba4fea2..9fe779b244f 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -9,7 +9,6 @@ import ( "github.com/lib/pq" "github.com/pelletier/go-toml" pkgerrors "github.com/pkg/errors" - libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -141,6 +140,7 @@ type innerConfig struct { ProviderType string `json:"providerType"` PluginName string `json:"pluginName"` TelemetryType string `json:"telemetryType"` + OCRVersion int `json:"OCRVersion"` Config } diff --git a/core/services/ocrcommon/adapters.go b/core/services/ocrcommon/adapters.go new file mode 100644 index 00000000000..ca7e84ccfa6 --- /dev/null +++ b/core/services/ocrcommon/adapters.go @@ -0,0 +1,73 @@ +package ocrcommon + +import ( + "context" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +var _ ocr3types.OnchainKeyring[any] = (*OCR3OnchainKeyringAdapter)(nil) + +type OCR3OnchainKeyringAdapter struct { + o ocrtypes.OnchainKeyring +} + +func NewOCR3OnchainKeyringAdapter(o ocrtypes.OnchainKeyring) *OCR3OnchainKeyringAdapter { + return &OCR3OnchainKeyringAdapter{o} +} + +func (k *OCR3OnchainKeyringAdapter) PublicKey() ocrtypes.OnchainPublicKey { + return k.o.PublicKey() +} + +func (k *OCR3OnchainKeyringAdapter) Sign(digest ocrtypes.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[any]) (signature []byte, err error) { + return k.o.Sign(ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: digest, + Epoch: uint32(seqNr), + Round: 0, + }, + ExtraHash: [32]byte(make([]byte, 32)), + }, r.Report) +} + +func (k *OCR3OnchainKeyringAdapter) Verify(opk ocrtypes.OnchainPublicKey, digest ocrtypes.ConfigDigest, seqNr uint64, ri ocr3types.ReportWithInfo[any], signature []byte) bool { + return k.o.Verify(opk, ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: digest, + Epoch: uint32(seqNr), + Round: 0, + }, + ExtraHash: [32]byte(make([]byte, 32)), + }, ri.Report, signature) +} + +func (k *OCR3OnchainKeyringAdapter) MaxSignatureLength() int { + return k.o.MaxSignatureLength() +} + +var _ ocr3types.ContractTransmitter[any] = (*OCR3ContractTransmitterAdapter)(nil) + +type OCR3ContractTransmitterAdapter struct { + ct ocrtypes.ContractTransmitter +} + +func NewOCR3ContractTransmitterAdapter(ct ocrtypes.ContractTransmitter) *OCR3ContractTransmitterAdapter { + return &OCR3ContractTransmitterAdapter{ct} +} + +func (c *OCR3ContractTransmitterAdapter) Transmit(ctx context.Context, digest ocrtypes.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[any], signatures []ocrtypes.AttributedOnchainSignature) error { + return c.ct.Transmit(ctx, ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: digest, + Epoch: uint32(seqNr), + Round: 0, + }, + ExtraHash: [32]byte(make([]byte, 32)), + }, r.Report, signatures) +} + +func (c *OCR3ContractTransmitterAdapter) FromAccount() (ocrtypes.Account, error) { + return c.ct.FromAccount() +} diff --git a/core/services/ocrcommon/adapters_test.go b/core/services/ocrcommon/adapters_test.go new file mode 100644 index 00000000000..a29cec27de7 --- /dev/null +++ b/core/services/ocrcommon/adapters_test.go @@ -0,0 +1,153 @@ +package ocrcommon_test + +import ( + "context" + "fmt" + "reflect" + "testing" + + "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" +) + +var _ ocrtypes.OnchainKeyring = (*fakeOnchainKeyring)(nil) + +var ( + account ocrtypes.Account = "Test-Account" + configDigest = ocrtypes.ConfigDigest([]byte("kKfYauxXBMjuP5EuuyacN6BwCfKJnP6d")) + seqNr uint64 = 11 + rwi = ocr3types.ReportWithInfo[any]{ + Report: []byte("report"), + } + signatures = []types.AttributedOnchainSignature{{ + Signature: []byte("signature1"), + Signer: 1, + }, { + Signature: []byte("signature2"), + Signer: 2, + }} + pubKey = ocrtypes.OnchainPublicKey("pub-key") + maxSignatureLength = 12 + sigs = []byte("some-signatures") +) + +type fakeOnchainKeyring struct { +} + +func (f fakeOnchainKeyring) PublicKey() ocrtypes.OnchainPublicKey { + return pubKey +} + +func (f fakeOnchainKeyring) Sign(rc ocrtypes.ReportContext, r ocrtypes.Report) (signature []byte, err error) { + if !reflect.DeepEqual(rc.ConfigDigest, configDigest) { + return nil, fmt.Errorf("expected configDigest %v but got %v", configDigest, rc.ReportTimestamp.ConfigDigest) + } + + if rc.Epoch != uint32(seqNr) { + return nil, fmt.Errorf("expected Epoch %v but got %v", seqNr, rc.Epoch) + } + + if rc.Round != 0 { + return nil, fmt.Errorf("expected Round %v but got %v", 0, rc.Round) + } + + if !reflect.DeepEqual(r, rwi.Report) { + return nil, fmt.Errorf("expected Report %v but got %v", rwi.Report, r) + } + return nil, nil +} + +func (f fakeOnchainKeyring) Verify(pk ocrtypes.OnchainPublicKey, rc ocrtypes.ReportContext, r ocrtypes.Report, signature []byte) bool { + if !reflect.DeepEqual(pk, pubKey) { + return false + } + + if !reflect.DeepEqual(rc.ConfigDigest, configDigest) { + return false + } + + if rc.Epoch != uint32(seqNr) { + return false + } + + if rc.Round != 0 { + return false + } + + if !reflect.DeepEqual(r, rwi.Report) { + return false + } + + if !reflect.DeepEqual(signature, sigs) { + return false + } + + return true +} + +func (f fakeOnchainKeyring) MaxSignatureLength() int { + return maxSignatureLength +} + +func TestOCR3OnchainKeyringAdapter(t *testing.T) { + kr := ocrcommon.NewOCR3OnchainKeyringAdapter(fakeOnchainKeyring{}) + + _, err := kr.Sign(configDigest, seqNr, rwi) + require.NoError(t, err) + require.True(t, kr.Verify(pubKey, configDigest, seqNr, rwi, sigs)) + + require.Equal(t, pubKey, kr.PublicKey()) + require.Equal(t, maxSignatureLength, kr.MaxSignatureLength()) +} + +var _ ocrtypes.ContractTransmitter = (*fakeContractTransmitter)(nil) + +type fakeContractTransmitter struct { +} + +func (f fakeContractTransmitter) Transmit(ctx context.Context, rc ocrtypes.ReportContext, report ocrtypes.Report, s []ocrtypes.AttributedOnchainSignature) error { + + if !reflect.DeepEqual(report, rwi.Report) { + return fmt.Errorf("expected Report %v but got %v", rwi.Report, report) + } + + if !reflect.DeepEqual(s, signatures) { + return fmt.Errorf("expected signatures %v but got %v", signatures, s) + } + + if !reflect.DeepEqual(rc.ConfigDigest, configDigest) { + return fmt.Errorf("expected configDigest %v but got %v", configDigest, rc.ReportTimestamp.ConfigDigest) + } + + if rc.Epoch != uint32(seqNr) { + return fmt.Errorf("expected Epoch %v but got %v", seqNr, rc.Epoch) + } + + if rc.Round != 0 { + return fmt.Errorf("expected Round %v but got %v", 0, rc.Round) + } + + return nil +} + +func (f fakeContractTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) (configDigest ocrtypes.ConfigDigest, epoch uint32, err error) { + panic("not implemented") +} + +func (f fakeContractTransmitter) FromAccount() (ocrtypes.Account, error) { + return account, nil +} + +func TestContractTransmitter(t *testing.T) { + ct := ocrcommon.NewOCR3ContractTransmitterAdapter(fakeContractTransmitter{}) + + require.NoError(t, ct.Transmit(context.Background(), configDigest, seqNr, rwi, signatures)) + + a, err := ct.FromAccount() + require.NoError(t, err) + require.Equal(t, a, account) +} diff --git a/go.mod b/go.mod index 5a85983fb48..04078ed4c3d 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 0610b422deb..1cce0e09a1a 100644 --- a/go.sum +++ b/go.sum @@ -1164,8 +1164,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca h1:Vtu+x4788S9stmuioWtfyxCKro7dwnqJFy96IuMRB7k= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 h1:XZ5A3s+DyRSnPisks6scNRGrW6Egb0wsFreVb/UEdP8= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 h1:DuSQLuq+Ilm3Q+2zn5agLrAi9UvFQmOUdKwZQKX0AFA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62/go.mod h1:Ny6kBD8Houh5yZRmGiB0ovsLHdb4qOHHwBno9JZUT+Y= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 726e70c260f..683ceba36a7 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 16aa3f2014d..3642c98ed7b 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1501,8 +1501,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca h1:Vtu+x4788S9stmuioWtfyxCKro7dwnqJFy96IuMRB7k= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240209032254-f9b58810d8ca/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 h1:XZ5A3s+DyRSnPisks6scNRGrW6Egb0wsFreVb/UEdP8= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 h1:DuSQLuq+Ilm3Q+2zn5agLrAi9UvFQmOUdKwZQKX0AFA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62/go.mod h1:Ny6kBD8Houh5yZRmGiB0ovsLHdb4qOHHwBno9JZUT+Y= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= From 1fb4203dc445b6bc03816cb414cae434f3909541 Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:00:53 -0500 Subject: [PATCH 07/98] BCF-2901 Fix potential JAID collisions in multi chain env (#11821) * Fix potential JAID collisions in multi chain env This fixes some rest api responses getting omitted when the JAID was same across multiple chains * Add JAID constructor that formats JAID with chainID prefix * minor test fix * Flip FormatWithPrefixedChainID params to make more sense --- core/cmd/cosmos_node_commands_test.go | 2 +- core/cmd/evm_node_commands_test.go | 4 +- core/cmd/ocr2_keys_commands_test.go | 2 +- core/cmd/solana_node_commands_test.go | 4 +- core/cmd/starknet_node_commands_test.go | 4 +- core/internal/cltest/cltest.go | 4 + core/web/eth_keys_controller.go | 2 +- core/web/eth_keys_controller_test.go | 15 ++- core/web/presenters/chain_msg_test.go | 69 ++++++++++++++ core/web/presenters/cosmos_chain.go | 2 +- core/web/presenters/cosmos_msg.go | 2 +- core/web/presenters/eth_key.go | 2 +- core/web/presenters/eth_key_test.go | 4 +- core/web/presenters/eth_tx.go | 1 + core/web/presenters/eth_tx_test.go | 8 +- core/web/presenters/evm_chain.go | 2 +- core/web/presenters/evm_forwarder_test.go | 64 +++++++++++++ core/web/presenters/jsonapi.go | 6 ++ core/web/presenters/node_test.go | 92 +++++++++++++++++++ core/web/presenters/solana_chain.go | 2 +- core/web/presenters/solana_msg.go | 2 +- core/web/presenters/starknet_chain.go | 2 +- .../actions/vrf/common/actions.go | 4 +- integration-tests/client/chainlink_models.go | 4 +- integration-tests/smoke/vrfv2_test.go | 2 +- integration-tests/smoke/vrfv2plus_test.go | 2 +- 26 files changed, 275 insertions(+), 32 deletions(-) create mode 100644 core/web/presenters/chain_msg_test.go create mode 100644 core/web/presenters/evm_forwarder_test.go create mode 100644 core/web/presenters/node_test.go diff --git a/core/cmd/cosmos_node_commands_test.go b/core/cmd/cosmos_node_commands_test.go index 728be9396f9..3197c48aa94 100644 --- a/core/cmd/cosmos_node_commands_test.go +++ b/core/cmd/cosmos_node_commands_test.go @@ -48,8 +48,8 @@ func TestShell_IndexCosmosNodes(t *testing.T) { nodes := *r.Renders[0].(*cmd.CosmosNodePresenters) require.Len(t, nodes, 1) n := nodes[0] + assert.Equal(t, cltest.FormatWithPrefixedChainID(chainID, *node.Name), n.ID) assert.Equal(t, chainID, n.ChainID) - assert.Equal(t, *node.Name, n.ID) assert.Equal(t, *node.Name, n.Name) wantConfig, err := toml.Marshal(node) require.NoError(t, err) diff --git a/core/cmd/evm_node_commands_test.go b/core/cmd/evm_node_commands_test.go index dae950fce01..96269c9e028 100644 --- a/core/cmd/evm_node_commands_test.go +++ b/core/cmd/evm_node_commands_test.go @@ -60,13 +60,13 @@ func TestShell_IndexEVMNodes(t *testing.T) { n1 := nodes[0] n2 := nodes[1] assert.Equal(t, chainID.String(), n1.ChainID) - assert.Equal(t, *node1.Name, n1.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(chainID.String(), *node1.Name), n1.ID) assert.Equal(t, *node1.Name, n1.Name) wantConfig, err := toml.Marshal(node1) require.NoError(t, err) assert.Equal(t, string(wantConfig), n1.Config) assert.Equal(t, chainID.String(), n2.ChainID) - assert.Equal(t, *node2.Name, n2.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(chainID.String(), *node2.Name), n2.ID) assert.Equal(t, *node2.Name, n2.Name) wantConfig2, err := toml.Marshal(node2) require.NoError(t, err) diff --git a/core/cmd/ocr2_keys_commands_test.go b/core/cmd/ocr2_keys_commands_test.go index 5a861fafa7c..eff44685612 100644 --- a/core/cmd/ocr2_keys_commands_test.go +++ b/core/cmd/ocr2_keys_commands_test.go @@ -32,7 +32,7 @@ func TestOCR2KeyBundlePresenter_RenderTable(t *testing.T) { pubKeyConfig := key.ConfigEncryptionPublicKey() pubKey := key.OffchainPublicKey() p := cmd.OCR2KeyBundlePresenter{ - JAID: cmd.JAID{ID: bundleID}, + JAID: cmd.NewJAID(bundleID), OCR2KeysBundleResource: presenters.OCR2KeysBundleResource{ JAID: presenters.NewJAID(key.ID()), ChainType: "evm", diff --git a/core/cmd/solana_node_commands_test.go b/core/cmd/solana_node_commands_test.go index 316cf16212d..ebe9502d1fa 100644 --- a/core/cmd/solana_node_commands_test.go +++ b/core/cmd/solana_node_commands_test.go @@ -55,13 +55,13 @@ func TestShell_IndexSolanaNodes(t *testing.T) { n1 := nodes[0] n2 := nodes[1] assert.Equal(t, id, n1.ChainID) - assert.Equal(t, *node1.Name, n1.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node1.Name), n1.ID) assert.Equal(t, *node1.Name, n1.Name) wantConfig, err := toml.Marshal(node1) require.NoError(t, err) assert.Equal(t, string(wantConfig), n1.Config) assert.Equal(t, id, n2.ChainID) - assert.Equal(t, *node2.Name, n2.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node2.Name), n2.ID) assert.Equal(t, *node2.Name, n2.Name) wantConfig2, err := toml.Marshal(node2) require.NoError(t, err) diff --git a/core/cmd/starknet_node_commands_test.go b/core/cmd/starknet_node_commands_test.go index 0347cdd18f7..95f712d29bd 100644 --- a/core/cmd/starknet_node_commands_test.go +++ b/core/cmd/starknet_node_commands_test.go @@ -54,13 +54,13 @@ func TestShell_IndexStarkNetNodes(t *testing.T) { n1 := nodes[0] n2 := nodes[1] assert.Equal(t, id, n1.ChainID) - assert.Equal(t, *node1.Name, n1.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node1.Name), n1.ID) assert.Equal(t, *node1.Name, n1.Name) wantConfig, err := toml.Marshal(node1) require.NoError(t, err) assert.Equal(t, string(wantConfig), n1.Config) assert.Equal(t, id, n2.ChainID) - assert.Equal(t, *node2.Name, n2.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node2.Name), n2.ID) assert.Equal(t, *node2.Name, n2.Name) wantConfig2, err := toml.Marshal(node2) require.NoError(t, err) diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index c7abfb31a2a..332513b28d4 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -165,6 +165,10 @@ func MustRandomBytes(t *testing.T, l int) (b []byte) { return b } +func FormatWithPrefixedChainID(chainID, id string) string { + return fmt.Sprintf("%s/%s", chainID, id) +} + type JobPipelineV2TestHelper struct { Prm pipeline.ORM Jrm job.ORM diff --git a/core/web/eth_keys_controller.go b/core/web/eth_keys_controller.go index fe76e8863ef..4e95bc3cb89 100644 --- a/core/web/eth_keys_controller.go +++ b/core/web/eth_keys_controller.go @@ -270,7 +270,7 @@ func (ekc *ETHKeysController) Chain(c *gin.Context) { jsonAPIError(c, http.StatusBadRequest, errors.Errorf("invalid address: %s, must be hex address", keyID)) return } - address := common.HexToAddress((keyID)) + address := common.HexToAddress(keyID) cid := c.Query("evmChainID") chain, ok := ekc.getChain(c, cid) diff --git a/core/web/eth_keys_controller_test.go b/core/web/eth_keys_controller_test.go index a9be5517bcc..e075b3196e1 100644 --- a/core/web/eth_keys_controller_test.go +++ b/core/web/eth_keys_controller_test.go @@ -284,7 +284,8 @@ func TestETHKeysController_ChainSuccess_UpdateNonce(t *testing.T) { err := cltest.ParseJSONAPIResponse(t, resp, &updatedKey) assert.NoError(t, err) - assert.Equal(t, key.ID(), updatedKey.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key.Address.String()), updatedKey.ID) + assert.Equal(t, key.Address.String(), updatedKey.Address) assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String()) assert.Equal(t, false, updatedKey.Disabled) } @@ -328,7 +329,8 @@ func TestETHKeysController_ChainSuccess_Disable(t *testing.T) { err := cltest.ParseJSONAPIResponse(t, resp, &updatedKey) assert.NoError(t, err) - assert.Equal(t, key.ID(), updatedKey.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(updatedKey.EVMChainID.String(), key.Address.String()), updatedKey.ID) + assert.Equal(t, key.Address.String(), updatedKey.Address) assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String()) assert.Equal(t, true, updatedKey.Disabled) } @@ -371,7 +373,8 @@ func TestETHKeysController_ChainSuccess_Enable(t *testing.T) { err := cltest.ParseJSONAPIResponse(t, resp, &updatedKey) assert.NoError(t, err) - assert.Equal(t, key.ID(), updatedKey.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key.Address.String()), updatedKey.ID) + assert.Equal(t, key.Address.String(), updatedKey.Address) assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String()) assert.Equal(t, false, updatedKey.Disabled) } @@ -436,7 +439,8 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) { err = cltest.ParseJSONAPIResponse(t, resp, &updatedKey) assert.NoError(t, err) - assert.Equal(t, key.ID(), updatedKey.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key.Address.String()), updatedKey.ID) + assert.Equal(t, key.Address.String(), updatedKey.Address) assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String()) assert.Equal(t, false, updatedKey.Disabled) @@ -663,7 +667,8 @@ func TestETHKeysController_DeleteSuccess(t *testing.T) { err := cltest.ParseJSONAPIResponse(t, resp, &deletedKey) assert.NoError(t, err) - assert.Equal(t, key0.ID(), deletedKey.ID) + assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key0.Address.String()), deletedKey.ID) + assert.Equal(t, key0.Address.String(), deletedKey.Address) assert.Equal(t, cltest.FixtureChainID.String(), deletedKey.EVMChainID.String()) assert.Equal(t, false, deletedKey.Disabled) diff --git a/core/web/presenters/chain_msg_test.go b/core/web/presenters/chain_msg_test.go new file mode 100644 index 00000000000..58192caef71 --- /dev/null +++ b/core/web/presenters/chain_msg_test.go @@ -0,0 +1,69 @@ +package presenters + +import ( + "fmt" + "testing" + + "github.com/manyminds/api2go/jsonapi" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/cosmostest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/solanatest" +) + +func TestSolanaMessageResource(t *testing.T) { + id := "1" + chainID := solanatest.RandomChainID() + r := NewSolanaMsgResource(id, chainID) + assert.Equal(t, chainID, r.ChainID) + + b, err := jsonapi.Marshal(r) + require.NoError(t, err) + + expected := fmt.Sprintf(` + { + "data":{ + "type":"solana_messages", + "id":"%s/%s", + "attributes":{ + "ChainID":"%s", + "from":"", + "to":"", + "amount":0 + } + } + } + `, chainID, id, chainID) + + assert.JSONEq(t, expected, string(b)) +} + +func TestCosmosMessageResource(t *testing.T) { + id := "1" + chainID := cosmostest.RandomChainID() + contractID := "cosmos1p3ucd3ptpw902fluyjzkq3fflq4btddac9sa3s" + r := NewCosmosMsgResource(id, chainID, contractID) + assert.Equal(t, chainID, r.ChainID) + assert.Equal(t, contractID, r.ContractID) + + b, err := jsonapi.Marshal(r) + require.NoError(t, err) + + expected := fmt.Sprintf(` + { + "data":{ + "type":"cosmos_messages", + "id":"%s/%s", + "attributes":{ + "ChainID":"%s", + "ContractID":"%s", + "State":"", + "TxHash":null + } + } + } + `, chainID, id, chainID, contractID) + + assert.JSONEq(t, expected, string(b)) +} diff --git a/core/web/presenters/cosmos_chain.go b/core/web/presenters/cosmos_chain.go index c3b006e5c7e..c2bc4b52b61 100644 --- a/core/web/presenters/cosmos_chain.go +++ b/core/web/presenters/cosmos_chain.go @@ -36,7 +36,7 @@ func (r CosmosNodeResource) GetName() string { // NewCosmosNodeResource returns a new CosmosNodeResource for node. func NewCosmosNodeResource(node types.NodeStatus) CosmosNodeResource { return CosmosNodeResource{NodeResource{ - JAID: NewJAID(node.Name), + JAID: NewPrefixedJAID(node.Name, node.ChainID), ChainID: node.ChainID, Name: node.Name, State: node.State, diff --git a/core/web/presenters/cosmos_msg.go b/core/web/presenters/cosmos_msg.go index 5bf0bb9b4f8..ab43d394ede 100644 --- a/core/web/presenters/cosmos_msg.go +++ b/core/web/presenters/cosmos_msg.go @@ -17,7 +17,7 @@ func (CosmosMsgResource) GetName() string { // NewCosmosMsgResource returns a new partial CosmosMsgResource. func NewCosmosMsgResource(id string, chainID string, contractID string) CosmosMsgResource { return CosmosMsgResource{ - JAID: NewJAID(id), + JAID: NewPrefixedJAID(id, chainID), ChainID: chainID, ContractID: contractID, } diff --git a/core/web/presenters/eth_key.go b/core/web/presenters/eth_key.go index d661d4334cd..812adeb13fa 100644 --- a/core/web/presenters/eth_key.go +++ b/core/web/presenters/eth_key.go @@ -40,7 +40,7 @@ type NewETHKeyOption func(*ETHKeyResource) // Use the functional options to inject the ETH and LINK balances func NewETHKeyResource(k ethkey.KeyV2, state ethkey.State, opts ...NewETHKeyOption) *ETHKeyResource { r := ÐKeyResource{ - JAID: NewJAID(k.Address.Hex()), + JAID: NewPrefixedJAID(k.Address.Hex(), state.EVMChainID.String()), EVMChainID: state.EVMChainID, Address: k.Address.Hex(), EthBalance: nil, diff --git a/core/web/presenters/eth_key_test.go b/core/web/presenters/eth_key_test.go index 8be13de74a1..46402141a4c 100644 --- a/core/web/presenters/eth_key_test.go +++ b/core/web/presenters/eth_key_test.go @@ -55,7 +55,7 @@ func TestETHKeyResource(t *testing.T) { { "data":{ "type":"eTHKeys", - "id":"%s", + "id":"42/%s", "attributes":{ "address":"%s", "evmChainID":"42", @@ -84,7 +84,7 @@ func TestETHKeyResource(t *testing.T) { { "data": { "type":"eTHKeys", - "id":"%s", + "id":"42/%s", "attributes":{ "address":"%s", "evmChainID":"42", diff --git a/core/web/presenters/eth_tx.go b/core/web/presenters/eth_tx.go index f944a99213f..65df01ef095 100644 --- a/core/web/presenters/eth_tx.go +++ b/core/web/presenters/eth_tx.go @@ -66,6 +66,7 @@ func NewEthTxResourceFromAttempt(txa txmgr.TxAttempt) EthTxResource { if txa.Tx.ChainID != nil { r.EVMChainID = *big.New(txa.Tx.ChainID) + r.JAID = NewPrefixedJAID(r.JAID.ID, txa.Tx.ChainID.String()) } if tx.Sequence != nil { diff --git a/core/web/presenters/eth_tx_test.go b/core/web/presenters/eth_tx_test.go index 2ed8e23c76a..193fa774ce9 100644 --- a/core/web/presenters/eth_tx_test.go +++ b/core/web/presenters/eth_tx_test.go @@ -20,12 +20,14 @@ import ( func TestEthTxResource(t *testing.T) { t.Parallel() + chainID := big.NewInt(54321) tx := txmgr.Tx{ ID: 1, EncodedPayload: []byte(`{"data": "is wilding out"}`), FromAddress: common.HexToAddress("0x1"), ToAddress: common.HexToAddress("0x2"), FeeLimit: uint32(5000), + ChainID: chainID, State: txmgrcommon.TxConfirmed, Value: big.Int(assets.NewEthValue(1)), } @@ -52,7 +54,7 @@ func TestEthTxResource(t *testing.T) { "sentAt": "", "to": "0x0000000000000000000000000000000000000002", "value": "0.000000000000000001", - "evmChainID": "0" + "evmChainID": "54321" } } } @@ -85,7 +87,7 @@ func TestEthTxResource(t *testing.T) { { "data": { "type": "evm_transactions", - "id": "0x0000000000000000000000000000000000000000000000000000000000010203", + "id": "54321/0x0000000000000000000000000000000000000000000000000000000000010203", "attributes": { "state": "confirmed", "data": "0x7b2264617461223a202269732077696c64696e67206f7574227d", @@ -98,7 +100,7 @@ func TestEthTxResource(t *testing.T) { "sentAt": "300", "to": "0x0000000000000000000000000000000000000002", "value": "0.000000000000000001", - "evmChainID": "0" + "evmChainID": "54321" } } } diff --git a/core/web/presenters/evm_chain.go b/core/web/presenters/evm_chain.go index 8cc6da46a77..adf399d4b01 100644 --- a/core/web/presenters/evm_chain.go +++ b/core/web/presenters/evm_chain.go @@ -34,7 +34,7 @@ func (r EVMNodeResource) GetName() string { // NewEVMNodeResource returns a new EVMNodeResource for node. func NewEVMNodeResource(node types.NodeStatus) EVMNodeResource { return EVMNodeResource{NodeResource{ - JAID: NewJAID(node.Name), + JAID: NewPrefixedJAID(node.Name, node.ChainID), ChainID: node.ChainID, Name: node.Name, State: node.State, diff --git a/core/web/presenters/evm_forwarder_test.go b/core/web/presenters/evm_forwarder_test.go new file mode 100644 index 00000000000..80eb6b190ef --- /dev/null +++ b/core/web/presenters/evm_forwarder_test.go @@ -0,0 +1,64 @@ +package presenters + +import ( + "fmt" + "strings" + "testing" + "time" + + "github.com/manyminds/api2go/jsonapi" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" +) + +func TestEVMForwarderResource(t *testing.T) { + var ( + ID = int64(1) + address = utils.RandomAddress() + chainID = *big.NewI(4) + createdAt = time.Now() + updatedAt = time.Now().Add(time.Second) + ) + fwd := forwarders.Forwarder{ + ID: ID, + Address: address, + EVMChainID: chainID, + CreatedAt: createdAt, + UpdatedAt: updatedAt, + } + + r := NewEVMForwarderResource(fwd) + assert.Equal(t, fmt.Sprint(ID), r.ID) + assert.Equal(t, address, r.Address) + assert.Equal(t, chainID, r.EVMChainID) + assert.Equal(t, createdAt, r.CreatedAt) + assert.Equal(t, updatedAt, r.UpdatedAt) + + b, err := jsonapi.Marshal(r) + require.NoError(t, err) + + createdAtMarshalled, err := createdAt.MarshalText() + require.NoError(t, err) + updatedAtMarshalled, err := updatedAt.MarshalText() + require.NoError(t, err) + + expected := fmt.Sprintf(` + { + "data":{ + "type":"evm_forwarder", + "id":"%d", + "attributes":{ + "address":"%s", + "evmChainId":"%s", + "createdAt":"%s", + "updatedAt":"%s" + } + } + } + `, ID, strings.ToLower(address.String()), chainID.String(), string(createdAtMarshalled), string(updatedAtMarshalled)) + assert.JSONEq(t, expected, string(b)) +} diff --git a/core/web/presenters/jsonapi.go b/core/web/presenters/jsonapi.go index ee3a2a7de8a..d14e24a7455 100644 --- a/core/web/presenters/jsonapi.go +++ b/core/web/presenters/jsonapi.go @@ -1,6 +1,7 @@ package presenters import ( + "fmt" "strconv" ) @@ -14,6 +15,11 @@ func NewJAID(id string) JAID { return JAID{id} } +// NewPrefixedJAID prefixes JAID with chain id in %s/%s format. +func NewPrefixedJAID(id string, chainID string) JAID { + return JAID{ID: fmt.Sprintf("%s/%s", chainID, id)} +} + // NewJAIDInt32 converts an int32 into a JAID func NewJAIDInt32(id int32) JAID { return JAID{strconv.Itoa(int(id))} diff --git a/core/web/presenters/node_test.go b/core/web/presenters/node_test.go new file mode 100644 index 00000000000..34210a52166 --- /dev/null +++ b/core/web/presenters/node_test.go @@ -0,0 +1,92 @@ +package presenters + +import ( + "fmt" + "testing" + + "github.com/manyminds/api2go/jsonapi" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +func TestNodeResource(t *testing.T) { + var nodeResource NodeResource + var r interface{} + state := "test" + cfg := "cfg" + testCases := []string{"solana", "cosmos", "starknet"} + for _, tc := range testCases { + chainID := fmt.Sprintf("%s chain ID", tc) + nodeName := fmt.Sprintf("%s_node", tc) + + switch tc { + case "evm": + evmNodeResource := NewEVMNodeResource( + types.NodeStatus{ + ChainID: chainID, + Name: nodeName, + Config: cfg, + State: state, + }) + r = evmNodeResource + nodeResource = evmNodeResource.NodeResource + case "solana": + solanaNodeResource := NewSolanaNodeResource( + types.NodeStatus{ + ChainID: chainID, + Name: nodeName, + Config: cfg, + State: state, + }) + r = solanaNodeResource + nodeResource = solanaNodeResource.NodeResource + case "cosmos": + cosmosNodeResource := NewCosmosNodeResource( + types.NodeStatus{ + ChainID: chainID, + Name: nodeName, + Config: cfg, + State: state, + }) + r = cosmosNodeResource + nodeResource = cosmosNodeResource.NodeResource + case "starknet": + starknetNodeResource := NewStarkNetNodeResource( + types.NodeStatus{ + ChainID: chainID, + Name: nodeName, + Config: cfg, + State: state, + }) + r = starknetNodeResource + nodeResource = starknetNodeResource.NodeResource + default: + t.Fail() + } + assert.Equal(t, chainID, nodeResource.ChainID) + assert.Equal(t, nodeName, nodeResource.Name) + assert.Equal(t, cfg, nodeResource.Config) + assert.Equal(t, state, nodeResource.State) + + b, err := jsonapi.Marshal(r) + require.NoError(t, err) + + expected := fmt.Sprintf(` + { + "data":{ + "type":"%s_node", + "id":"%s/%s", + "attributes":{ + "chainID":"%s", + "name":"%s", + "config":"%s", + "state":"%s" + } + } + } + `, tc, chainID, nodeName, chainID, nodeName, cfg, state) + assert.JSONEq(t, expected, string(b)) + } +} diff --git a/core/web/presenters/solana_chain.go b/core/web/presenters/solana_chain.go index f04d2b65d55..798d98124a5 100644 --- a/core/web/presenters/solana_chain.go +++ b/core/web/presenters/solana_chain.go @@ -36,7 +36,7 @@ func (r SolanaNodeResource) GetName() string { // NewSolanaNodeResource returns a new SolanaNodeResource for node. func NewSolanaNodeResource(node types.NodeStatus) SolanaNodeResource { return SolanaNodeResource{NodeResource{ - JAID: NewJAID(node.Name), + JAID: NewPrefixedJAID(node.Name, node.ChainID), ChainID: node.ChainID, Name: node.Name, State: node.State, diff --git a/core/web/presenters/solana_msg.go b/core/web/presenters/solana_msg.go index b7330754e38..3acf2aac0dc 100644 --- a/core/web/presenters/solana_msg.go +++ b/core/web/presenters/solana_msg.go @@ -17,7 +17,7 @@ func (SolanaMsgResource) GetName() string { // NewSolanaMsgResource returns a new partial SolanaMsgResource. func NewSolanaMsgResource(id string, chainID string) SolanaMsgResource { return SolanaMsgResource{ - JAID: NewJAID(id), + JAID: NewPrefixedJAID(id, chainID), ChainID: chainID, } } diff --git a/core/web/presenters/starknet_chain.go b/core/web/presenters/starknet_chain.go index ec1cd453a55..addf798fe9f 100644 --- a/core/web/presenters/starknet_chain.go +++ b/core/web/presenters/starknet_chain.go @@ -36,7 +36,7 @@ func (r StarkNetNodeResource) GetName() string { // NewStarkNetNodeResource returns a new StarkNetNodeResource for node. func NewStarkNetNodeResource(node types.NodeStatus) StarkNetNodeResource { return StarkNetNodeResource{NodeResource{ - JAID: NewJAID(node.Name), + JAID: NewPrefixedJAID(node.Name, node.ChainID), ChainID: node.ChainID, Name: node.Name, State: node.State, diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index ec7972de597..0c779ea90e5 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -54,8 +54,8 @@ func CreateAndFundSendingKeys( if response.StatusCode != 200 { return nil, fmt.Errorf("error creating transaction key - response code, err %d", response.StatusCode) } - newNativeTokenKeyAddresses = append(newNativeTokenKeyAddresses, newTxKey.Data.ID) - err = actions.FundAddress(client, newTxKey.Data.ID, big.NewFloat(chainlinkNodeFunding)) + newNativeTokenKeyAddresses = append(newNativeTokenKeyAddresses, newTxKey.Data.Attributes.Address) + err = actions.FundAddress(client, newTxKey.Data.Attributes.Address, big.NewFloat(chainlinkNodeFunding)) if err != nil { return nil, err } diff --git a/integration-tests/client/chainlink_models.go b/integration-tests/client/chainlink_models.go index 320c7a21cc4..370497423f3 100644 --- a/integration-tests/client/chainlink_models.go +++ b/integration-tests/client/chainlink_models.go @@ -380,8 +380,8 @@ type TxKeyData struct { // TxKeyAttributes is the model that represents the created keys when read type TxKeyAttributes struct { PublicKey string `json:"publicKey"` - - StarkKey string `json:"starkPubKey,omitempty"` + Address string `json:"address"` + StarkKey string `json:"starkPubKey,omitempty"` } type SingleTransactionDataWrapper struct { diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index c289cd019c1..e0c304a3951 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -543,7 +543,7 @@ func TestVRFv2MultipleSendingKeys(t *testing.T) { require.Equal(t, numberOfTxKeysToCreate+1, len(fulfillmentTxFromAddresses)) var txKeyAddresses []string for _, txKey := range txKeys.Data { - txKeyAddresses = append(txKeyAddresses, txKey.ID) + txKeyAddresses = append(txKeyAddresses, txKey.Attributes.Address) } less := func(a, b string) bool { return a < b } equalIgnoreOrder := cmp.Diff(txKeyAddresses, fulfillmentTxFromAddresses, cmpopts.SortSlices(less)) == "" diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 701cae9a027..29cc5534791 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -734,7 +734,7 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { require.Equal(t, numberOfTxKeysToCreate+1, len(fulfillmentTxFromAddresses)) var txKeyAddresses []string for _, txKey := range txKeys.Data { - txKeyAddresses = append(txKeyAddresses, txKey.ID) + txKeyAddresses = append(txKeyAddresses, txKey.Attributes.Address) } less := func(a, b string) bool { return a < b } equalIgnoreOrder := cmp.Diff(txKeyAddresses, fulfillmentTxFromAddresses, cmpopts.SortSlices(less)) == "" From 877f2f532f71887113c587fdcb5e731d880890b7 Mon Sep 17 00:00:00 2001 From: Cedric Date: Mon, 12 Feb 2024 19:36:59 +0000 Subject: [PATCH 08/98] [KS-36] Add workflow job type and hardcoded DF2.0 workflow engine (#11974) * Add workflow job type * [KS-36] Add workflow delegate with hardcoded engine for DF2.0 --- core/services/chainlink/application.go | 7 + core/services/job/models.go | 1 + core/services/job/orm.go | 2 + core/services/pipeline/common.go | 1 + core/services/workflows/delegate.go | 40 +++++ core/services/workflows/engine.go | 216 +++++++++++++++++++++++++ core/services/workflows/engine_test.go | 125 ++++++++++++++ core/web/presenters/job.go | 2 + 8 files changed, 394 insertions(+) create mode 100644 core/services/workflows/delegate.go create mode 100644 core/services/workflows/engine.go create mode 100644 core/services/workflows/engine_test.go diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index a9f9c22df52..e7f867c54fb 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -22,6 +22,7 @@ import ( commonservices "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -57,6 +58,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/core/services/vrf" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" + "github.com/smartcontractkit/chainlink/v2/core/services/workflows" "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/sessions/ldapauth" "github.com/smartcontractkit/chainlink/v2/core/sessions/localauth" @@ -183,6 +185,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { keyStore := opts.KeyStore restrictedHTTPClient := opts.RestrictedHTTPClient unrestrictedHTTPClient := opts.UnrestrictedHTTPClient + registry := capabilities.NewRegistry() // LOOPs can be created as options, in the case of LOOP relayers, or // as OCR2 job implementations, in the case of Median today. @@ -351,6 +354,10 @@ func NewApplication(opts ApplicationOpts) (Application, error) { streamRegistry, pipelineRunner, cfg.JobPipeline()), + job.Workflow: workflows.NewDelegate( + globalLogger, + registry, + ), } webhookJobRunner = delegates[job.Webhook].(*webhook.Delegate).WebhookJobRunner() ) diff --git a/core/services/job/models.go b/core/services/job/models.go index 2aee9182a9c..b769106d647 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -48,6 +48,7 @@ const ( Stream Type = (Type)(pipeline.StreamJobType) VRF Type = (Type)(pipeline.VRFJobType) Webhook Type = (Type)(pipeline.WebhookJobType) + Workflow Type = (Type)(pipeline.WorkflowJobType) ) //revive:disable:redefines-builtin-id diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 475b749dfc5..07b9cb95aae 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -442,6 +442,8 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { jb.GatewaySpecID = &specID case Stream: // 'stream' type has no associated spec, nothing to do here + case Workflow: + // 'workflow' type has no associated spec, nothing to do here default: o.lggr.Panicf("Unsupported jb.Type: %v", jb.Type) } diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index 74e13ae200c..1c8703e2eb1 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -44,6 +44,7 @@ const ( StreamJobType string = "stream" VRFJobType string = "vrf" WebhookJobType string = "webhook" + WorkflowJobType string = "workflow" ) //go:generate mockery --quiet --name Config --output ./mocks/ --case=underscore diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go new file mode 100644 index 00000000000..1e48e229da5 --- /dev/null +++ b/core/services/workflows/delegate.go @@ -0,0 +1,40 @@ +package workflows + +import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +type Delegate struct { + registry types.CapabilitiesRegistry + logger logger.Logger +} + +var _ job.Delegate = (*Delegate)(nil) + +func (d *Delegate) JobType() job.Type { + return job.Workflow +} + +func (d *Delegate) BeforeJobCreated(spec job.Job) {} + +func (d *Delegate) AfterJobCreated(jb job.Job) {} + +func (d *Delegate) BeforeJobDeleted(spec job.Job) {} + +func (d *Delegate) OnDeleteJob(jb job.Job, q pg.Queryer) error { return nil } + +// ServicesForSpec satisfies the job.Delegate interface. +func (d *Delegate) ServicesForSpec(spec job.Job) ([]job.ServiceCtx, error) { + engine, err := NewEngine(d.logger, d.registry) + if err != nil { + return nil, err + } + return []job.ServiceCtx{engine}, nil +} + +func NewDelegate(logger logger.Logger, registry types.CapabilitiesRegistry) *Delegate { + return &Delegate{logger: logger, registry: registry} +} diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go new file mode 100644 index 00000000000..1f34b58105d --- /dev/null +++ b/core/services/workflows/engine.go @@ -0,0 +1,216 @@ +package workflows + +import ( + "context" + "fmt" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +const ( + mockedWorkflowID = "ef7c8168-f4d1-422f-a4b2-8ce0a1075f0a" + mockedTriggerID = "bd727a82-5cac-4071-be62-0152dd9adb0f" +) + +type Engine struct { + services.StateMachine + logger logger.Logger + registry types.CapabilitiesRegistry + trigger capabilities.TriggerCapability + consensus capabilities.ConsensusCapability + target capabilities.TargetCapability + callbackCh chan capabilities.CapabilityResponse + cancel func() +} + +func (e *Engine) Start(ctx context.Context) error { + return e.StartOnce("Engine", func() error { + err := e.registerTrigger(ctx) + if err != nil { + return err + } + + // create a new context, since the one passed in via Start is short-lived. + ctx, cancel := context.WithCancel(context.Background()) + e.cancel = cancel + go e.loop(ctx) + return nil + }) +} + +func (e *Engine) registerTrigger(ctx context.Context) error { + triggerConf, err := values.NewMap( + map[string]any{ + "feedlist": []any{ + // ETHUSD, LINKUSD, USDBTC + 123, 456, 789, + }, + }, + ) + if err != nil { + return err + } + + triggerInputs, err := values.NewMap( + map[string]any{ + "triggerId": mockedTriggerID, + }, + ) + if err != nil { + return err + } + + triggerRegRequest := capabilities.CapabilityRequest{ + Metadata: capabilities.RequestMetadata{ + WorkflowID: mockedWorkflowID, + }, + Config: triggerConf, + Inputs: triggerInputs, + } + err = e.trigger.RegisterTrigger(ctx, e.callbackCh, triggerRegRequest) + if err != nil { + return fmt.Errorf("failed to instantiate mercury_trigger, %s", err) + } + return nil +} + +func (e *Engine) loop(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case resp := <-e.callbackCh: + err := e.handleExecution(ctx, resp) + if err != nil { + e.logger.Error("error executing event %+v: %w", resp, err) + } + } + } +} + +func (e *Engine) handleExecution(ctx context.Context, resp capabilities.CapabilityResponse) error { + results, err := e.handleConsensus(ctx, resp) + if err != nil { + return err + } + + _, err = e.handleTarget(ctx, results) + return err +} + +func (e *Engine) handleTarget(ctx context.Context, resp *values.List) (*values.List, error) { + report, err := resp.Unwrap() + if err != nil { + return nil, err + } + inputs := map[string]values.Value{ + "report": resp, + } + config, err := values.NewMap(map[string]any{ + "address": "0xaabbcc", + "method": "updateFeedValues(report bytes, role uint8)", + "params": []any{ + report, 1, + }, + }) + if err != nil { + return nil, err + } + + tr := capabilities.CapabilityRequest{ + Inputs: &values.Map{Underlying: inputs}, + Config: config, + Metadata: capabilities.RequestMetadata{ + WorkflowID: mockedWorkflowID, + }, + } + return capabilities.ExecuteSync(ctx, e.target, tr) +} + +func (e *Engine) handleConsensus(ctx context.Context, resp capabilities.CapabilityResponse) (*values.List, error) { + inputs := map[string]values.Value{ + "observations": resp.Value, + } + config, err := values.NewMap(map[string]any{ + "aggregation_method": "data_feeds_2_0", + "aggregation_config": map[string]any{ + // ETHUSD + "123": map[string]any{ + "deviation": "0.005", + "heartbeat": "24h", + }, + // LINKUSD + "456": map[string]any{ + "deviation": "0.001", + "heartbeat": "24h", + }, + // BTCUSD + "789": map[string]any{ + "deviation": "0.002", + "heartbeat": "6h", + }, + }, + "encoder": "EVM", + }) + if err != nil { + return nil, nil + } + cr := capabilities.CapabilityRequest{ + Metadata: capabilities.RequestMetadata{ + WorkflowID: mockedWorkflowID, + }, + Inputs: &values.Map{Underlying: inputs}, + Config: config, + } + return capabilities.ExecuteSync(ctx, e.consensus, cr) +} + +func (e *Engine) Close() error { + return e.StopOnce("Engine", func() error { + defer e.cancel() + + triggerInputs, err := values.NewMap( + map[string]any{ + "triggerId": mockedTriggerID, + }, + ) + if err != nil { + return err + } + deregRequest := capabilities.CapabilityRequest{ + Metadata: capabilities.RequestMetadata{ + WorkflowID: mockedWorkflowID, + }, + Inputs: triggerInputs, + } + return e.trigger.UnregisterTrigger(context.Background(), deregRequest) + }) +} + +func NewEngine(lggr logger.Logger, registry types.CapabilitiesRegistry) (*Engine, error) { + ctx := context.Background() + trigger, err := registry.GetTrigger(ctx, "on_mercury_report") + if err != nil { + return nil, err + } + consensus, err := registry.GetConsensus(ctx, "off-chain-reporting") + if err != nil { + return nil, err + } + target, err := registry.GetTarget(ctx, "write_polygon_mainnet") + if err != nil { + return nil, err + } + return &Engine{ + logger: lggr, + registry: registry, + trigger: trigger, + consensus: consensus, + target: target, + callbackCh: make(chan capabilities.CapabilityResponse), + }, nil +} diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go new file mode 100644 index 00000000000..603f5eee3b1 --- /dev/null +++ b/core/services/workflows/engine_test.go @@ -0,0 +1,125 @@ +package workflows + +import ( + "context" + "testing" + + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/values" + coreCap "github.com/smartcontractkit/chainlink/v2/core/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +type mockCapability struct { + capabilities.CapabilityInfo + capabilities.CallbackExecutable + response chan capabilities.CapabilityResponse + transform func(capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) +} + +func newMockCapability(info capabilities.CapabilityInfo, transform func(capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error)) *mockCapability { + return &mockCapability{ + transform: transform, + CapabilityInfo: info, + response: make(chan capabilities.CapabilityResponse, 10), + } +} + +func (m *mockCapability) Execute(ctx context.Context, ch chan<- capabilities.CapabilityResponse, req capabilities.CapabilityRequest) error { + cr, err := m.transform(req) + if err != nil { + return err + } + + ch <- cr + close(ch) + m.response <- cr + return nil +} + +type mockTriggerCapability struct { + capabilities.CapabilityInfo + ch chan<- capabilities.CapabilityResponse +} + +var _ capabilities.TriggerCapability = (*mockTriggerCapability)(nil) + +func (m *mockTriggerCapability) RegisterTrigger(ctx context.Context, ch chan<- capabilities.CapabilityResponse, req capabilities.CapabilityRequest) error { + m.ch = ch + return nil +} + +func (m *mockTriggerCapability) UnregisterTrigger(ctx context.Context, req capabilities.CapabilityRequest) error { + return nil +} + +func TestEngineWithHardcodedWorkflow(t *testing.T) { + ctx := context.Background() + reg := coreCap.NewRegistry() + + trigger := &mockTriggerCapability{ + CapabilityInfo: capabilities.MustNewCapabilityInfo( + "on_mercury_report", + capabilities.CapabilityTypeTrigger, + "issues a trigger when a mercury report is received.", + "v1.0.0", + ), + } + require.NoError(t, reg.Add(ctx, trigger)) + + consensus := newMockCapability( + capabilities.MustNewCapabilityInfo( + "off-chain-reporting", + capabilities.CapabilityTypeConsensus, + "an ocr3 consensus capability", + "v3.0.0", + ), + func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { + return capabilities.CapabilityResponse{ + Value: req.Inputs.Underlying["observations"], + }, nil + }, + ) + require.NoError(t, reg.Add(ctx, consensus)) + + target := newMockCapability( + capabilities.MustNewCapabilityInfo( + "write_polygon_mainnet", + capabilities.CapabilityTypeTarget, + "a write capability targeting polygon mainnet", + "v1.0.0", + ), + func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { + + list := req.Inputs.Underlying["report"].(*values.List) + return capabilities.CapabilityResponse{ + Value: list.Underlying[0], + }, nil + }, + ) + require.NoError(t, reg.Add(ctx, target)) + + lggr := logger.TestLogger(t) + eng, err := NewEngine(lggr, reg) + require.NoError(t, err) + + err = eng.Start(ctx) + require.NoError(t, err) + defer eng.Close() + + resp, err := values.NewMap(map[string]any{ + "123": decimal.NewFromFloat(1.00), + "456": decimal.NewFromFloat(1.25), + "789": decimal.NewFromFloat(1.50), + }) + require.NoError(t, err) + cr := capabilities.CapabilityResponse{ + Value: resp, + } + trigger.ch <- cr + assert.Equal(t, cr, <-target.response) +} diff --git a/core/web/presenters/job.go b/core/web/presenters/job.go index 6b0293665df..7c8643015dd 100644 --- a/core/web/presenters/job.go +++ b/core/web/presenters/job.go @@ -517,6 +517,8 @@ func NewJobResource(j job.Job) *JobResource { resource.GatewaySpec = NewGatewaySpec(j.GatewaySpec) case job.Stream: // no spec; nothing to do + case job.Workflow: + // no spec; nothing to do case job.LegacyGasStationServer, job.LegacyGasStationSidecar: // unsupported } From 2da47a95be68f5193538a55fdc0cf4df15d89711 Mon Sep 17 00:00:00 2001 From: Awbrey Hughlett Date: Mon, 12 Feb 2024 15:50:14 -0500 Subject: [PATCH 09/98] Add New CI Test Script for Mercury LOOPP (#11987) * Add New Test File for Mercury LOOPP This commit adds a new test file for mercury specific integration tests and are configured to only run when the `integration` build flag is provided. * remove parallel tests for plugin --- .github/workflows/ci-core.yml | 1 + .../mercury/integration_plugin_test.go | 27 +++++++++++++++++++ .../ocr2/plugins/mercury/integration_test.go | 12 +++++++++ 3 files changed, 40 insertions(+) create mode 100644 core/services/ocr2/plugins/mercury/integration_plugin_test.go diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 5ffa971ed9e..e681f887700 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -82,6 +82,7 @@ jobs: pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-starknet/relayer) go install ./pkg/chainlink/cmd/chainlink-starknet popd + make install-mercury-loop - name: Increase Race Timeout if: github.event.schedule != '' run: | diff --git a/core/services/ocr2/plugins/mercury/integration_plugin_test.go b/core/services/ocr2/plugins/mercury/integration_plugin_test.go new file mode 100644 index 00000000000..74285f32dcb --- /dev/null +++ b/core/services/ocr2/plugins/mercury/integration_plugin_test.go @@ -0,0 +1,27 @@ +//go:build integration + +package mercury_test + +import ( + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/config/env" +) + +func TestIntegration_MercuryV1_Plugin(t *testing.T) { + t.Setenv(string(env.MercuryPlugin.Cmd), "chainlink-mercury") + + integration_MercuryV1(t) +} + +func TestIntegration_MercuryV2_Plugin(t *testing.T) { + t.Setenv(string(env.MercuryPlugin.Cmd), "chainlink-mercury") + + integration_MercuryV2(t) +} + +func TestIntegration_MercuryV3_Plugin(t *testing.T) { + t.Setenv(string(env.MercuryPlugin.Cmd), "chainlink-mercury") + + integration_MercuryV3(t) +} diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 6d847098f94..0ebc6a5e354 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -128,6 +128,10 @@ func setupBlockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBacke func TestIntegration_MercuryV1(t *testing.T) { t.Parallel() + integration_MercuryV1(t) +} + +func integration_MercuryV1(t *testing.T) { var logObservers []*observer.ObservedLogs t.Cleanup(func() { detectPanicLogs(t, logObservers) @@ -466,6 +470,10 @@ func TestIntegration_MercuryV1(t *testing.T) { func TestIntegration_MercuryV2(t *testing.T) { t.Parallel() + integration_MercuryV2(t) +} + +func integration_MercuryV2(t *testing.T) { var logObservers []*observer.ObservedLogs t.Cleanup(func() { detectPanicLogs(t, logObservers) @@ -736,6 +744,10 @@ func TestIntegration_MercuryV2(t *testing.T) { func TestIntegration_MercuryV3(t *testing.T) { t.Parallel() + integration_MercuryV3(t) +} + +func integration_MercuryV3(t *testing.T) { var logObservers []*observer.ObservedLogs t.Cleanup(func() { detectPanicLogs(t, logObservers) From 13d8b49583f5569e376981b2ff8a079f1678b715 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 13 Feb 2024 11:48:35 -0300 Subject: [PATCH 10/98] add method to export test config as base64 (#12008) --- integration-tests/testconfig/testconfig.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 0913e09b5da..18249cd790e 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -208,6 +208,15 @@ func (c TestConfig) GetConfigurationName() string { return c.ConfigurationName } +func (c *TestConfig) AsBase64() (string, error) { + content, err := toml.Marshal(*c) + if err != nil { + return "", errors.Wrapf(err, "error marshaling test config") + } + + return base64.StdEncoding.EncodeToString(content), nil +} + type Common struct { ChainlinkNodeFunding *float64 `toml:"chainlink_node_funding"` } From c89a15af1def21a9ee4157baa4c71a9033a0e83f Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 13 Feb 2024 10:26:46 -0500 Subject: [PATCH 11/98] pnpm i (#11998) --- contracts/pnpm-lock.yaml | 3712 +++++++++++++++++++------------------- 1 file changed, 1872 insertions(+), 1840 deletions(-) diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 4680467028a..b8c12e24ea1 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -1,130 +1,186 @@ -lockfileVersion: 5.4 +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false overrides: '@ethersproject/logger': 5.0.6 -specifiers: - '@eth-optimism/contracts': 0.6.0 - '@ethereum-waffle/mock-contract': ^3.4.4 - '@ethersproject/abi': ~5.7.0 - '@ethersproject/bignumber': ~5.7.0 - '@ethersproject/contracts': ~5.7.0 - '@ethersproject/providers': ~5.7.2 - '@ethersproject/random': ~5.7.0 - '@nomicfoundation/hardhat-network-helpers': ^1.0.9 - '@nomiclabs/hardhat-ethers': ^2.2.3 - '@nomiclabs/hardhat-etherscan': ^3.1.7 - '@nomiclabs/hardhat-waffle': 2.0.6 - '@openzeppelin/contracts': 4.9.3 - '@openzeppelin/contracts-upgradeable': 4.9.3 - '@openzeppelin/hardhat-upgrades': 1.28.0 - '@openzeppelin/test-helpers': ^0.5.16 - '@scroll-tech/contracts': 0.1.0 - '@typechain/ethers-v5': ^7.2.0 - '@typechain/hardhat': ^7.0.0 - '@types/cbor': 5.0.1 - '@types/chai': ^4.3.11 - '@types/debug': ^4.1.12 - '@types/deep-equal-in-any-order': ^1.0.3 - '@types/mocha': ^10.0.6 - '@types/node': ^16.18.68 - '@typescript-eslint/eslint-plugin': ^6.14.0 - '@typescript-eslint/parser': ^6.14.0 - abi-to-sol: ^0.6.6 - cbor: ^5.2.0 - chai: ^4.3.10 - debug: ^4.3.4 - deep-equal-in-any-order: ^2.0.6 - eslint: ^8.55.0 - eslint-config-prettier: ^9.1.0 - eslint-plugin-prettier: ^5.0.1 - ethereum-waffle: ^3.4.4 - ethers: ~5.7.2 - hardhat: ~2.19.2 - hardhat-abi-exporter: ^2.10.1 - hardhat-contract-sizer: ^2.10.0 - hardhat-gas-reporter: ^1.0.9 - hardhat-ignore-warnings: ^0.2.6 - istanbul: ^0.4.5 - moment: ^2.29.4 - prettier: ^3.1.1 - prettier-plugin-solidity: 1.2.0 - rlp: ^2.2.7 - solhint: ^4.0.0 - solhint-plugin-chainlink-solidity: git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.0 - solhint-plugin-prettier: ^0.1.0 - solidity-coverage: ^0.8.5 - ts-node: ^10.9.2 - tslib: ^2.6.2 - typechain: ^8.2.1 - typescript: ^5.3.3 - dependencies: - '@eth-optimism/contracts': 0.6.0_ethers@5.7.2 - '@openzeppelin/contracts': 4.9.3 - '@openzeppelin/contracts-upgradeable': 4.9.3 - '@scroll-tech/contracts': 0.1.0 + '@eth-optimism/contracts': + specifier: 0.6.0 + version: 0.6.0(ethers@5.7.2) + '@openzeppelin/contracts': + specifier: 4.9.3 + version: 4.9.3 + '@openzeppelin/contracts-upgradeable': + specifier: 4.9.3 + version: 4.9.3 + '@scroll-tech/contracts': + specifier: 0.1.0 + version: 0.1.0 devDependencies: - '@ethereum-waffle/mock-contract': 3.4.4 - '@ethersproject/abi': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/contracts': 5.7.0 - '@ethersproject/providers': 5.7.2 - '@ethersproject/random': 5.7.0 - '@nomicfoundation/hardhat-network-helpers': 1.0.10_hardhat@2.19.2 - '@nomiclabs/hardhat-ethers': 2.2.3_z6q3nf6v3crguog4fmnabttfbe - '@nomiclabs/hardhat-etherscan': 3.1.8_hardhat@2.19.2 - '@nomiclabs/hardhat-waffle': 2.0.6_o2e3xrjkuas65lubqlsgrdpvpa - '@openzeppelin/hardhat-upgrades': 1.28.0_pwiliixddycc3ncpjrbbdedcey - '@openzeppelin/test-helpers': 0.5.16_bn.js@4.12.0 - '@typechain/ethers-v5': 7.2.0_tclb6finxruvhalpmjwhx4avhu - '@typechain/hardhat': 7.0.0_m4jqzzk4enwlwaue5mxuokvtaq - '@types/cbor': 5.0.1 - '@types/chai': 4.3.11 - '@types/debug': 4.1.12 - '@types/deep-equal-in-any-order': 1.0.3 - '@types/mocha': 10.0.6 - '@types/node': 16.18.68 - '@typescript-eslint/eslint-plugin': 6.18.1_kzaxd5qmua5pq4bpt4gj2rbjta - '@typescript-eslint/parser': 6.18.1_7hj7rehet5x3fvq7nqub5sammm - abi-to-sol: 0.6.6 - cbor: 5.2.0 - chai: 4.3.10 - debug: 4.3.4 - deep-equal-in-any-order: 2.0.6 - eslint: 8.55.0 - eslint-config-prettier: 9.1.0_eslint@8.55.0 - eslint-plugin-prettier: 5.0.1_34cv2ng2ecdkhobougxv63nlsu - ethereum-waffle: 3.4.4_typescript@5.3.3 - ethers: 5.7.2 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa - hardhat-abi-exporter: 2.10.1_hardhat@2.19.2 - hardhat-contract-sizer: 2.10.0_hardhat@2.19.2 - hardhat-gas-reporter: 1.0.9_hardhat@2.19.2 - hardhat-ignore-warnings: 0.2.9 - istanbul: 0.4.5 - moment: 2.29.4 - prettier: 3.2.1 - prettier-plugin-solidity: 1.2.0_prettier@3.2.1 - rlp: 2.2.7 - solhint: 4.0.0 - solhint-plugin-chainlink-solidity: github.com/smartcontractkit/chainlink-solhint-rules/cfc50b32f95b730304a50deb2e27e88d87115874 - solhint-plugin-prettier: 0.1.0_sl2subkwtlymlyf3uzoc3og3za - solidity-coverage: 0.8.5_hardhat@2.19.2 - ts-node: 10.9.2_elefmx52zewn5giftcrxd6iwku - tslib: 2.6.2 - typechain: 8.3.2_typescript@5.3.3 - typescript: 5.3.3 + '@ethereum-waffle/mock-contract': + specifier: ^3.4.4 + version: 3.4.4 + '@ethersproject/abi': + specifier: ~5.7.0 + version: 5.7.0 + '@ethersproject/bignumber': + specifier: ~5.7.0 + version: 5.7.0 + '@ethersproject/contracts': + specifier: ~5.7.0 + version: 5.7.0 + '@ethersproject/providers': + specifier: ~5.7.2 + version: 5.7.2 + '@ethersproject/random': + specifier: ~5.7.0 + version: 5.7.0 + '@nomicfoundation/hardhat-network-helpers': + specifier: ^1.0.9 + version: 1.0.10(hardhat@2.19.2) + '@nomiclabs/hardhat-ethers': + specifier: ^2.2.3 + version: 2.2.3(ethers@5.7.2)(hardhat@2.19.2) + '@nomiclabs/hardhat-etherscan': + specifier: ^3.1.7 + version: 3.1.8(hardhat@2.19.2) + '@nomiclabs/hardhat-waffle': + specifier: 2.0.6 + version: 2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.8)(ethereum-waffle@3.4.4)(ethers@5.7.2)(hardhat@2.19.2) + '@openzeppelin/hardhat-upgrades': + specifier: 1.28.0 + version: 1.28.0(@nomiclabs/hardhat-ethers@2.2.3)(@nomiclabs/hardhat-etherscan@3.1.8)(ethers@5.7.2)(hardhat@2.19.2) + '@openzeppelin/test-helpers': + specifier: ^0.5.16 + version: 0.5.16(bn.js@4.12.0) + '@typechain/ethers-v5': + specifier: ^7.2.0 + version: 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2)(typescript@5.3.3) + '@typechain/hardhat': + specifier: ^7.0.0 + version: 7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0)(ethers@5.7.2)(hardhat@2.19.2)(typechain@8.3.2) + '@types/cbor': + specifier: 5.0.1 + version: 5.0.1 + '@types/chai': + specifier: ^4.3.11 + version: 4.3.11 + '@types/debug': + specifier: ^4.1.12 + version: 4.1.12 + '@types/deep-equal-in-any-order': + specifier: ^1.0.3 + version: 1.0.3 + '@types/mocha': + specifier: ^10.0.6 + version: 10.0.6 + '@types/node': + specifier: ^16.18.68 + version: 16.18.68 + '@typescript-eslint/eslint-plugin': + specifier: ^6.14.0 + version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/parser': + specifier: ^6.14.0 + version: 6.18.1(eslint@8.55.0)(typescript@5.3.3) + abi-to-sol: + specifier: ^0.6.6 + version: 0.6.6 + cbor: + specifier: ^5.2.0 + version: 5.2.0 + chai: + specifier: ^4.3.10 + version: 4.3.10 + debug: + specifier: ^4.3.4 + version: 4.3.4(supports-color@8.1.1) + deep-equal-in-any-order: + specifier: ^2.0.6 + version: 2.0.6 + eslint: + specifier: ^8.55.0 + version: 8.55.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@8.55.0) + eslint-plugin-prettier: + specifier: ^5.0.1 + version: 5.0.1(eslint-config-prettier@9.1.0)(eslint@8.55.0)(prettier@3.2.1) + ethereum-waffle: + specifier: ^3.4.4 + version: 3.4.4(typescript@5.3.3) + ethers: + specifier: ~5.7.2 + version: 5.7.2 + hardhat: + specifier: ~2.19.2 + version: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) + hardhat-abi-exporter: + specifier: ^2.10.1 + version: 2.10.1(hardhat@2.19.2) + hardhat-contract-sizer: + specifier: ^2.10.0 + version: 2.10.0(hardhat@2.19.2) + hardhat-gas-reporter: + specifier: ^1.0.9 + version: 1.0.9(hardhat@2.19.2) + hardhat-ignore-warnings: + specifier: ^0.2.6 + version: 0.2.9 + istanbul: + specifier: ^0.4.5 + version: 0.4.5 + moment: + specifier: ^2.29.4 + version: 2.29.4 + prettier: + specifier: ^3.1.1 + version: 3.2.1 + prettier-plugin-solidity: + specifier: 1.2.0 + version: 1.2.0(prettier@3.2.1) + rlp: + specifier: ^2.2.7 + version: 2.2.7 + solhint: + specifier: ^4.0.0 + version: 4.0.0 + solhint-plugin-chainlink-solidity: + specifier: git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.0 + version: github.com/smartcontractkit/chainlink-solhint-rules/cfc50b32f95b730304a50deb2e27e88d87115874 + solhint-plugin-prettier: + specifier: ^0.1.0 + version: 0.1.0(prettier-plugin-solidity@1.2.0)(prettier@3.2.1) + solidity-coverage: + specifier: ^0.8.5 + version: 0.8.5(hardhat@2.19.2) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@16.18.68)(typescript@5.3.3) + tslib: + specifier: ^2.6.2 + version: 2.6.2 + typechain: + specifier: ^8.2.1 + version: 8.3.2(typescript@5.3.3) + typescript: + specifier: ^5.3.3 + version: 5.3.3 packages: - /@aashutoshrathi/word-wrap/1.2.6: + /@aashutoshrathi/word-wrap@1.2.6: resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} dev: true - /@aws-crypto/sha256-js/1.2.2: + /@aws-crypto/sha256-js@1.2.2: resolution: {integrity: sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==} dependencies: '@aws-crypto/util': 1.2.2 @@ -132,7 +188,7 @@ packages: tslib: 1.14.1 dev: true - /@aws-crypto/util/1.2.2: + /@aws-crypto/util@1.2.2: resolution: {integrity: sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==} dependencies: '@aws-sdk/types': 3.468.0 @@ -140,7 +196,7 @@ packages: tslib: 1.14.1 dev: true - /@aws-sdk/types/3.468.0: + /@aws-sdk/types@3.468.0: resolution: {integrity: sha512-rx/9uHI4inRbp2tw3Y4Ih4PNZkVj32h7WneSg3MVgVjAoVD5Zti9KhS5hkvsBxfgmQmg0AQbE+b1sy5WGAgntA==} engines: {node: '>=14.0.0'} dependencies: @@ -148,25 +204,25 @@ packages: tslib: 2.6.2 dev: true - /@aws-sdk/util-utf8-browser/3.259.0: + /@aws-sdk/util-utf8-browser@3.259.0: resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} dependencies: tslib: 2.6.2 dev: true - /@babel/code-frame/7.18.6: + /@babel/code-frame@7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 dev: true - /@babel/helper-validator-identifier/7.19.1: + /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} dev: true - /@babel/highlight/7.18.6: + /@babel/highlight@7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} dependencies: @@ -175,37 +231,37 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/runtime/7.19.0: + /@babel/runtime@7.19.0: resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.9 dev: true - /@chainsafe/as-sha256/0.3.1: + /@chainsafe/as-sha256@0.3.1: resolution: {integrity: sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==} dev: true - /@chainsafe/persistent-merkle-tree/0.4.2: + /@chainsafe/persistent-merkle-tree@0.4.2: resolution: {integrity: sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==} dependencies: '@chainsafe/as-sha256': 0.3.1 dev: true - /@chainsafe/persistent-merkle-tree/0.5.0: + /@chainsafe/persistent-merkle-tree@0.5.0: resolution: {integrity: sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==} dependencies: '@chainsafe/as-sha256': 0.3.1 dev: true - /@chainsafe/ssz/0.10.2: + /@chainsafe/ssz@0.10.2: resolution: {integrity: sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==} dependencies: '@chainsafe/as-sha256': 0.3.1 '@chainsafe/persistent-merkle-tree': 0.5.0 dev: true - /@chainsafe/ssz/0.9.4: + /@chainsafe/ssz@0.9.4: resolution: {integrity: sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==} dependencies: '@chainsafe/as-sha256': 0.3.1 @@ -213,21 +269,21 @@ packages: case: 1.6.3 dev: true - /@colors/colors/1.5.0: + /@colors/colors@1.5.0: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} requiresBuild: true dev: true optional: true - /@cspotcode/source-map-support/0.8.1: + /@cspotcode/source-map-support@0.8.1: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} dependencies: '@jridgewell/trace-mapping': 0.3.9 dev: true - /@ensdomains/address-encoder/0.1.9: + /@ensdomains/address-encoder@0.1.9: resolution: {integrity: sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==} dependencies: bech32: 1.1.4 @@ -239,7 +295,7 @@ packages: ripemd160: 2.0.2 dev: true - /@ensdomains/ens/0.4.5: + /@ensdomains/ens@0.4.5: resolution: {integrity: sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==} deprecated: Please use @ensdomains/ens-contracts dependencies: @@ -250,7 +306,7 @@ packages: web3-utils: 1.8.0 dev: true - /@ensdomains/ensjs/2.1.0: + /@ensdomains/ensjs@2.1.0: resolution: {integrity: sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==} dependencies: '@babel/runtime': 7.19.0 @@ -266,12 +322,12 @@ packages: - utf-8-validate dev: true - /@ensdomains/resolver/0.2.4: + /@ensdomains/resolver@0.2.4: resolution: {integrity: sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==} deprecated: Please use @ensdomains/ens-contracts dev: true - /@eslint-community/eslint-utils/4.4.0_eslint@8.55.0: + /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -281,17 +337,17 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/regexpp/4.9.1: + /@eslint-community/regexpp@4.9.1: resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc/2.1.4: + /@eslint/eslintrc@2.1.4: resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) espree: 9.6.1 globals: 13.20.0 ignore: 5.2.4 @@ -303,12 +359,12 @@ packages: - supports-color dev: true - /@eslint/js/8.55.0: + /@eslint/js@8.55.0: resolution: {integrity: sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@eth-optimism/contracts/0.6.0_ethers@5.7.2: + /@eth-optimism/contracts@0.6.0(ethers@5.7.2): resolution: {integrity: sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==} peerDependencies: ethers: ^5 @@ -322,7 +378,7 @@ packages: - utf-8-validate dev: false - /@eth-optimism/core-utils/0.12.0: + /@eth-optimism/core-utils@0.12.0: resolution: {integrity: sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==} dependencies: '@ethersproject/abi': 5.7.0 @@ -346,7 +402,7 @@ packages: - utf-8-validate dev: false - /@ethereum-waffle/chai/3.4.4: + /@ethereum-waffle/chai@3.4.4: resolution: {integrity: sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==} engines: {node: '>=10.0'} dependencies: @@ -359,13 +415,13 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/compiler/3.4.4_typescript@5.3.3: + /@ethereum-waffle/compiler@3.4.4(typescript@5.3.3): resolution: {integrity: sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==} engines: {node: '>=10.0'} dependencies: '@resolver-engine/imports': 0.3.3 '@resolver-engine/imports-fs': 0.3.3 - '@typechain/ethers-v5': 2.0.0_qm5qgbtbzj2awa7q5l4ce4se5a + '@typechain/ethers-v5': 2.0.0(ethers@5.7.2)(typechain@3.0.0) '@types/mkdirp': 0.5.2 '@types/node-fetch': 2.6.2 ethers: 5.7.2 @@ -373,7 +429,7 @@ packages: node-fetch: 2.6.7 solc: 0.6.12 ts-generator: 0.1.1 - typechain: 3.0.0_typescript@5.3.3 + typechain: 3.0.0(typescript@5.3.3) transitivePeerDependencies: - bufferutil - encoding @@ -382,7 +438,7 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/ens/3.4.4: + /@ethereum-waffle/ens@3.4.4: resolution: {integrity: sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==} engines: {node: '>=10.0'} dependencies: @@ -394,7 +450,7 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/mock-contract/3.4.4: + /@ethereum-waffle/mock-contract@3.4.4: resolution: {integrity: sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==} engines: {node: '>=10.0'} dependencies: @@ -405,7 +461,7 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/provider/3.4.4: + /@ethereum-waffle/provider@3.4.4: resolution: {integrity: sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==} engines: {node: '>=10.0'} dependencies: @@ -421,21 +477,21 @@ packages: - utf-8-validate dev: true - /@ethereumjs/common/2.6.5: + /@ethereumjs/common@2.6.5: resolution: {integrity: sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==} dependencies: crc-32: 1.2.2 ethereumjs-util: 7.1.5 dev: true - /@ethereumjs/tx/3.5.2: + /@ethereumjs/tx@3.5.2: resolution: {integrity: sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==} dependencies: '@ethereumjs/common': 2.6.5 ethereumjs-util: 7.1.5 dev: true - /@ethersproject/abi/5.0.0-beta.153: + /@ethersproject/abi@5.0.0-beta.153: resolution: {integrity: sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==} dependencies: '@ethersproject/address': 5.7.0 @@ -450,7 +506,7 @@ packages: dev: true optional: true - /@ethersproject/abi/5.7.0: + /@ethersproject/abi@5.7.0: resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} dependencies: '@ethersproject/address': 5.7.0 @@ -463,7 +519,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/abstract-provider/5.7.0: + /@ethersproject/abstract-provider@5.7.0: resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} dependencies: '@ethersproject/bignumber': 5.7.0 @@ -474,7 +530,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/web': 5.7.1 - /@ethersproject/abstract-signer/5.7.0: + /@ethersproject/abstract-signer@5.7.0: resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -483,7 +539,7 @@ packages: '@ethersproject/logger': 5.0.6 '@ethersproject/properties': 5.7.0 - /@ethersproject/address/5.7.0: + /@ethersproject/address@5.7.0: resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} dependencies: '@ethersproject/bignumber': 5.7.0 @@ -492,35 +548,35 @@ packages: '@ethersproject/logger': 5.0.6 '@ethersproject/rlp': 5.7.0 - /@ethersproject/base64/5.7.0: + /@ethersproject/base64@5.7.0: resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} dependencies: '@ethersproject/bytes': 5.7.0 - /@ethersproject/basex/5.7.0: + /@ethersproject/basex@5.7.0: resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/properties': 5.7.0 - /@ethersproject/bignumber/5.7.0: + /@ethersproject/bignumber@5.7.0: resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 bn.js: 5.2.1 - /@ethersproject/bytes/5.7.0: + /@ethersproject/bytes@5.7.0: resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/constants/5.7.0: + /@ethersproject/constants@5.7.0: resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} dependencies: '@ethersproject/bignumber': 5.7.0 - /@ethersproject/contracts/5.7.0: + /@ethersproject/contracts@5.7.0: resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} dependencies: '@ethersproject/abi': 5.7.0 @@ -534,7 +590,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/transactions': 5.7.0 - /@ethersproject/hash/5.7.0: + /@ethersproject/hash@5.7.0: resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -547,7 +603,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/hdnode/5.7.0: + /@ethersproject/hdnode@5.7.0: resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -563,7 +619,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/wordlists': 5.7.0 - /@ethersproject/json-wallets/5.7.0: + /@ethersproject/json-wallets@5.7.0: resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -580,32 +636,32 @@ packages: aes-js: 3.0.0 scrypt-js: 3.0.1 - /@ethersproject/keccak256/5.7.0: + /@ethersproject/keccak256@5.7.0: resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} dependencies: '@ethersproject/bytes': 5.7.0 js-sha3: 0.8.0 - /@ethersproject/logger/5.0.6: + /@ethersproject/logger@5.0.6: resolution: {integrity: sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ==} - /@ethersproject/networks/5.7.1: + /@ethersproject/networks@5.7.1: resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/pbkdf2/5.7.0: + /@ethersproject/pbkdf2@5.7.0: resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/sha2': 5.7.0 - /@ethersproject/properties/5.7.0: + /@ethersproject/properties@5.7.0: resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/providers/5.7.2: + /@ethersproject/providers@5.7.2: resolution: {integrity: sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -632,26 +688,26 @@ packages: - bufferutil - utf-8-validate - /@ethersproject/random/5.7.0: + /@ethersproject/random@5.7.0: resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/rlp/5.7.0: + /@ethersproject/rlp@5.7.0: resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/sha2/5.7.0: + /@ethersproject/sha2@5.7.0: resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 hash.js: 1.1.7 - /@ethersproject/signing-key/5.7.0: + /@ethersproject/signing-key@5.7.0: resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} dependencies: '@ethersproject/bytes': 5.7.0 @@ -661,7 +717,7 @@ packages: elliptic: 6.5.4 hash.js: 1.1.7 - /@ethersproject/solidity/5.7.0: + /@ethersproject/solidity@5.7.0: resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==} dependencies: '@ethersproject/bignumber': 5.7.0 @@ -671,14 +727,14 @@ packages: '@ethersproject/sha2': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/strings/5.7.0: + /@ethersproject/strings@5.7.0: resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/constants': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/transactions/5.7.0: + /@ethersproject/transactions@5.7.0: resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} dependencies: '@ethersproject/address': 5.7.0 @@ -691,14 +747,14 @@ packages: '@ethersproject/rlp': 5.7.0 '@ethersproject/signing-key': 5.7.0 - /@ethersproject/units/5.7.0: + /@ethersproject/units@5.7.0: resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==} dependencies: '@ethersproject/bignumber': 5.7.0 '@ethersproject/constants': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/wallet/5.7.0: + /@ethersproject/wallet@5.7.0: resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -717,7 +773,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/wordlists': 5.7.0 - /@ethersproject/web/5.7.1: + /@ethersproject/web@5.7.1: resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} dependencies: '@ethersproject/base64': 5.7.0 @@ -726,7 +782,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/wordlists/5.7.0: + /@ethersproject/wordlists@5.7.0: resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} dependencies: '@ethersproject/bytes': 5.7.0 @@ -735,43 +791,43 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@humanwhocodes/config-array/0.11.13: + /@humanwhocodes/config-array@0.11.13: resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color dev: true - /@humanwhocodes/module-importer/1.0.1: + /@humanwhocodes/module-importer@1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} dev: true - /@humanwhocodes/object-schema/2.0.1: + /@humanwhocodes/object-schema@2.0.1: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true - /@jridgewell/resolve-uri/3.1.1: + /@jridgewell/resolve-uri@3.1.1: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} dev: true - /@jridgewell/sourcemap-codec/1.4.15: + /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true - /@jridgewell/trace-mapping/0.3.9: + /@jridgewell/trace-mapping@0.3.9: resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@metamask/eth-sig-util/4.0.1: + /@metamask/eth-sig-util@4.0.1: resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==} engines: {node: '>=12.0.0'} dependencies: @@ -782,15 +838,15 @@ packages: tweetnacl-util: 0.15.1 dev: true - /@noble/hashes/1.1.2: + /@noble/hashes@1.1.2: resolution: {integrity: sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==} dev: true - /@noble/secp256k1/1.6.3: + /@noble/secp256k1@1.6.3: resolution: {integrity: sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==} dev: true - /@nodelib/fs.scandir/2.1.5: + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} dependencies: @@ -798,12 +854,12 @@ packages: run-parallel: 1.1.9 dev: true - /@nodelib/fs.stat/2.0.5: + /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} dev: true - /@nodelib/fs.walk/1.2.8: + /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} dependencies: @@ -811,7 +867,7 @@ packages: fastq: 1.6.0 dev: true - /@nomicfoundation/ethereumjs-block/5.0.2: + /@nomicfoundation/ethereumjs-block@5.0.2: resolution: {integrity: sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q==} engines: {node: '>=14'} dependencies: @@ -827,7 +883,7 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ethereumjs-blockchain/7.0.2: + /@nomicfoundation/ethereumjs-blockchain@7.0.2: resolution: {integrity: sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w==} engines: {node: '>=14'} dependencies: @@ -839,7 +895,7 @@ packages: '@nomicfoundation/ethereumjs-tx': 5.0.2 '@nomicfoundation/ethereumjs-util': 9.0.2 abstract-level: 1.0.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 level: 8.0.0 lru-cache: 5.1.1 @@ -850,14 +906,14 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ethereumjs-common/4.0.2: + /@nomicfoundation/ethereumjs-common@4.0.2: resolution: {integrity: sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg==} dependencies: '@nomicfoundation/ethereumjs-util': 9.0.2 crc-32: 1.2.2 dev: true - /@nomicfoundation/ethereumjs-ethash/3.0.2: + /@nomicfoundation/ethereumjs-ethash@3.0.2: resolution: {integrity: sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg==} engines: {node: '>=14'} dependencies: @@ -872,7 +928,7 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ethereumjs-evm/2.0.2: + /@nomicfoundation/ethereumjs-evm@2.0.2: resolution: {integrity: sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ==} engines: {node: '>=14'} dependencies: @@ -880,7 +936,7 @@ packages: '@nomicfoundation/ethereumjs-common': 4.0.2 '@nomicfoundation/ethereumjs-tx': 5.0.2 '@nomicfoundation/ethereumjs-util': 9.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 mcl-wasm: 0.7.9 rustbn.js: 0.2.0 @@ -890,18 +946,18 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ethereumjs-rlp/5.0.2: + /@nomicfoundation/ethereumjs-rlp@5.0.2: resolution: {integrity: sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA==} engines: {node: '>=14'} hasBin: true dev: true - /@nomicfoundation/ethereumjs-statemanager/2.0.2: + /@nomicfoundation/ethereumjs-statemanager@2.0.2: resolution: {integrity: sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA==} dependencies: '@nomicfoundation/ethereumjs-common': 4.0.2 '@nomicfoundation/ethereumjs-rlp': 5.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 ethers: 5.7.2 js-sdsl: 4.4.2 @@ -911,7 +967,7 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ethereumjs-trie/6.0.2: + /@nomicfoundation/ethereumjs-trie@6.0.2: resolution: {integrity: sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ==} engines: {node: '>=14'} dependencies: @@ -922,7 +978,7 @@ packages: readable-stream: 3.6.0 dev: true - /@nomicfoundation/ethereumjs-tx/5.0.2: + /@nomicfoundation/ethereumjs-tx@5.0.2: resolution: {integrity: sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g==} engines: {node: '>=14'} dependencies: @@ -937,7 +993,7 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ethereumjs-util/9.0.2: + /@nomicfoundation/ethereumjs-util@9.0.2: resolution: {integrity: sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ==} engines: {node: '>=14'} dependencies: @@ -946,7 +1002,7 @@ packages: ethereum-cryptography: 0.1.3 dev: true - /@nomicfoundation/ethereumjs-vm/7.0.2: + /@nomicfoundation/ethereumjs-vm@7.0.2: resolution: {integrity: sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA==} engines: {node: '>=14'} dependencies: @@ -959,7 +1015,7 @@ packages: '@nomicfoundation/ethereumjs-trie': 6.0.2 '@nomicfoundation/ethereumjs-tx': 5.0.2 '@nomicfoundation/ethereumjs-util': 9.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 mcl-wasm: 0.7.9 rustbn.js: 0.2.0 @@ -969,16 +1025,16 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/hardhat-network-helpers/1.0.10_hardhat@2.19.2: + /@nomicfoundation/hardhat-network-helpers@1.0.10(hardhat@2.19.2): resolution: {integrity: sha512-R35/BMBlx7tWN5V6d/8/19QCwEmIdbnA4ZrsuXgvs8i2qFx5i7h6mH5pBS4Pwi4WigLH+upl6faYusrNPuzMrQ==} peerDependencies: hardhat: ^2.9.5 dependencies: ethereumjs-util: 7.1.5 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) dev: true - /@nomicfoundation/solidity-analyzer-darwin-arm64/0.1.0: + /@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0: resolution: {integrity: sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==} engines: {node: '>= 10'} cpu: [arm64] @@ -987,7 +1043,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-darwin-x64/0.1.0: + /@nomicfoundation/solidity-analyzer-darwin-x64@0.1.0: resolution: {integrity: sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==} engines: {node: '>= 10'} cpu: [x64] @@ -996,7 +1052,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-freebsd-x64/0.1.0: + /@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.0: resolution: {integrity: sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==} engines: {node: '>= 10'} cpu: [x64] @@ -1005,7 +1061,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-arm64-gnu/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.0: resolution: {integrity: sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==} engines: {node: '>= 10'} cpu: [arm64] @@ -1014,7 +1070,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-arm64-musl/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.0: resolution: {integrity: sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==} engines: {node: '>= 10'} cpu: [arm64] @@ -1023,7 +1079,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-x64-gnu/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.0: resolution: {integrity: sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==} engines: {node: '>= 10'} cpu: [x64] @@ -1032,7 +1088,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-x64-musl/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.0: resolution: {integrity: sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==} engines: {node: '>= 10'} cpu: [x64] @@ -1041,7 +1097,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-win32-arm64-msvc/0.1.0: + /@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.0: resolution: {integrity: sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==} engines: {node: '>= 10'} cpu: [arm64] @@ -1050,7 +1106,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-win32-ia32-msvc/0.1.0: + /@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.0: resolution: {integrity: sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==} engines: {node: '>= 10'} cpu: [ia32] @@ -1059,7 +1115,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-win32-x64-msvc/0.1.0: + /@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.0: resolution: {integrity: sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==} engines: {node: '>= 10'} cpu: [x64] @@ -1068,7 +1124,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer/0.1.0: + /@nomicfoundation/solidity-analyzer@0.1.0: resolution: {integrity: sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==} engines: {node: '>= 12'} optionalDependencies: @@ -1084,17 +1140,17 @@ packages: '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.0 dev: true - /@nomiclabs/hardhat-ethers/2.2.3_z6q3nf6v3crguog4fmnabttfbe: + /@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.19.2): resolution: {integrity: sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==} peerDependencies: ethers: ^5.0.0 hardhat: ^2.0.0 dependencies: ethers: 5.7.2 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) dev: true - /@nomiclabs/hardhat-etherscan/3.1.8_hardhat@2.19.2: + /@nomiclabs/hardhat-etherscan@3.1.8(hardhat@2.19.2): resolution: {integrity: sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ==} deprecated: The @nomiclabs/hardhat-etherscan package is deprecated, please use @nomicfoundation/hardhat-verify instead peerDependencies: @@ -1104,9 +1160,9 @@ packages: '@ethersproject/address': 5.7.0 cbor: 8.1.0 chalk: 2.4.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) fs-extra: 7.0.1 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) lodash: 4.17.21 semver: 6.3.0 table: 6.8.1 @@ -1115,7 +1171,7 @@ packages: - supports-color dev: true - /@nomiclabs/hardhat-waffle/2.0.6_o2e3xrjkuas65lubqlsgrdpvpa: + /@nomiclabs/hardhat-waffle@2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.8)(ethereum-waffle@3.4.4)(ethers@5.7.2)(hardhat@2.19.2): resolution: {integrity: sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg==} peerDependencies: '@nomiclabs/hardhat-ethers': ^2.0.0 @@ -1124,34 +1180,34 @@ packages: ethers: ^5.0.0 hardhat: ^2.0.0 dependencies: - '@nomiclabs/hardhat-ethers': 2.2.3_z6q3nf6v3crguog4fmnabttfbe + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.19.2) '@types/sinon-chai': 3.2.8 - ethereum-waffle: 3.4.4_typescript@5.3.3 + ethereum-waffle: 3.4.4(typescript@5.3.3) ethers: 5.7.2 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) dev: true - /@openzeppelin/contract-loader/0.6.3: + /@openzeppelin/contract-loader@0.6.3: resolution: {integrity: sha512-cOFIjBjwbGgZhDZsitNgJl0Ye1rd5yu/Yx5LMgeq3u0ZYzldm4uObzHDFq4gjDdoypvyORjjJa3BlFA7eAnVIg==} dependencies: find-up: 4.1.0 fs-extra: 8.1.0 dev: true - /@openzeppelin/contracts-upgradeable/4.9.3: + /@openzeppelin/contracts-upgradeable@4.9.3: resolution: {integrity: sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==} dev: false - /@openzeppelin/contracts/4.9.3: + /@openzeppelin/contracts@4.9.3: resolution: {integrity: sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==} dev: false - /@openzeppelin/defender-base-client/1.52.0_debug@4.3.4: + /@openzeppelin/defender-base-client@1.52.0(debug@4.3.4): resolution: {integrity: sha512-VFNu/pjVpAnFKIfuKT1cn9dRpbcO8FO8EAmVZ2XrrAsKXEWDZ3TNBtACxmj7fAu0ad/TzRkb66o5rMts7Fv7jw==} dependencies: amazon-cognito-identity-js: 6.3.7 async-retry: 1.3.3 - axios: 1.6.2_debug@4.3.4 + axios: 1.6.2(debug@4.3.4) lodash: 4.17.21 node-fetch: 2.6.7 transitivePeerDependencies: @@ -1159,7 +1215,7 @@ packages: - encoding dev: true - /@openzeppelin/hardhat-upgrades/1.28.0_pwiliixddycc3ncpjrbbdedcey: + /@openzeppelin/hardhat-upgrades@1.28.0(@nomiclabs/hardhat-ethers@2.2.3)(@nomiclabs/hardhat-etherscan@3.1.8)(ethers@5.7.2)(hardhat@2.19.2): resolution: {integrity: sha512-7sb/Jf+X+uIufOBnmHR0FJVWuxEs2lpxjJnLNN6eCJCP8nD0v+Ot5lTOW2Qb/GFnh+fLvJtEkhkowz4ZQ57+zQ==} hasBin: true peerDependencies: @@ -1172,28 +1228,28 @@ packages: '@nomiclabs/harhdat-etherscan': optional: true dependencies: - '@nomiclabs/hardhat-ethers': 2.2.3_z6q3nf6v3crguog4fmnabttfbe - '@nomiclabs/hardhat-etherscan': 3.1.8_hardhat@2.19.2 - '@openzeppelin/defender-base-client': 1.52.0_debug@4.3.4 - '@openzeppelin/platform-deploy-client': 0.8.0_debug@4.3.4 + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.19.2) + '@nomiclabs/hardhat-etherscan': 3.1.8(hardhat@2.19.2) + '@openzeppelin/defender-base-client': 1.52.0(debug@4.3.4) + '@openzeppelin/platform-deploy-client': 0.8.0(debug@4.3.4) '@openzeppelin/upgrades-core': 1.31.3 chalk: 4.1.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethers: 5.7.2 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) proper-lockfile: 4.1.2 transitivePeerDependencies: - encoding - supports-color dev: true - /@openzeppelin/platform-deploy-client/0.8.0_debug@4.3.4: + /@openzeppelin/platform-deploy-client@0.8.0(debug@4.3.4): resolution: {integrity: sha512-POx3AsnKwKSV/ZLOU/gheksj0Lq7Is1q2F3pKmcFjGZiibf+4kjGxr4eSMrT+2qgKYZQH1ZLQZ+SkbguD8fTvA==} deprecated: '@openzeppelin/platform-deploy-client is deprecated. Please use @openzeppelin/defender-sdk-deploy-client' dependencies: '@ethersproject/abi': 5.7.0 - '@openzeppelin/defender-base-client': 1.52.0_debug@4.3.4 - axios: 0.21.4_debug@4.3.4 + '@openzeppelin/defender-base-client': 1.52.0(debug@4.3.4) + axios: 0.21.4(debug@4.3.4) lodash: 4.17.21 node-fetch: 2.6.7 transitivePeerDependencies: @@ -1201,14 +1257,14 @@ packages: - encoding dev: true - /@openzeppelin/test-helpers/0.5.16_bn.js@4.12.0: + /@openzeppelin/test-helpers@0.5.16(bn.js@4.12.0): resolution: {integrity: sha512-T1EvspSfH1qQO/sgGlskLfYVBbqzJR23SZzYl/6B2JnT4EhThcI85UpvDk0BkLWKaDScQTabGHt4GzHW+3SfZg==} dependencies: '@openzeppelin/contract-loader': 0.6.3 '@truffle/contract': 4.6.2 ansi-colors: 3.2.4 chai: 4.3.10 - chai-bn: 0.2.2_bn.js@4.12.0+chai@4.3.10 + chai-bn: 0.2.2(bn.js@4.12.0)(chai@4.3.10) ethjs-abi: 0.2.1 lodash.flatten: 4.4.0 semver: 5.7.1 @@ -1222,14 +1278,14 @@ packages: - utf-8-validate dev: true - /@openzeppelin/upgrades-core/1.31.3: + /@openzeppelin/upgrades-core@1.31.3: resolution: {integrity: sha512-i7q0IuItKS4uO0clJwm4CARmt98aA9dLfKh38HFRbX+aFLGXwF0sOvB2iwr6f87ShH7d3DNuLrVgnnXUrYb7CA==} hasBin: true dependencies: cbor: 9.0.1 chalk: 4.1.2 compare-versions: 6.1.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereumjs-util: 7.1.5 minimist: 1.2.8 proper-lockfile: 4.1.2 @@ -1238,7 +1294,7 @@ packages: - supports-color dev: true - /@pkgr/utils/2.4.2: + /@pkgr/utils@2.4.2: resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} dependencies: @@ -1250,19 +1306,19 @@ packages: tslib: 2.6.2 dev: true - /@pnpm/config.env-replace/1.1.0: + /@pnpm/config.env-replace@1.1.0: resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} engines: {node: '>=12.22.0'} dev: true - /@pnpm/network.ca-file/1.0.2: + /@pnpm/network.ca-file@1.0.2: resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} engines: {node: '>=12.22.0'} dependencies: graceful-fs: 4.2.10 dev: true - /@pnpm/npm-conf/2.2.2: + /@pnpm/npm-conf@2.2.2: resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} engines: {node: '>=12'} dependencies: @@ -1271,7 +1327,7 @@ packages: config-chain: 1.1.13 dev: true - /@prettier/sync/0.3.0_prettier@3.2.1: + /@prettier/sync@0.3.0(prettier@3.2.1): resolution: {integrity: sha512-3dcmCyAxIcxy036h1I7MQU/uEEBq8oLwf1CE3xeze+MPlgkdlb/+w6rGR/1dhp6Hqi17fRS6nvwnOzkESxEkOw==} peerDependencies: prettier: ^3.0.0 @@ -1279,7 +1335,7 @@ packages: prettier: 3.2.1 dev: true - /@resolver-engine/core/0.3.3: + /@resolver-engine/core@0.3.3: resolution: {integrity: sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==} dependencies: debug: 3.2.7 @@ -1289,7 +1345,7 @@ packages: - supports-color dev: true - /@resolver-engine/fs/0.3.3: + /@resolver-engine/fs@0.3.3: resolution: {integrity: sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==} dependencies: '@resolver-engine/core': 0.3.3 @@ -1298,7 +1354,7 @@ packages: - supports-color dev: true - /@resolver-engine/imports-fs/0.3.3: + /@resolver-engine/imports-fs@0.3.3: resolution: {integrity: sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==} dependencies: '@resolver-engine/fs': 0.3.3 @@ -1308,7 +1364,7 @@ packages: - supports-color dev: true - /@resolver-engine/imports/0.3.3: + /@resolver-engine/imports@0.3.3: resolution: {integrity: sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==} dependencies: '@resolver-engine/core': 0.3.3 @@ -1320,15 +1376,15 @@ packages: - supports-color dev: true - /@scroll-tech/contracts/0.1.0: + /@scroll-tech/contracts@0.1.0: resolution: {integrity: sha512-aBbDOc3WB/WveZdpJYcrfvMYMz7ZTEiW8M9XMJLba8p9FAR5KGYB/cV+8+EUsq3MKt7C1BfR+WnXoTVdvwIY6w==} dev: false - /@scure/base/1.1.1: + /@scure/base@1.1.1: resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} dev: true - /@scure/bip32/1.1.0: + /@scure/bip32@1.1.0: resolution: {integrity: sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==} dependencies: '@noble/hashes': 1.1.2 @@ -1336,14 +1392,14 @@ packages: '@scure/base': 1.1.1 dev: true - /@scure/bip39/1.1.0: + /@scure/bip39@1.1.0: resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} dependencies: '@noble/hashes': 1.1.2 '@scure/base': 1.1.1 dev: true - /@sentry/core/5.30.0: + /@sentry/core@5.30.0: resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} engines: {node: '>=6'} dependencies: @@ -1354,7 +1410,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/hub/5.30.0: + /@sentry/hub@5.30.0: resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} engines: {node: '>=6'} dependencies: @@ -1363,7 +1419,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/minimal/5.30.0: + /@sentry/minimal@5.30.0: resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} engines: {node: '>=6'} dependencies: @@ -1372,7 +1428,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/node/5.30.0: + /@sentry/node@5.30.0: resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} engines: {node: '>=6'} dependencies: @@ -1389,7 +1445,7 @@ packages: - supports-color dev: true - /@sentry/tracing/5.30.0: + /@sentry/tracing@5.30.0: resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} engines: {node: '>=6'} dependencies: @@ -1400,12 +1456,12 @@ packages: tslib: 1.14.1 dev: true - /@sentry/types/5.30.0: + /@sentry/types@5.30.0: resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} engines: {node: '>=6'} dev: true - /@sentry/utils/5.30.0: + /@sentry/utils@5.30.0: resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} engines: {node: '>=6'} dependencies: @@ -1413,56 +1469,56 @@ packages: tslib: 1.14.1 dev: true - /@sindresorhus/is/0.14.0: + /@sindresorhus/is@0.14.0: resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} engines: {node: '>=6'} dev: true - /@sindresorhus/is/4.6.0: + /@sindresorhus/is@4.6.0: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} dev: true - /@smithy/types/2.7.0: + /@smithy/types@2.7.0: resolution: {integrity: sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 dev: true - /@solidity-parser/parser/0.14.3: + /@solidity-parser/parser@0.14.3: resolution: {integrity: sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==} dependencies: antlr4ts: 0.5.0-alpha.4 dev: true - /@solidity-parser/parser/0.16.0: + /@solidity-parser/parser@0.16.0: resolution: {integrity: sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==} dependencies: antlr4ts: 0.5.0-alpha.4 dev: true - /@solidity-parser/parser/0.16.2: + /@solidity-parser/parser@0.16.2: resolution: {integrity: sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==} dependencies: antlr4ts: 0.5.0-alpha.4 dev: true - /@szmarczak/http-timer/1.1.2: + /@szmarczak/http-timer@1.1.2: resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} engines: {node: '>=6'} dependencies: defer-to-connect: 1.1.1 dev: true - /@szmarczak/http-timer/5.0.1: + /@szmarczak/http-timer@5.0.1: resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} dependencies: defer-to-connect: 2.0.1 dev: true - /@truffle/abi-utils/0.3.2: + /@truffle/abi-utils@0.3.2: resolution: {integrity: sha512-32queMD64YKL/tmQgSV4Xs073dIaZ9tp7NP1icjwvFSA3Q9yeu7ApYbSbYMsx9H9zWkkVOsfcoJ2kJEieOCzsA==} dependencies: change-case: 3.0.2 @@ -1470,11 +1526,11 @@ packages: web3-utils: 1.7.4 dev: true - /@truffle/blockchain-utils/0.1.4: + /@truffle/blockchain-utils@0.1.4: resolution: {integrity: sha512-HegAo5A8UX9vE8dtceBRgCY207gOb9wj54c8mNOOWHcFpkyJz7kZYGo44As6Imh10/0hD2j7vHQ56Jf+uszJ3A==} dev: true - /@truffle/codec/0.14.5: + /@truffle/codec@0.14.5: resolution: {integrity: sha512-3FCpTJe6o7LGWUfrSdguMpdpH1PTn3u7bIfbj6Cfdzym2OAVSgxTgdlqC1poepbk0xcOVcUW+EsqNwLMqmBiPA==} dependencies: '@truffle/abi-utils': 0.3.2 @@ -1482,7 +1538,7 @@ packages: big.js: 6.2.1 bn.js: 5.2.1 cbor: 5.2.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) lodash: 4.17.21 semver: 7.3.7 utf8: 3.0.0 @@ -1491,23 +1547,23 @@ packages: - supports-color dev: true - /@truffle/compile-common/0.8.1: + /@truffle/compile-common@0.8.1: resolution: {integrity: sha512-7mzzG9Cfrn+fDT5Sqi7B6pccvIIV5w/GM8/56YgnjysbDzy5aZ6mv0fe37ZbcznEVQ35NJjBy+lEr/ozOGXwQA==} dependencies: '@truffle/error': 0.1.1 colors: 1.4.0 dev: true - /@truffle/contract-schema/3.4.10: + /@truffle/contract-schema@3.4.10: resolution: {integrity: sha512-BhRNRoRvlj2th6E5RNS0BnS0ZxQe01JJz8I7MjkGqdeXSvrn6qDCAnbmvhNgUv0l5h8w5+gBOQhAJhILf1shdQ==} dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true - /@truffle/contract/4.6.2: + /@truffle/contract@4.6.2: resolution: {integrity: sha512-OZZIDmKtHgZS2Q6sCczNe8OfTuMWpRaAo3vwY49LGGs0VXLiwc7nIcCFh+bMg14IRK6vBN4pWE9W9eWSBFy31Q==} dependencies: '@ensdomains/ensjs': 2.1.0 @@ -1517,7 +1573,7 @@ packages: '@truffle/error': 0.1.1 '@truffle/interface-adapter': 0.5.22 bignumber.js: 7.2.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethers: 4.0.49 web3: 1.7.4 web3-core-helpers: 1.7.4 @@ -1530,24 +1586,24 @@ packages: - utf-8-validate dev: true - /@truffle/debug-utils/6.0.35: + /@truffle/debug-utils@6.0.35: resolution: {integrity: sha512-GuLsc+GFEYiUM683GWh4/ol3jkBts5a601detVWu1Xo5/bSL5gxooOjgOTovjA8dimCjkyi/DnK2yHHC+q+g0g==} dependencies: '@truffle/codec': 0.14.5 '@trufflesuite/chromafi': 3.0.0 bn.js: 5.2.1 chalk: 2.4.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) highlightjs-solidity: 2.0.5 transitivePeerDependencies: - supports-color dev: true - /@truffle/error/0.1.1: + /@truffle/error@0.1.1: resolution: {integrity: sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==} dev: true - /@truffle/interface-adapter/0.5.22: + /@truffle/interface-adapter@0.5.22: resolution: {integrity: sha512-Bgl5Afb1mPVNedI8CJzZQzVIdrZWSXISTBrXPZmppD4Q+6V1RUzlLxiaGGB4gYHOA+U0pBzD8MCcSycPAD9RsA==} dependencies: bn.js: 5.2.1 @@ -1559,7 +1615,7 @@ packages: - utf-8-validate dev: true - /@trufflesuite/chromafi/3.0.0: + /@trufflesuite/chromafi@3.0.0: resolution: {integrity: sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==} dependencies: camelcase: 4.1.0 @@ -1572,33 +1628,33 @@ packages: strip-indent: 2.0.0 dev: true - /@tsconfig/node10/1.0.9: + /@tsconfig/node10@1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} dev: true - /@tsconfig/node12/1.0.11: + /@tsconfig/node12@1.0.11: resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} dev: true - /@tsconfig/node14/1.0.3: + /@tsconfig/node14@1.0.3: resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} dev: true - /@tsconfig/node16/1.0.3: + /@tsconfig/node16@1.0.3: resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} dev: true - /@typechain/ethers-v5/2.0.0_qm5qgbtbzj2awa7q5l4ce4se5a: + /@typechain/ethers-v5@2.0.0(ethers@5.7.2)(typechain@3.0.0): resolution: {integrity: sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==} peerDependencies: ethers: ^5.0.0 typechain: ^3.0.0 dependencies: ethers: 5.7.2 - typechain: 3.0.0_typescript@5.3.3 + typechain: 3.0.0(typescript@5.3.3) dev: true - /@typechain/ethers-v5/7.2.0_tclb6finxruvhalpmjwhx4avhu: + /@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2)(typescript@5.3.3): resolution: {integrity: sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==} peerDependencies: '@ethersproject/abi': ^5.0.0 @@ -1613,12 +1669,12 @@ packages: '@ethersproject/providers': 5.7.2 ethers: 5.7.2 lodash: 4.17.21 - ts-essentials: 7.0.3_typescript@5.3.3 - typechain: 8.3.2_typescript@5.3.3 + ts-essentials: 7.0.3(typescript@5.3.3) + typechain: 8.3.2(typescript@5.3.3) typescript: 5.3.3 dev: true - /@typechain/hardhat/7.0.0_m4jqzzk4enwlwaue5mxuokvtaq: + /@typechain/hardhat@7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0)(ethers@5.7.2)(hardhat@2.19.2)(typechain@8.3.2): resolution: {integrity: sha512-XB79i5ewg9Met7gMVGfgVkmypicbnI25T5clJBEooMoW2161p4zvKFpoS2O+lBppQyMrPIZkdvl2M3LMDayVcA==} peerDependencies: '@ethersproject/abi': ^5.4.7 @@ -1630,26 +1686,26 @@ packages: dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/providers': 5.7.2 - '@typechain/ethers-v5': 7.2.0_tclb6finxruvhalpmjwhx4avhu + '@typechain/ethers-v5': 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2)(typescript@5.3.3) ethers: 5.7.2 fs-extra: 9.1.0 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa - typechain: 8.3.2_typescript@5.3.3 + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) + typechain: 8.3.2(typescript@5.3.3) dev: true - /@types/bn.js/4.11.6: + /@types/bn.js@4.11.6: resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} dependencies: '@types/node': 16.18.68 dev: true - /@types/bn.js/5.1.1: + /@types/bn.js@5.1.1: resolution: {integrity: sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==} dependencies: '@types/node': 16.18.68 dev: true - /@types/cacheable-request/6.0.2: + /@types/cacheable-request@6.0.2: resolution: {integrity: sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==} dependencies: '@types/http-cache-semantics': 4.0.1 @@ -1658,43 +1714,43 @@ packages: '@types/responselike': 1.0.0 dev: true - /@types/cbor/5.0.1: + /@types/cbor@5.0.1: resolution: {integrity: sha512-zVqJy2KzusZPLOgyGJDnOIbu3DxIGGqxYbEwtEEe4Z+la8jwIhOyb+GMrlHafs5tvKruwf8f8qOYP6zTvse/pw==} dependencies: '@types/node': 16.18.68 dev: true - /@types/chai/4.3.11: + /@types/chai@4.3.11: resolution: {integrity: sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==} dev: true - /@types/concat-stream/1.6.1: + /@types/concat-stream@1.6.1: resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} dependencies: '@types/node': 16.18.68 dev: true - /@types/debug/4.1.12: + /@types/debug@4.1.12: resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} dependencies: '@types/ms': 0.7.31 dev: true - /@types/deep-equal-in-any-order/1.0.3: + /@types/deep-equal-in-any-order@1.0.3: resolution: {integrity: sha512-jT0O3hAILDKeKbdWJ9FZLD0Xdfhz7hMvfyFlRWpirjiEVr8G+GZ4kVIzPIqM6x6Rpp93TNPgOAed4XmvcuV6Qg==} dev: true - /@types/events/3.0.0: + /@types/events@3.0.0: resolution: {integrity: sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==} dev: true - /@types/form-data/0.0.33: + /@types/form-data@0.0.33: resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} dependencies: '@types/node': 16.18.68 dev: true - /@types/glob/7.1.1: + /@types/glob@7.1.1: resolution: {integrity: sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==} dependencies: '@types/events': 3.0.0 @@ -1702,126 +1758,126 @@ packages: '@types/node': 16.18.68 dev: true - /@types/http-cache-semantics/4.0.1: + /@types/http-cache-semantics@4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true - /@types/json-schema/7.0.13: + /@types/json-schema@7.0.13: resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==} dev: true - /@types/keyv/3.1.4: + /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: '@types/node': 16.18.68 dev: true - /@types/lru-cache/5.1.1: + /@types/lru-cache@5.1.1: resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} dev: true - /@types/minimatch/3.0.3: + /@types/minimatch@3.0.3: resolution: {integrity: sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==} dev: true - /@types/mkdirp/0.5.2: + /@types/mkdirp@0.5.2: resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==} dependencies: '@types/node': 16.18.68 dev: true - /@types/mocha/10.0.6: + /@types/mocha@10.0.6: resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==} dev: true - /@types/ms/0.7.31: + /@types/ms@0.7.31: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true - /@types/node-fetch/2.6.2: + /@types/node-fetch@2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: '@types/node': 16.18.68 form-data: 3.0.1 dev: true - /@types/node/10.17.60: + /@types/node@10.17.60: resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} dev: true - /@types/node/12.19.16: + /@types/node@12.19.16: resolution: {integrity: sha512-7xHmXm/QJ7cbK2laF+YYD7gb5MggHIIQwqyjin3bpEGiSuvScMQ5JZZXPvRipi1MwckTQbJZROMns/JxdnIL1Q==} dev: true - /@types/node/16.18.68: + /@types/node@16.18.68: resolution: {integrity: sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg==} dev: true - /@types/node/8.10.66: + /@types/node@8.10.66: resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} dev: true - /@types/pbkdf2/3.1.0: + /@types/pbkdf2@3.1.0: resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} dependencies: '@types/node': 16.18.68 dev: true - /@types/prettier/2.7.1: + /@types/prettier@2.7.1: resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} dev: true - /@types/qs/6.9.7: + /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} dev: true - /@types/readable-stream/2.3.15: + /@types/readable-stream@2.3.15: resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==} dependencies: '@types/node': 16.18.68 safe-buffer: 5.1.2 dev: true - /@types/resolve/0.0.8: + /@types/resolve@0.0.8: resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} dependencies: '@types/node': 16.18.68 dev: true - /@types/responselike/1.0.0: + /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: '@types/node': 16.18.68 dev: true - /@types/secp256k1/4.0.3: + /@types/secp256k1@4.0.3: resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} dependencies: '@types/node': 16.18.68 dev: true - /@types/semver/7.5.0: + /@types/semver@7.5.0: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} dev: true - /@types/sinon-chai/3.2.8: + /@types/sinon-chai@3.2.8: resolution: {integrity: sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==} dependencies: '@types/chai': 4.3.11 '@types/sinon': 10.0.13 dev: true - /@types/sinon/10.0.13: + /@types/sinon@10.0.13: resolution: {integrity: sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==} dependencies: '@types/sinonjs__fake-timers': 8.1.2 dev: true - /@types/sinonjs__fake-timers/8.1.2: + /@types/sinonjs__fake-timers@8.1.2: resolution: {integrity: sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==} dev: true - /@typescript-eslint/eslint-plugin/6.18.1_kzaxd5qmua5pq4bpt4gj2rbjta: + /@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.55.0)(typescript@5.3.3): resolution: {integrity: sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1833,24 +1889,24 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.9.1 - '@typescript-eslint/parser': 6.18.1_7hj7rehet5x3fvq7nqub5sammm + '@typescript-eslint/parser': 6.18.1(eslint@8.55.0)(typescript@5.3.3) '@typescript-eslint/scope-manager': 6.18.1 - '@typescript-eslint/type-utils': 6.18.1_7hj7rehet5x3fvq7nqub5sammm - '@typescript-eslint/utils': 6.18.1_7hj7rehet5x3fvq7nqub5sammm + '@typescript-eslint/type-utils': 6.18.1(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.55.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) eslint: 8.55.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.3_typescript@5.3.3 + ts-api-utils: 1.0.3(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser/6.18.1_7hj7rehet5x3fvq7nqub5sammm: + /@typescript-eslint/parser@6.18.1(eslint@8.55.0)(typescript@5.3.3): resolution: {integrity: sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1862,16 +1918,16 @@ packages: dependencies: '@typescript-eslint/scope-manager': 6.18.1 '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/typescript-estree': 6.18.1_typescript@5.3.3 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) eslint: 8.55.0 typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/6.18.1: + /@typescript-eslint/scope-manager@6.18.1: resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: @@ -1879,7 +1935,7 @@ packages: '@typescript-eslint/visitor-keys': 6.18.1 dev: true - /@typescript-eslint/type-utils/6.18.1_7hj7rehet5x3fvq7nqub5sammm: + /@typescript-eslint/type-utils@6.18.1(eslint@8.55.0)(typescript@5.3.3): resolution: {integrity: sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1889,22 +1945,22 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.18.1_typescript@5.3.3 - '@typescript-eslint/utils': 6.18.1_7hj7rehet5x3fvq7nqub5sammm - debug: 4.3.4 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.55.0)(typescript@5.3.3) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.55.0 - ts-api-utils: 1.0.3_typescript@5.3.3 + ts-api-utils: 1.0.3(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/6.18.1: + /@typescript-eslint/types@6.18.1: resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree/6.18.1_typescript@5.3.3: + /@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3): resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1915,29 +1971,29 @@ packages: dependencies: '@typescript-eslint/types': 6.18.1 '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3_typescript@5.3.3 + ts-api-utils: 1.0.3(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/6.18.1_7hj7rehet5x3fvq7nqub5sammm: + /@typescript-eslint/utils@6.18.1(eslint@8.55.0)(typescript@5.3.3): resolution: {integrity: sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.55.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) '@types/json-schema': 7.0.13 '@types/semver': 7.5.0 '@typescript-eslint/scope-manager': 6.18.1 '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/typescript-estree': 6.18.1_typescript@5.3.3 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) eslint: 8.55.0 semver: 7.5.4 transitivePeerDependencies: @@ -1945,7 +2001,7 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/6.18.1: + /@typescript-eslint/visitor-keys@6.18.1: resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: @@ -1953,45 +2009,45 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@ungap/structured-clone/1.2.0: + /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@yarnpkg/lockfile/1.1.0: + /@yarnpkg/lockfile@1.1.0: resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} dev: true - /abbrev/1.0.9: + /abbrev@1.0.9: resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} dev: true - /abbrev/1.1.1: + /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: true - /abi-to-sol/0.6.6: + /abi-to-sol@0.6.6: resolution: {integrity: sha512-PRn81rSpv6NXFPYQSw7ujruqIP6UkwZ/XoFldtiqCX8+2kHVc73xVaUVvdbro06vvBVZiwnxhEIGdI4BRMwGHw==} hasBin: true dependencies: '@truffle/abi-utils': 0.3.2 '@truffle/contract-schema': 3.4.10 ajv: 6.12.6 - better-ajv-errors: 0.8.2_ajv@6.12.6 + better-ajv-errors: 0.8.2(ajv@6.12.6) neodoc: 2.0.2 semver: 7.3.7 source-map-support: 0.5.21 optionalDependencies: prettier: 2.8.8 - prettier-plugin-solidity: 1.2.0_prettier@2.8.8 + prettier-plugin-solidity: 1.2.0(prettier@2.8.8) transitivePeerDependencies: - supports-color dev: true - /abortcontroller-polyfill/1.7.3: + /abortcontroller-polyfill@1.7.3: resolution: {integrity: sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==} dev: true - /abstract-level/1.0.3: + /abstract-level@1.0.3: resolution: {integrity: sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==} engines: {node: '>=12'} dependencies: @@ -2004,33 +2060,33 @@ packages: queue-microtask: 1.2.3 dev: true - /abstract-leveldown/2.6.3: + /abstract-leveldown@2.6.3: resolution: {integrity: sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==} dependencies: xtend: 4.0.2 dev: true - /abstract-leveldown/2.7.2: + /abstract-leveldown@2.7.2: resolution: {integrity: sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==} dependencies: xtend: 4.0.2 dev: true - /abstract-leveldown/3.0.0: + /abstract-leveldown@3.0.0: resolution: {integrity: sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==} engines: {node: '>=4'} dependencies: xtend: 4.0.2 dev: true - /abstract-leveldown/5.0.0: + /abstract-leveldown@5.0.0: resolution: {integrity: sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==} engines: {node: '>=6'} dependencies: xtend: 4.0.2 dev: true - /accepts/1.3.7: + /accepts@1.3.7: resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} engines: {node: '>= 0.6'} dependencies: @@ -2038,7 +2094,7 @@ packages: negotiator: 0.6.2 dev: true - /acorn-jsx/5.3.2_acorn@8.10.0: + /acorn-jsx@5.3.2(acorn@8.10.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2046,45 +2102,45 @@ packages: acorn: 8.10.0 dev: true - /acorn-walk/8.2.0: + /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} dev: true - /acorn/8.10.0: + /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} hasBin: true dev: true - /address/1.1.2: + /address@1.1.2: resolution: {integrity: sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==} engines: {node: '>= 0.12.0'} dev: true - /adm-zip/0.4.16: + /adm-zip@0.4.16: resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} engines: {node: '>=0.3.0'} dev: true - /aes-js/3.0.0: + /aes-js@3.0.0: resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} - /aes-js/3.1.2: + /aes-js@3.1.2: resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} dev: true optional: true - /agent-base/6.0.2: + /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true - /aggregate-error/3.1.0: + /aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} dependencies: @@ -2092,7 +2148,7 @@ packages: indent-string: 4.0.0 dev: true - /ajv/6.12.6: + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: fast-deep-equal: 3.1.3 @@ -2101,7 +2157,7 @@ packages: uri-js: 4.4.1 dev: true - /ajv/8.11.0: + /ajv@8.11.0: resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} dependencies: fast-deep-equal: 3.1.3 @@ -2110,7 +2166,7 @@ packages: uri-js: 4.4.1 dev: true - /amazon-cognito-identity-js/6.3.7: + /amazon-cognito-identity-js@6.3.7: resolution: {integrity: sha512-tSjnM7KyAeOZ7UMah+oOZ6cW4Gf64FFcc7BE2l7MTcp7ekAPrXaCbpcW2xEpH1EiDS4cPcAouHzmCuc2tr72vQ==} dependencies: '@aws-crypto/sha256-js': 1.2.2 @@ -2122,88 +2178,88 @@ packages: - encoding dev: true - /amdefine/1.0.1: + /amdefine@1.0.1: resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} engines: {node: '>=0.4.2'} dev: true optional: true - /ansi-colors/3.2.3: + /ansi-colors@3.2.3: resolution: {integrity: sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==} engines: {node: '>=6'} dev: true - /ansi-colors/3.2.4: + /ansi-colors@3.2.4: resolution: {integrity: sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==} engines: {node: '>=6'} dev: true - /ansi-colors/4.1.1: + /ansi-colors@4.1.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} dev: true - /ansi-colors/4.1.3: + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} dev: true - /ansi-escapes/4.3.2: + /ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} dependencies: type-fest: 0.21.3 dev: true - /ansi-regex/2.1.1: + /ansi-regex@2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} dev: true - /ansi-regex/3.0.1: + /ansi-regex@3.0.1: resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} engines: {node: '>=4'} dev: true - /ansi-regex/4.1.1: + /ansi-regex@4.1.1: resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} engines: {node: '>=6'} dev: true - /ansi-regex/5.0.1: + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true - /ansi-styles/2.2.1: + /ansi-styles@2.2.1: resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} engines: {node: '>=0.10.0'} dev: true - /ansi-styles/3.2.1: + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} dependencies: color-convert: 1.9.3 dev: true - /ansi-styles/4.3.0: + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 dev: true - /antlr4/4.13.0: + /antlr4@4.13.0: resolution: {integrity: sha512-zooUbt+UscjnWyOrsuY/tVFL4rwrAGwOivpQmvmUDE22hy/lUA467Rc1rcixyRwcRUIXFYBwv7+dClDSHdmmew==} engines: {node: '>=16'} dev: true - /antlr4ts/0.5.0-alpha.4: + /antlr4ts@0.5.0-alpha.4: resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} dev: true - /anymatch/3.1.2: + /anymatch@3.1.2: resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} engines: {node: '>= 8'} dependencies: @@ -2211,86 +2267,86 @@ packages: picomatch: 2.3.1 dev: true - /arg/4.1.3: + /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: true - /argparse/1.0.10: + /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: sprintf-js: 1.0.3 dev: true - /argparse/2.0.1: + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /arr-diff/4.0.0: + /arr-diff@4.0.0: resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} engines: {node: '>=0.10.0'} dev: true - /arr-flatten/1.1.0: + /arr-flatten@1.1.0: resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} engines: {node: '>=0.10.0'} dev: true - /arr-union/3.1.0: + /arr-union@3.1.0: resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} engines: {node: '>=0.10.0'} dev: true - /array-back/1.0.4: + /array-back@1.0.4: resolution: {integrity: sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==} engines: {node: '>=0.12.0'} dependencies: typical: 2.6.1 dev: true - /array-back/2.0.0: + /array-back@2.0.0: resolution: {integrity: sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==} engines: {node: '>=4'} dependencies: typical: 2.6.1 dev: true - /array-back/3.1.0: + /array-back@3.1.0: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} engines: {node: '>=6'} dev: true - /array-back/4.0.2: + /array-back@4.0.2: resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} engines: {node: '>=8'} dev: true - /array-buffer-byte-length/1.0.0: + /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} dependencies: call-bind: 1.0.5 is-array-buffer: 3.0.2 dev: true - /array-flatten/1.1.1: + /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: true - /array-union/2.1.0: + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /array-uniq/1.0.3: + /array-uniq@1.0.3: resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} engines: {node: '>=0.10.0'} dev: true - /array-unique/0.3.2: + /array-unique@0.3.2: resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} engines: {node: '>=0.10.0'} dev: true - /array.prototype.findlast/1.2.3: + /array.prototype.findlast@1.2.3: resolution: {integrity: sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g==} engines: {node: '>= 0.4'} dependencies: @@ -2301,7 +2357,7 @@ packages: get-intrinsic: 1.2.2 dev: true - /array.prototype.reduce/1.0.4: + /array.prototype.reduce@1.0.4: resolution: {integrity: sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==} engines: {node: '>= 0.4'} dependencies: @@ -2312,7 +2368,7 @@ packages: is-string: 1.0.7 dev: true - /arraybuffer.prototype.slice/1.0.2: + /arraybuffer.prototype.slice@1.0.2: resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} engines: {node: '>= 0.4'} dependencies: @@ -2325,11 +2381,11 @@ packages: is-shared-array-buffer: 1.0.2 dev: true - /asap/2.0.6: + /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} dev: true - /asn1.js/4.10.1: + /asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} dependencies: bn.js: 4.12.0 @@ -2337,113 +2393,113 @@ packages: minimalistic-assert: 1.0.1 dev: true - /asn1/0.2.4: + /asn1@0.2.4: resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} dependencies: safer-buffer: 2.1.2 dev: true - /assert-plus/1.0.0: + /assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} dev: true - /assertion-error/1.1.0: + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - /assign-symbols/1.0.0: + /assign-symbols@1.0.0: resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} engines: {node: '>=0.10.0'} dev: true - /ast-parents/0.0.1: + /ast-parents@0.0.1: resolution: {integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==} dev: true - /astral-regex/2.0.0: + /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} dev: true - /async-eventemitter/0.2.4: + /async-eventemitter@0.2.4: resolution: {integrity: sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==} dependencies: async: 2.6.3 dev: true - /async-limiter/1.0.1: + /async-limiter@1.0.1: resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} dev: true - /async-retry/1.3.3: + /async-retry@1.3.3: resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} dependencies: retry: 0.13.1 dev: true - /async/1.5.2: + /async@1.5.2: resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} dev: true - /async/2.6.2: + /async@2.6.2: resolution: {integrity: sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==} dependencies: lodash: 4.17.21 dev: true - /async/2.6.3: + /async@2.6.3: resolution: {integrity: sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==} dependencies: lodash: 4.17.21 dev: true - /asynckit/0.4.0: + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: true - /at-least-node/1.0.0: + /at-least-node@1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} dev: true - /atob/2.1.2: + /atob@2.1.2: resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} engines: {node: '>= 4.5.0'} hasBin: true dev: true - /available-typed-arrays/1.0.5: + /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} dev: true - /aws-sign2/0.7.0: + /aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} dev: true - /aws4/1.11.0: + /aws4@1.11.0: resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} dev: true - /axios/0.21.4_debug@4.3.4: + /axios@0.21.4(debug@4.3.4): resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} dependencies: - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2(debug@4.3.4) transitivePeerDependencies: - debug dev: true - /axios/1.6.2_debug@4.3.4: + /axios@1.6.2(debug@4.3.4): resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==} dependencies: - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug dev: true - /babel-code-frame/6.26.0: + /babel-code-frame@6.26.0: resolution: {integrity: sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==} dependencies: chalk: 1.1.3 @@ -2451,7 +2507,7 @@ packages: js-tokens: 3.0.2 dev: true - /babel-core/6.26.3: + /babel-core@6.26.3: resolution: {integrity: sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==} dependencies: babel-code-frame: 6.26.0 @@ -2477,7 +2533,7 @@ packages: - supports-color dev: true - /babel-generator/6.26.1: + /babel-generator@6.26.1: resolution: {integrity: sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==} dependencies: babel-messages: 6.23.0 @@ -2490,7 +2546,7 @@ packages: trim-right: 1.0.1 dev: true - /babel-helper-builder-binary-assignment-operator-visitor/6.24.1: + /babel-helper-builder-binary-assignment-operator-visitor@6.24.1: resolution: {integrity: sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==} dependencies: babel-helper-explode-assignable-expression: 6.24.1 @@ -2500,7 +2556,7 @@ packages: - supports-color dev: true - /babel-helper-call-delegate/6.24.1: + /babel-helper-call-delegate@6.24.1: resolution: {integrity: sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==} dependencies: babel-helper-hoist-variables: 6.24.1 @@ -2511,7 +2567,7 @@ packages: - supports-color dev: true - /babel-helper-define-map/6.26.0: + /babel-helper-define-map@6.26.0: resolution: {integrity: sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==} dependencies: babel-helper-function-name: 6.24.1 @@ -2522,7 +2578,7 @@ packages: - supports-color dev: true - /babel-helper-explode-assignable-expression/6.24.1: + /babel-helper-explode-assignable-expression@6.24.1: resolution: {integrity: sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==} dependencies: babel-runtime: 6.26.0 @@ -2532,7 +2588,7 @@ packages: - supports-color dev: true - /babel-helper-function-name/6.24.1: + /babel-helper-function-name@6.24.1: resolution: {integrity: sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==} dependencies: babel-helper-get-function-arity: 6.24.1 @@ -2544,28 +2600,28 @@ packages: - supports-color dev: true - /babel-helper-get-function-arity/6.24.1: + /babel-helper-get-function-arity@6.24.1: resolution: {integrity: sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-helper-hoist-variables/6.24.1: + /babel-helper-hoist-variables@6.24.1: resolution: {integrity: sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-helper-optimise-call-expression/6.24.1: + /babel-helper-optimise-call-expression@6.24.1: resolution: {integrity: sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-helper-regex/6.26.0: + /babel-helper-regex@6.26.0: resolution: {integrity: sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==} dependencies: babel-runtime: 6.26.0 @@ -2573,7 +2629,7 @@ packages: lodash: 4.17.21 dev: true - /babel-helper-remap-async-to-generator/6.24.1: + /babel-helper-remap-async-to-generator@6.24.1: resolution: {integrity: sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==} dependencies: babel-helper-function-name: 6.24.1 @@ -2585,7 +2641,7 @@ packages: - supports-color dev: true - /babel-helper-replace-supers/6.24.1: + /babel-helper-replace-supers@6.24.1: resolution: {integrity: sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==} dependencies: babel-helper-optimise-call-expression: 6.24.1 @@ -2598,7 +2654,7 @@ packages: - supports-color dev: true - /babel-helpers/6.24.1: + /babel-helpers@6.24.1: resolution: {integrity: sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==} dependencies: babel-runtime: 6.26.0 @@ -2607,31 +2663,31 @@ packages: - supports-color dev: true - /babel-messages/6.23.0: + /babel-messages@6.23.0: resolution: {integrity: sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-check-es2015-constants/6.22.0: + /babel-plugin-check-es2015-constants@6.22.0: resolution: {integrity: sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-syntax-async-functions/6.13.0: + /babel-plugin-syntax-async-functions@6.13.0: resolution: {integrity: sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==} dev: true - /babel-plugin-syntax-exponentiation-operator/6.13.0: + /babel-plugin-syntax-exponentiation-operator@6.13.0: resolution: {integrity: sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==} dev: true - /babel-plugin-syntax-trailing-function-commas/6.22.0: + /babel-plugin-syntax-trailing-function-commas@6.22.0: resolution: {integrity: sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==} dev: true - /babel-plugin-transform-async-to-generator/6.24.1: + /babel-plugin-transform-async-to-generator@6.24.1: resolution: {integrity: sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==} dependencies: babel-helper-remap-async-to-generator: 6.24.1 @@ -2641,19 +2697,19 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-arrow-functions/6.22.0: + /babel-plugin-transform-es2015-arrow-functions@6.22.0: resolution: {integrity: sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-block-scoped-functions/6.22.0: + /babel-plugin-transform-es2015-block-scoped-functions@6.22.0: resolution: {integrity: sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-block-scoping/6.26.0: + /babel-plugin-transform-es2015-block-scoping@6.26.0: resolution: {integrity: sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==} dependencies: babel-runtime: 6.26.0 @@ -2665,7 +2721,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-classes/6.24.1: + /babel-plugin-transform-es2015-classes@6.24.1: resolution: {integrity: sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==} dependencies: babel-helper-define-map: 6.26.0 @@ -2681,7 +2737,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-computed-properties/6.24.1: + /babel-plugin-transform-es2015-computed-properties@6.24.1: resolution: {integrity: sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==} dependencies: babel-runtime: 6.26.0 @@ -2690,26 +2746,26 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-destructuring/6.23.0: + /babel-plugin-transform-es2015-destructuring@6.23.0: resolution: {integrity: sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-duplicate-keys/6.24.1: + /babel-plugin-transform-es2015-duplicate-keys@6.24.1: resolution: {integrity: sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-plugin-transform-es2015-for-of/6.23.0: + /babel-plugin-transform-es2015-for-of@6.23.0: resolution: {integrity: sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-function-name/6.24.1: + /babel-plugin-transform-es2015-function-name@6.24.1: resolution: {integrity: sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==} dependencies: babel-helper-function-name: 6.24.1 @@ -2719,13 +2775,13 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-literals/6.22.0: + /babel-plugin-transform-es2015-literals@6.22.0: resolution: {integrity: sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-modules-amd/6.24.1: + /babel-plugin-transform-es2015-modules-amd@6.24.1: resolution: {integrity: sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==} dependencies: babel-plugin-transform-es2015-modules-commonjs: 6.26.2 @@ -2735,7 +2791,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-modules-commonjs/6.26.2: + /babel-plugin-transform-es2015-modules-commonjs@6.26.2: resolution: {integrity: sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==} dependencies: babel-plugin-transform-strict-mode: 6.24.1 @@ -2746,7 +2802,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-modules-systemjs/6.24.1: + /babel-plugin-transform-es2015-modules-systemjs@6.24.1: resolution: {integrity: sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==} dependencies: babel-helper-hoist-variables: 6.24.1 @@ -2756,7 +2812,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-modules-umd/6.24.1: + /babel-plugin-transform-es2015-modules-umd@6.24.1: resolution: {integrity: sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==} dependencies: babel-plugin-transform-es2015-modules-amd: 6.24.1 @@ -2766,7 +2822,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-object-super/6.24.1: + /babel-plugin-transform-es2015-object-super@6.24.1: resolution: {integrity: sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==} dependencies: babel-helper-replace-supers: 6.24.1 @@ -2775,7 +2831,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-parameters/6.24.1: + /babel-plugin-transform-es2015-parameters@6.24.1: resolution: {integrity: sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==} dependencies: babel-helper-call-delegate: 6.24.1 @@ -2788,20 +2844,20 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-shorthand-properties/6.24.1: + /babel-plugin-transform-es2015-shorthand-properties@6.24.1: resolution: {integrity: sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-plugin-transform-es2015-spread/6.22.0: + /babel-plugin-transform-es2015-spread@6.22.0: resolution: {integrity: sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-sticky-regex/6.24.1: + /babel-plugin-transform-es2015-sticky-regex@6.24.1: resolution: {integrity: sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==} dependencies: babel-helper-regex: 6.26.0 @@ -2809,19 +2865,19 @@ packages: babel-types: 6.26.0 dev: true - /babel-plugin-transform-es2015-template-literals/6.22.0: + /babel-plugin-transform-es2015-template-literals@6.22.0: resolution: {integrity: sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-typeof-symbol/6.23.0: + /babel-plugin-transform-es2015-typeof-symbol@6.23.0: resolution: {integrity: sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-unicode-regex/6.24.1: + /babel-plugin-transform-es2015-unicode-regex@6.24.1: resolution: {integrity: sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==} dependencies: babel-helper-regex: 6.26.0 @@ -2829,7 +2885,7 @@ packages: regexpu-core: 2.0.0 dev: true - /babel-plugin-transform-exponentiation-operator/6.24.1: + /babel-plugin-transform-exponentiation-operator@6.24.1: resolution: {integrity: sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==} dependencies: babel-helper-builder-binary-assignment-operator-visitor: 6.24.1 @@ -2839,20 +2895,20 @@ packages: - supports-color dev: true - /babel-plugin-transform-regenerator/6.26.0: + /babel-plugin-transform-regenerator@6.26.0: resolution: {integrity: sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==} dependencies: regenerator-transform: 0.10.1 dev: true - /babel-plugin-transform-strict-mode/6.24.1: + /babel-plugin-transform-strict-mode@6.24.1: resolution: {integrity: sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-preset-env/1.7.0: + /babel-preset-env@1.7.0: resolution: {integrity: sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==} dependencies: babel-plugin-check-es2015-constants: 6.22.0 @@ -2889,7 +2945,7 @@ packages: - supports-color dev: true - /babel-register/6.26.0: + /babel-register@6.26.0: resolution: {integrity: sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==} dependencies: babel-core: 6.26.3 @@ -2903,14 +2959,14 @@ packages: - supports-color dev: true - /babel-runtime/6.26.0: + /babel-runtime@6.26.0: resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} dependencies: core-js: 2.6.12 regenerator-runtime: 0.11.1 dev: true - /babel-template/6.26.0: + /babel-template@6.26.0: resolution: {integrity: sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==} dependencies: babel-runtime: 6.26.0 @@ -2922,7 +2978,7 @@ packages: - supports-color dev: true - /babel-traverse/6.26.0: + /babel-traverse@6.26.0: resolution: {integrity: sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==} dependencies: babel-code-frame: 6.26.0 @@ -2938,7 +2994,7 @@ packages: - supports-color dev: true - /babel-types/6.26.0: + /babel-types@6.26.0: resolution: {integrity: sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==} dependencies: babel-runtime: 6.26.0 @@ -2947,7 +3003,7 @@ packages: to-fast-properties: 1.0.3 dev: true - /babelify/7.3.0: + /babelify@7.3.0: resolution: {integrity: sha512-vID8Fz6pPN5pJMdlUnNFSfrlcx5MUule4k9aKs/zbZPyXxMTcRrB0M4Tarw22L8afr8eYSWxDPYCob3TdrqtlA==} dependencies: babel-core: 6.26.3 @@ -2956,29 +3012,33 @@ packages: - supports-color dev: true - /babylon/6.18.0: + /babylon@6.18.0: resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==} hasBin: true dev: true - /backoff/2.5.0: + /backoff@2.5.0: resolution: {integrity: sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==} engines: {node: '>= 0.6'} dependencies: precond: 0.2.3 dev: true - /balanced-match/1.0.0: + /balanced-match@1.0.0: resolution: {integrity: sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==} dev: true - /base-x/3.0.9: + /base-x@3.0.9: resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} dependencies: safe-buffer: 5.2.1 dev: true - /base/0.11.2: + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /base@0.11.2: resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} engines: {node: '>=0.10.0'} dependencies: @@ -2991,20 +3051,16 @@ packages: pascalcase: 0.1.1 dev: true - /base64-js/1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true - - /bcrypt-pbkdf/1.0.2: + /bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: tweetnacl: 0.14.5 dev: true - /bech32/1.1.4: + /bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} - /better-ajv-errors/0.8.2_ajv@6.12.6: + /better-ajv-errors@0.8.2(ajv@6.12.6): resolution: {integrity: sha512-FnODTBJSQSHmJXDLPiC7ca0dC4S1HSTPv1+Hg2sm/C71i3Dj0l1jcUEaq/3OQ6MmnUveshTsUvUj65pDSr3Qow==} peerDependencies: ajv: 4.11.8 - 8 @@ -3019,52 +3075,52 @@ packages: leven: 3.1.0 dev: true - /big-integer/1.6.36: + /big-integer@1.6.36: resolution: {integrity: sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==} engines: {node: '>=0.6'} dev: true - /big-integer/1.6.51: + /big-integer@1.6.51: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} dev: true - /big.js/6.2.1: + /big.js@6.2.1: resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} dev: true - /bigint-crypto-utils/3.1.8: + /bigint-crypto-utils@3.1.8: resolution: {integrity: sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw==} engines: {node: '>=10.4.0'} dependencies: bigint-mod-arith: 3.1.2 dev: true - /bigint-mod-arith/3.1.2: + /bigint-mod-arith@3.1.2: resolution: {integrity: sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==} engines: {node: '>=10.4.0'} dev: true - /bignumber.js/7.2.1: + /bignumber.js@7.2.1: resolution: {integrity: sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==} dev: true - /bignumber.js/9.1.0: + /bignumber.js@9.1.0: resolution: {integrity: sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==} dev: true - /binary-extensions/2.2.0: + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true - /bindings/1.5.0: + /bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} dependencies: file-uri-to-path: 1.0.0 dev: true - /bip39/2.5.0: + /bip39@2.5.0: resolution: {integrity: sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==} dependencies: create-hash: 1.2.0 @@ -3074,31 +3130,31 @@ packages: unorm: 1.6.0 dev: true - /bip66/1.1.5: + /bip66@1.1.5: resolution: {integrity: sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==} dependencies: safe-buffer: 5.2.1 dev: true - /blakejs/1.2.1: + /blakejs@1.2.1: resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} dev: true - /bluebird/3.7.2: + /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} dev: true - /bn.js/4.11.6: + /bn.js@4.11.6: resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} dev: true - /bn.js/4.12.0: + /bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} - /bn.js/5.2.1: + /bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - /body-parser/1.19.0: + /body-parser@1.19.0: resolution: {integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==} engines: {node: '>= 0.8'} dependencies: @@ -3116,31 +3172,31 @@ packages: - supports-color dev: true - /boolbase/1.0.0: + /boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true - /bplist-parser/0.2.0: + /bplist-parser@0.2.0: resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} engines: {node: '>= 5.10.0'} dependencies: big-integer: 1.6.51 dev: true - /brace-expansion/1.1.11: + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.0 concat-map: 0.0.1 dev: true - /brace-expansion/2.0.1: + /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.0 dev: true - /braces/2.3.2: + /braces@2.3.2: resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} engines: {node: '>=0.10.0'} dependencies: @@ -3158,17 +3214,17 @@ packages: - supports-color dev: true - /braces/3.0.2: + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} dependencies: fill-range: 7.0.1 dev: true - /brorand/1.1.0: + /brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - /browser-level/1.0.1: + /browser-level@1.0.1: resolution: {integrity: sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==} dependencies: abstract-level: 1.0.3 @@ -3177,11 +3233,11 @@ packages: run-parallel-limit: 1.1.0 dev: true - /browser-stdout/1.3.1: + /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true - /browserify-aes/1.2.0: + /browserify-aes@1.2.0: resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} dependencies: buffer-xor: 1.0.3 @@ -3192,7 +3248,7 @@ packages: safe-buffer: 5.2.1 dev: true - /browserify-cipher/1.0.1: + /browserify-cipher@1.0.1: resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} dependencies: browserify-aes: 1.2.0 @@ -3200,7 +3256,7 @@ packages: evp_bytestokey: 1.0.3 dev: true - /browserify-des/1.0.2: + /browserify-des@1.0.2: resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} dependencies: cipher-base: 1.0.4 @@ -3209,21 +3265,21 @@ packages: safe-buffer: 5.2.1 dev: true - /browserify-rsa/4.0.1: + /browserify-rsa@4.0.1: resolution: {integrity: sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==} dependencies: bn.js: 4.12.0 randombytes: 2.1.0 dev: true - /browserify-sha3/0.0.4: + /browserify-sha3@0.0.4: resolution: {integrity: sha512-WmXX4M8lltqzMnBiPbP9KQdITknmxe4Wp3rhGfpYJst5yOeGwKkHpC0t+Ty22laH4Ltg9YO+p14p93wiipqjxA==} dependencies: js-sha3: 0.6.1 safe-buffer: 5.2.1 dev: true - /browserify-sign/4.0.4: + /browserify-sign@4.0.4: resolution: {integrity: sha512-D2ItxCwNtLcHRrOCuEDZQlIezlFyUV/N5IYz6TY1svu1noyThFuthoEjzT8ChZe3UEctqnwmykcPhet3Eiz58A==} dependencies: bn.js: 4.12.0 @@ -3235,7 +3291,7 @@ packages: parse-asn1: 5.1.5 dev: true - /browserslist/3.2.8: + /browserslist@3.2.8: resolution: {integrity: sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==} hasBin: true dependencies: @@ -3243,13 +3299,13 @@ packages: electron-to-chromium: 1.4.270 dev: true - /bs58/4.0.1: + /bs58@4.0.1: resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} dependencies: base-x: 3.0.9 dev: true - /bs58check/2.1.2: + /bs58check@2.1.2: resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} dependencies: bs58: 4.0.1 @@ -3257,25 +3313,25 @@ packages: safe-buffer: 5.2.1 dev: true - /buffer-from/1.1.2: + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true - /buffer-to-arraybuffer/0.0.5: + /buffer-to-arraybuffer@0.0.5: resolution: {integrity: sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==} dev: true - /buffer-xor/1.0.3: + /buffer-xor@1.0.3: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} dev: true - /buffer-xor/2.0.2: + /buffer-xor@2.0.2: resolution: {integrity: sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==} dependencies: safe-buffer: 5.2.1 dev: true - /buffer/4.9.2: + /buffer@4.9.2: resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} dependencies: base64-js: 1.5.1 @@ -3283,21 +3339,21 @@ packages: isarray: 1.0.0 dev: true - /buffer/5.7.1: + /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 dev: true - /buffer/6.0.3: + /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 dev: true - /bufferutil/4.0.6: + /bufferutil@4.0.6: resolution: {integrity: sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==} engines: {node: '>=6.14.2'} requiresBuild: true @@ -3305,49 +3361,49 @@ packages: node-gyp-build: 4.5.0 dev: true - /bufio/1.0.7: + /bufio@1.0.7: resolution: {integrity: sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==} engines: {node: '>=8.0.0'} dev: false - /bundle-name/3.0.0: + /bundle-name@3.0.0: resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} engines: {node: '>=12'} dependencies: run-applescript: 5.0.0 dev: true - /busboy/1.6.0: + /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} dependencies: streamsearch: 1.1.0 dev: true - /bytes/3.1.0: + /bytes@3.1.0: resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} engines: {node: '>= 0.8'} dev: true - /bytes/3.1.2: + /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} dev: true - /bytewise-core/1.2.3: + /bytewise-core@1.2.3: resolution: {integrity: sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==} dependencies: typewise-core: 1.2.0 dev: true - /bytewise/1.1.0: + /bytewise@1.1.0: resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==} dependencies: bytewise-core: 1.2.3 typewise: 1.0.3 dev: true - /cache-base/1.0.1: + /cache-base@1.0.1: resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} engines: {node: '>=0.10.0'} dependencies: @@ -3362,12 +3418,12 @@ packages: unset-value: 1.0.0 dev: true - /cacheable-lookup/6.1.0: + /cacheable-lookup@6.1.0: resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} engines: {node: '>=10.6.0'} dev: true - /cacheable-request/6.1.0: + /cacheable-request@6.1.0: resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} engines: {node: '>=8'} dependencies: @@ -3380,7 +3436,7 @@ packages: responselike: 1.0.2 dev: true - /cacheable-request/7.0.2: + /cacheable-request@7.0.2: resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} engines: {node: '>=8'} dependencies: @@ -3393,21 +3449,21 @@ packages: responselike: 2.0.1 dev: true - /cachedown/1.0.0: + /cachedown@1.0.0: resolution: {integrity: sha512-t+yVk82vQWCJF3PsWHMld+jhhjkkWjcAzz8NbFx1iULOXWl8Tm/FdM4smZNVw3MRr0X+lVTx9PKzvEn4Ng19RQ==} dependencies: abstract-leveldown: 2.7.2 lru-cache: 3.2.0 dev: true - /call-bind/1.0.2: + /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 get-intrinsic: 1.1.3 dev: true - /call-bind/1.0.5: + /call-bind@1.0.5: resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: function-bind: 1.1.2 @@ -3415,57 +3471,57 @@ packages: set-function-length: 1.1.1 dev: true - /callsites/3.1.0: + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} dev: true - /camel-case/3.0.0: + /camel-case@3.0.0: resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 dev: true - /camelcase/3.0.0: + /camelcase@3.0.0: resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} engines: {node: '>=0.10.0'} dev: true - /camelcase/4.1.0: + /camelcase@4.1.0: resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} engines: {node: '>=4'} dev: true - /camelcase/5.3.1: + /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} dev: true - /camelcase/6.3.0: + /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001414: + /caniuse-lite@1.0.30001414: resolution: {integrity: sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==} dev: true - /case/1.6.3: + /case@1.6.3: resolution: {integrity: sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==} engines: {node: '>= 0.8.0'} dev: true - /caseless/0.12.0: + /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true - /catering/2.1.1: + /catering@2.1.1: resolution: {integrity: sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==} engines: {node: '>=6'} dev: true - /cbor/5.2.0: + /cbor@5.2.0: resolution: {integrity: sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==} engines: {node: '>=6.0.0'} dependencies: @@ -3473,21 +3529,21 @@ packages: nofilter: 1.0.4 dev: true - /cbor/8.1.0: + /cbor@8.1.0: resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} engines: {node: '>=12.19'} dependencies: nofilter: 3.1.0 dev: true - /cbor/9.0.1: + /cbor@9.0.1: resolution: {integrity: sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ==} engines: {node: '>=16'} dependencies: nofilter: 3.1.0 dev: true - /chai-bn/0.2.2_bn.js@4.12.0+chai@4.3.10: + /chai-bn@0.2.2(bn.js@4.12.0)(chai@4.3.10): resolution: {integrity: sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==} peerDependencies: bn.js: ^4.11.0 @@ -3497,7 +3553,7 @@ packages: chai: 4.3.10 dev: true - /chai/4.3.10: + /chai@4.3.10: resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} engines: {node: '>=4'} dependencies: @@ -3509,7 +3565,7 @@ packages: pathval: 1.1.1 type-detect: 4.0.8 - /chalk/1.1.3: + /chalk@1.1.3: resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} engines: {node: '>=0.10.0'} dependencies: @@ -3520,7 +3576,7 @@ packages: supports-color: 2.0.0 dev: true - /chalk/2.4.2: + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} dependencies: @@ -3529,7 +3585,7 @@ packages: supports-color: 5.5.0 dev: true - /chalk/4.1.2: + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} dependencies: @@ -3537,7 +3593,7 @@ packages: supports-color: 7.2.0 dev: true - /change-case/3.0.2: + /change-case@3.0.2: resolution: {integrity: sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==} dependencies: camel-case: 3.0.0 @@ -3560,22 +3616,22 @@ packages: upper-case-first: 1.1.2 dev: true - /charenc/0.0.2: + /charenc@0.0.2: resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} dev: true - /check-error/1.0.3: + /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: get-func-name: 2.0.2 - /checkpoint-store/1.1.0: + /checkpoint-store@1.1.0: resolution: {integrity: sha512-J/NdY2WvIx654cc6LWSq/IYFFCUf75fFTgwzFnmbqyORH4MwgiQCgswLLKBGzmsyTI5V7i5bp/So6sMbDWhedg==} dependencies: functional-red-black-tree: 1.0.1 dev: true - /cheerio-select/2.1.0: + /cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} dependencies: boolbase: 1.0.0 @@ -3586,7 +3642,7 @@ packages: domutils: 3.0.1 dev: true - /cheerio/1.0.0-rc.12: + /cheerio@1.0.0-rc.12: resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} engines: {node: '>= 6'} dependencies: @@ -3599,7 +3655,7 @@ packages: parse5-htmlparser2-tree-adapter: 7.0.0 dev: true - /chokidar/3.3.0: + /chokidar@3.3.0: resolution: {integrity: sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==} engines: {node: '>= 8.10.0'} dependencies: @@ -3614,7 +3670,7 @@ packages: fsevents: 2.1.3 dev: true - /chokidar/3.5.3: + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} dependencies: @@ -3629,15 +3685,15 @@ packages: fsevents: 2.3.2 dev: true - /chownr/1.1.4: + /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} dev: true - /ci-info/2.0.0: + /ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} dev: true - /cids/0.7.5: + /cids@0.7.5: resolution: {integrity: sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==} engines: {node: '>=4.0.0', npm: '>=3.0.0'} deprecated: This module has been superseded by the multiformats module @@ -3649,18 +3705,18 @@ packages: multihashes: 0.4.21 dev: true - /cipher-base/1.0.4: + /cipher-base@1.0.4: resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 dev: true - /class-is/1.1.0: + /class-is@1.1.0: resolution: {integrity: sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==} dev: true - /class-utils/0.3.6: + /class-utils@0.3.6: resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} engines: {node: '>=0.10.0'} dependencies: @@ -3670,7 +3726,7 @@ packages: static-extend: 0.1.2 dev: true - /classic-level/1.2.0: + /classic-level@1.2.0: resolution: {integrity: sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==} engines: {node: '>=12'} requiresBuild: true @@ -3682,12 +3738,12 @@ packages: node-gyp-build: 4.5.0 dev: true - /clean-stack/2.2.0: + /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} dev: true - /cli-table3/0.5.1: + /cli-table3@0.5.1: resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} engines: {node: '>=6'} dependencies: @@ -3697,7 +3753,7 @@ packages: colors: 1.4.0 dev: true - /cli-table3/0.6.3: + /cli-table3@0.6.3: resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} engines: {node: 10.* || >= 12.*} dependencies: @@ -3706,7 +3762,7 @@ packages: '@colors/colors': 1.5.0 dev: true - /cliui/3.2.0: + /cliui@3.2.0: resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} dependencies: string-width: 1.0.2 @@ -3714,7 +3770,7 @@ packages: wrap-ansi: 2.1.0 dev: true - /cliui/5.0.0: + /cliui@5.0.0: resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} dependencies: string-width: 3.1.0 @@ -3722,7 +3778,7 @@ packages: wrap-ansi: 5.1.0 dev: true - /cliui/7.0.4: + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: string-width: 4.2.3 @@ -3730,28 +3786,28 @@ packages: wrap-ansi: 7.0.0 dev: true - /clone-response/1.0.2: + /clone-response@1.0.2: resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==} dependencies: mimic-response: 1.0.1 dev: true - /clone/2.1.2: + /clone@2.1.2: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} dev: true - /code-error-fragment/0.0.230: + /code-error-fragment@0.0.230: resolution: {integrity: sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw==} engines: {node: '>= 4'} dev: true - /code-point-at/1.1.0: + /code-point-at@1.1.0: resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} engines: {node: '>=0.10.0'} dev: true - /collection-visit/1.0.0: + /collection-visit@1.0.0: resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} engines: {node: '>=0.10.0'} dependencies: @@ -3759,44 +3815,44 @@ packages: object-visit: 1.0.1 dev: true - /color-convert/1.9.3: + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 dev: true - /color-convert/2.0.1: + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 dev: true - /color-name/1.1.3: + /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} dev: true - /color-name/1.1.4: + /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true - /colors/1.4.0: + /colors@1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} dev: true - /combined-stream/1.0.8: + /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 dev: true - /command-exists/1.2.9: + /command-exists@1.2.9: resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} dev: true - /command-line-args/4.0.7: + /command-line-args@4.0.7: resolution: {integrity: sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==} hasBin: true dependencies: @@ -3805,7 +3861,7 @@ packages: typical: 2.6.1 dev: true - /command-line-args/5.2.1: + /command-line-args@5.2.1: resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} engines: {node: '>=4.0.0'} dependencies: @@ -3815,7 +3871,7 @@ packages: typical: 4.0.0 dev: true - /command-line-usage/6.1.3: + /command-line-usage@6.1.3: resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} engines: {node: '>=8.0.0'} dependencies: @@ -3825,28 +3881,28 @@ packages: typical: 5.2.0 dev: true - /commander/10.0.1: + /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} dev: true - /commander/3.0.2: + /commander@3.0.2: resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} dev: true - /compare-versions/6.1.0: + /compare-versions@6.1.0: resolution: {integrity: sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==} dev: true - /component-emitter/1.3.0: + /component-emitter@1.3.0: resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} dev: true - /concat-map/0.0.1: + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /concat-stream/1.6.2: + /concat-stream@1.6.2: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} engines: {'0': node >= 0.8} dependencies: @@ -3856,28 +3912,28 @@ packages: typedarray: 0.0.6 dev: true - /config-chain/1.1.13: + /config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} dependencies: ini: 1.3.8 proto-list: 1.2.4 dev: true - /constant-case/2.0.0: + /constant-case@2.0.0: resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==} dependencies: snake-case: 2.1.0 upper-case: 1.1.3 dev: true - /content-disposition/0.5.3: + /content-disposition@0.5.3: resolution: {integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==} engines: {node: '>= 0.6'} dependencies: safe-buffer: 5.1.2 dev: true - /content-hash/2.5.2: + /content-hash@2.5.2: resolution: {integrity: sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==} dependencies: cids: 0.7.5 @@ -3885,65 +3941,65 @@ packages: multihashes: 0.4.21 dev: true - /content-type/1.0.4: + /content-type@1.0.4: resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} engines: {node: '>= 0.6'} dev: true - /convert-source-map/1.8.0: + /convert-source-map@1.8.0: resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} dependencies: safe-buffer: 5.1.2 dev: true - /cookie-signature/1.0.6: + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} dev: true - /cookie/0.4.0: + /cookie@0.4.0: resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==} engines: {node: '>= 0.6'} dev: true - /cookie/0.4.2: + /cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} dev: true - /cookiejar/2.1.2: + /cookiejar@2.1.2: resolution: {integrity: sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==} dev: true - /copy-descriptor/0.1.1: + /copy-descriptor@0.1.1: resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} engines: {node: '>=0.10.0'} dev: true - /core-js-pure/3.25.3: + /core-js-pure@3.25.3: resolution: {integrity: sha512-T/7qvgv70MEvRkZ8p6BasLZmOVYKzOaWNBEHAU8FmveCJkl4nko2quqPQOmy6AJIp5MBanhz9no3A94NoRb0XA==} requiresBuild: true dev: true - /core-js/2.6.12: + /core-js@2.6.12: resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. requiresBuild: true dev: true - /core-js/3.30.1: + /core-js@3.30.1: resolution: {integrity: sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==} requiresBuild: true dev: true - /core-util-is/1.0.2: + /core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} dev: true - /core-util-is/1.0.3: + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true - /cors/2.8.5: + /cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} dependencies: @@ -3951,7 +4007,7 @@ packages: vary: 1.1.2 dev: true - /cosmiconfig/8.2.0: + /cosmiconfig@8.2.0: resolution: {integrity: sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==} engines: {node: '>=14'} dependencies: @@ -3961,20 +4017,20 @@ packages: path-type: 4.0.0 dev: true - /crc-32/1.2.2: + /crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} hasBin: true dev: true - /create-ecdh/4.0.3: + /create-ecdh@4.0.3: resolution: {integrity: sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==} dependencies: bn.js: 4.12.0 elliptic: 6.5.4 dev: true - /create-hash/1.2.0: + /create-hash@1.2.0: resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} dependencies: cipher-base: 1.0.4 @@ -3984,7 +4040,7 @@ packages: sha.js: 2.4.11 dev: true - /create-hmac/1.1.7: + /create-hmac@1.1.7: resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} dependencies: cipher-base: 1.0.4 @@ -3995,11 +4051,11 @@ packages: sha.js: 2.4.11 dev: true - /create-require/1.1.1: + /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true - /cross-fetch/2.2.6: + /cross-fetch@2.2.6: resolution: {integrity: sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA==} dependencies: node-fetch: 2.6.7 @@ -4008,7 +4064,7 @@ packages: - encoding dev: true - /cross-fetch/3.1.5: + /cross-fetch@3.1.5: resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} dependencies: node-fetch: 2.6.7 @@ -4016,7 +4072,7 @@ packages: - encoding dev: true - /cross-spawn/6.0.5: + /cross-spawn@6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} dependencies: @@ -4027,7 +4083,7 @@ packages: which: 1.3.1 dev: true - /cross-spawn/7.0.3: + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} dependencies: @@ -4036,11 +4092,11 @@ packages: which: 2.0.2 dev: true - /crypt/0.0.2: + /crypt@0.0.2: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} dev: true - /crypto-addr-codec/0.1.7: + /crypto-addr-codec@0.1.7: resolution: {integrity: sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==} dependencies: base-x: 3.0.9 @@ -4052,7 +4108,7 @@ packages: sha3: 2.1.4 dev: true - /crypto-browserify/3.12.0: + /crypto-browserify@3.12.0: resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} dependencies: browserify-cipher: 1.0.1 @@ -4068,7 +4124,7 @@ packages: randomfill: 1.0.4 dev: true - /css-select/5.1.0: + /css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} dependencies: boolbase: 1.0.0 @@ -4078,30 +4134,30 @@ packages: nth-check: 2.1.1 dev: true - /css-what/6.1.0: + /css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} dev: true - /d/1.0.1: + /d@1.0.1: resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} dependencies: es5-ext: 0.10.62 type: 1.2.0 dev: true - /dashdash/1.14.1: + /dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} dependencies: assert-plus: 1.0.0 dev: true - /death/1.1.0: + /death@1.1.0: resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} dev: true - /debug/2.6.9: + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: supports-color: '*' @@ -4112,19 +4168,7 @@ packages: ms: 2.0.0 dev: true - /debug/3.2.6: - resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} - deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - - /debug/3.2.6_supports-color@6.0.0: + /debug@3.2.6(supports-color@6.0.0): resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) peerDependencies: @@ -4137,7 +4181,7 @@ packages: supports-color: 6.0.0 dev: true - /debug/3.2.7: + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: supports-color: '*' @@ -4148,19 +4192,7 @@ packages: ms: 2.1.3 dev: true - /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /debug/4.3.4_supports-color@8.1.1: + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -4173,49 +4205,49 @@ packages: supports-color: 8.1.1 dev: true - /decamelize/1.2.0: + /decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} dev: true - /decamelize/4.0.0: + /decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} dev: true - /decode-uri-component/0.2.0: + /decode-uri-component@0.2.0: resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} engines: {node: '>=0.10'} dev: true - /decompress-response/3.3.0: + /decompress-response@3.3.0: resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} engines: {node: '>=4'} dependencies: mimic-response: 1.0.1 dev: true - /decompress-response/6.0.0: + /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 dev: true - /deep-eql/4.1.3: + /deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} dependencies: type-detect: 4.0.8 - /deep-equal-in-any-order/2.0.6: + /deep-equal-in-any-order@2.0.6: resolution: {integrity: sha512-RfnWHQzph10YrUjvWwhd15Dne8ciSJcZ3U6OD7owPwiVwsdE5IFSoZGg8rlwJD11ES+9H5y8j3fCofviRHOqLQ==} dependencies: lodash.mapvalues: 4.6.0 sort-any: 2.0.0 dev: true - /deep-equal/1.1.1: + /deep-equal@1.1.1: resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} dependencies: is-arguments: 1.0.4 @@ -4226,16 +4258,16 @@ packages: regexp.prototype.flags: 1.5.1 dev: true - /deep-extend/0.6.0: + /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} dev: true - /deep-is/0.1.4: + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true - /default-browser-id/3.0.0: + /default-browser-id@3.0.0: resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} engines: {node: '>=12'} dependencies: @@ -4243,7 +4275,7 @@ packages: untildify: 4.0.0 dev: true - /default-browser/4.0.0: + /default-browser@4.0.0: resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} engines: {node: '>=14.16'} dependencies: @@ -4253,22 +4285,22 @@ packages: titleize: 3.0.0 dev: true - /defer-to-connect/1.1.1: + /defer-to-connect@1.1.1: resolution: {integrity: sha512-J7thop4u3mRTkYRQ+Vpfwy2G5Ehoy82I14+14W4YMDLKdWloI9gSzRbV30s/NckQGVJtPkWNcW4oMAUigTdqiQ==} dev: true - /defer-to-connect/2.0.1: + /defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} dev: true - /deferred-leveldown/1.2.2: + /deferred-leveldown@1.2.2: resolution: {integrity: sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==} dependencies: abstract-leveldown: 2.6.3 dev: true - /deferred-leveldown/4.0.2: + /deferred-leveldown@4.0.2: resolution: {integrity: sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==} engines: {node: '>=6'} dependencies: @@ -4276,7 +4308,7 @@ packages: inherits: 2.0.4 dev: true - /define-data-property/1.1.1: + /define-data-property@1.1.1: resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} dependencies: @@ -4285,12 +4317,12 @@ packages: has-property-descriptors: 1.0.0 dev: true - /define-lazy-prop/3.0.0: + /define-lazy-prop@3.0.0: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} dev: true - /define-properties/1.1.4: + /define-properties@1.1.4: resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} engines: {node: '>= 0.4'} dependencies: @@ -4298,7 +4330,7 @@ packages: object-keys: 1.1.1 dev: true - /define-properties/1.2.1: + /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: @@ -4307,21 +4339,21 @@ packages: object-keys: 1.1.1 dev: true - /define-property/0.2.5: + /define-property@0.2.5: resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} engines: {node: '>=0.10.0'} dependencies: is-descriptor: 0.1.6 dev: true - /define-property/1.0.0: + /define-property@1.0.0: resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} engines: {node: '>=0.10.0'} dependencies: is-descriptor: 1.0.2 dev: true - /define-property/2.0.2: + /define-property@2.0.2: resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} engines: {node: '>=0.10.0'} dependencies: @@ -4329,16 +4361,16 @@ packages: isobject: 3.0.1 dev: true - /defined/1.0.0: + /defined@1.0.0: resolution: {integrity: sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==} dev: true - /delayed-stream/1.0.0: + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} dev: true - /delete-empty/3.0.0: + /delete-empty@3.0.0: resolution: {integrity: sha512-ZUyiwo76W+DYnKsL3Kim6M/UOavPdBJgDYWOmuQhYaZvJH0AXAHbUNyEDtRbBra8wqqr686+63/0azfEk1ebUQ==} engines: {node: '>=10'} hasBin: true @@ -4349,40 +4381,40 @@ packages: rimraf: 2.7.1 dev: true - /depd/1.1.2: + /depd@1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} dev: true - /depd/2.0.0: + /depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} dev: true - /des.js/1.0.1: + /des.js@1.0.1: resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 dev: true - /destroy/1.0.4: + /destroy@1.0.4: resolution: {integrity: sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==} dev: true - /detect-indent/4.0.0: + /detect-indent@4.0.0: resolution: {integrity: sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==} engines: {node: '>=0.10.0'} dependencies: repeating: 2.0.1 dev: true - /detect-indent/5.0.0: + /detect-indent@5.0.0: resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} engines: {node: '>=4'} dev: true - /detect-port/1.3.0: + /detect-port@1.3.0: resolution: {integrity: sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==} engines: {node: '>= 4.2.1'} hasBin: true @@ -4393,22 +4425,22 @@ packages: - supports-color dev: true - /diff/3.5.0: + /diff@3.5.0: resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} engines: {node: '>=0.3.1'} dev: true - /diff/4.0.2: + /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} dev: true - /diff/5.0.0: + /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} dev: true - /diffie-hellman/5.0.3: + /diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} dependencies: bn.js: 4.12.0 @@ -4416,27 +4448,27 @@ packages: randombytes: 2.1.0 dev: true - /difflib/0.2.4: + /difflib@0.2.4: resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} dependencies: heap: 0.2.6 dev: true - /dir-glob/3.0.1: + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} dependencies: path-type: 4.0.0 dev: true - /doctrine/3.0.0: + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 dev: true - /dom-serializer/2.0.0: + /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: domelementtype: 2.3.0 @@ -4444,22 +4476,22 @@ packages: entities: 4.4.0 dev: true - /dom-walk/0.1.1: + /dom-walk@0.1.1: resolution: {integrity: sha512-8CGZnLAdYN/o0SHjlP3nLvliHpi2f/prVU63/Hc4DTDpBgsNVAJekegjFtxfZ7NTUEDzHUByjX1gT3eYakIKqg==} dev: true - /domelementtype/2.3.0: + /domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} dev: true - /domhandler/5.0.3: + /domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} dependencies: domelementtype: 2.3.0 dev: true - /domutils/3.0.1: + /domutils@3.0.1: resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} dependencies: dom-serializer: 2.0.0 @@ -4467,20 +4499,20 @@ packages: domhandler: 5.0.3 dev: true - /dot-case/2.1.1: + /dot-case@2.1.1: resolution: {integrity: sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==} dependencies: no-case: 2.3.2 dev: true - /dotignore/0.1.2: + /dotignore@0.1.2: resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==} hasBin: true dependencies: minimatch: 3.1.2 dev: true - /drbg.js/1.0.1: + /drbg.js@1.0.1: resolution: {integrity: sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==} engines: {node: '>=0.10'} dependencies: @@ -4489,26 +4521,26 @@ packages: create-hmac: 1.1.7 dev: true - /duplexer3/0.1.4: + /duplexer3@0.1.4: resolution: {integrity: sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==} dev: true - /ecc-jsbn/0.1.2: + /ecc-jsbn@0.1.2: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} dependencies: jsbn: 0.1.1 safer-buffer: 2.1.2 dev: true - /ee-first/1.1.1: + /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: true - /electron-to-chromium/1.4.270: + /electron-to-chromium@1.4.270: resolution: {integrity: sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg==} dev: true - /elliptic/6.5.4: + /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} dependencies: bn.js: 4.12.0 @@ -4519,20 +4551,20 @@ packages: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - /emoji-regex/7.0.3: + /emoji-regex@7.0.3: resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} dev: true - /emoji-regex/8.0.0: + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true - /encodeurl/1.0.2: + /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} dev: true - /encoding-down/5.0.4: + /encoding-down@5.0.4: resolution: {integrity: sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==} engines: {node: '>=6'} dependencies: @@ -4543,49 +4575,49 @@ packages: xtend: 4.0.2 dev: true - /encoding/0.1.13: + /encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} dependencies: iconv-lite: 0.6.3 dev: true - /end-of-stream/1.4.4: + /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 dev: true - /enquirer/2.3.6: + /enquirer@2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} dependencies: ansi-colors: 4.1.3 dev: true - /entities/4.4.0: + /entities@4.4.0: resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} engines: {node: '>=0.12'} dev: true - /env-paths/2.2.1: + /env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} dev: true - /errno/0.1.8: + /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true dependencies: prr: 1.0.1 dev: true - /error-ex/1.3.2: + /error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 dev: true - /es-abstract/1.20.3: + /es-abstract@1.20.3: resolution: {integrity: sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw==} engines: {node: '>= 0.4'} dependencies: @@ -4615,7 +4647,7 @@ packages: unbox-primitive: 1.0.2 dev: true - /es-abstract/1.22.3: + /es-abstract@1.22.3: resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} dependencies: @@ -4660,11 +4692,11 @@ packages: which-typed-array: 1.1.13 dev: true - /es-array-method-boxes-properly/1.0.0: + /es-array-method-boxes-properly@1.0.0: resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} dev: true - /es-set-tostringtag/2.0.2: + /es-set-tostringtag@2.0.2: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: @@ -4673,13 +4705,13 @@ packages: hasown: 2.0.0 dev: true - /es-shim-unscopables/1.0.2: + /es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: hasown: 2.0.0 dev: true - /es-to-primitive/1.2.1: + /es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} dependencies: @@ -4688,7 +4720,7 @@ packages: is-symbol: 1.0.3 dev: true - /es5-ext/0.10.62: + /es5-ext@0.10.62: resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} engines: {node: '>=0.10'} requiresBuild: true @@ -4698,7 +4730,7 @@ packages: next-tick: 1.1.0 dev: true - /es6-iterator/2.0.3: + /es6-iterator@2.0.3: resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} dependencies: d: 1.0.1 @@ -4706,37 +4738,37 @@ packages: es6-symbol: 3.1.3 dev: true - /es6-promise/4.2.8: + /es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} dev: true - /es6-symbol/3.1.3: + /es6-symbol@3.1.3: resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} dependencies: d: 1.0.1 ext: 1.4.0 dev: true - /escalade/3.1.1: + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} dev: true - /escape-html/1.0.3: + /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} dev: true - /escape-string-regexp/1.0.5: + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} dev: true - /escape-string-regexp/4.0.0: + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true - /escodegen/1.8.1: + /escodegen@1.8.1: resolution: {integrity: sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==} engines: {node: '>=0.12.0'} hasBin: true @@ -4749,7 +4781,7 @@ packages: source-map: 0.2.0 dev: true - /eslint-config-prettier/9.1.0_eslint@8.55.0: + /eslint-config-prettier@9.1.0(eslint@8.55.0): resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: @@ -4758,7 +4790,7 @@ packages: eslint: 8.55.0 dev: true - /eslint-plugin-prettier/5.0.1_34cv2ng2ecdkhobougxv63nlsu: + /eslint-plugin-prettier@5.0.1(eslint-config-prettier@9.1.0)(eslint@8.55.0)(prettier@3.2.1): resolution: {integrity: sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -4773,13 +4805,13 @@ packages: optional: true dependencies: eslint: 8.55.0 - eslint-config-prettier: 9.1.0_eslint@8.55.0 + eslint-config-prettier: 9.1.0(eslint@8.55.0) prettier: 3.2.1 prettier-linter-helpers: 1.0.0 synckit: 0.8.5 dev: true - /eslint-scope/7.2.2: + /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -4787,17 +4819,17 @@ packages: estraverse: 5.3.0 dev: true - /eslint-visitor-keys/3.4.3: + /eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.55.0: + /eslint@8.55.0: resolution: {integrity: sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.55.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) '@eslint-community/regexpp': 4.9.1 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.55.0 @@ -4808,7 +4840,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -4839,62 +4871,62 @@ packages: - supports-color dev: true - /espree/9.6.1: + /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.10.0 - acorn-jsx: 5.3.2_acorn@8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) eslint-visitor-keys: 3.4.3 dev: true - /esprima/2.7.3: + /esprima@2.7.3: resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==} engines: {node: '>=0.10.0'} hasBin: true dev: true - /esprima/4.0.1: + /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true dev: true - /esquery/1.5.0: + /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 dev: true - /esrecurse/4.3.0: + /esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 dev: true - /estraverse/1.9.3: + /estraverse@1.9.3: resolution: {integrity: sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==} engines: {node: '>=0.10.0'} dev: true - /estraverse/5.3.0: + /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} dev: true - /esutils/2.0.3: + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} dev: true - /etag/1.8.1: + /etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} dev: true - /eth-block-tracker/3.0.1: + /eth-block-tracker@3.0.1: resolution: {integrity: sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==} dependencies: eth-query: 2.1.2 @@ -4908,14 +4940,14 @@ packages: - supports-color dev: true - /eth-ens-namehash/2.0.8: + /eth-ens-namehash@2.0.8: resolution: {integrity: sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==} dependencies: idna-uts46-hx: 2.3.1 js-sha3: 0.5.7 dev: true - /eth-gas-reporter/0.2.25: + /eth-gas-reporter@0.2.25: resolution: {integrity: sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==} peerDependencies: '@codechecks/client': ^0.1.0 @@ -4935,12 +4967,12 @@ packages: mocha: 7.2.0 req-cwd: 2.0.0 request: 2.88.2 - request-promise-native: 1.0.9_request@2.88.2 + request-promise-native: 1.0.9(request@2.88.2) sha1: 1.1.1 sync-request: 6.1.0 dev: true - /eth-json-rpc-infura/3.2.1: + /eth-json-rpc-infura@3.2.1: resolution: {integrity: sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. dependencies: @@ -4953,7 +4985,7 @@ packages: - supports-color dev: true - /eth-json-rpc-middleware/1.6.0: + /eth-json-rpc-middleware@1.6.0: resolution: {integrity: sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==} dependencies: async: 2.6.3 @@ -4973,7 +5005,7 @@ packages: - supports-color dev: true - /eth-lib/0.1.29: + /eth-lib@0.1.29: resolution: {integrity: sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==} dependencies: bn.js: 4.12.0 @@ -4988,7 +5020,7 @@ packages: - utf-8-validate dev: true - /eth-lib/0.2.8: + /eth-lib@0.2.8: resolution: {integrity: sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==} dependencies: bn.js: 4.12.0 @@ -4996,14 +5028,14 @@ packages: xhr-request-promise: 0.1.2 dev: true - /eth-query/2.1.2: + /eth-query@2.1.2: resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} dependencies: json-rpc-random-id: 1.0.1 xtend: 4.0.2 dev: true - /eth-sig-util/1.4.2: + /eth-sig-util@1.4.2: resolution: {integrity: sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw==} deprecated: Deprecated in favor of '@metamask/eth-sig-util' dependencies: @@ -5011,7 +5043,7 @@ packages: ethereumjs-util: 5.2.1 dev: true - /eth-sig-util/3.0.0: + /eth-sig-util@3.0.0: resolution: {integrity: sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ==} deprecated: Deprecated in favor of '@metamask/eth-sig-util' dependencies: @@ -5023,7 +5055,7 @@ packages: tweetnacl-util: 0.15.1 dev: true - /eth-tx-summary/3.2.4: + /eth-tx-summary@3.2.4: resolution: {integrity: sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==} dependencies: async: 2.6.3 @@ -5038,7 +5070,7 @@ packages: through2: 2.0.5 dev: true - /ethashjs/0.0.8: + /ethashjs@0.0.8: resolution: {integrity: sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==} deprecated: 'New package name format for new versions: @ethereumjs/ethash. Please update.' dependencies: @@ -5048,21 +5080,21 @@ packages: miller-rabin: 4.0.1 dev: true - /ethereum-bloom-filters/1.0.10: + /ethereum-bloom-filters@1.0.10: resolution: {integrity: sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==} dependencies: js-sha3: 0.8.0 dev: true - /ethereum-common/0.0.18: + /ethereum-common@0.0.18: resolution: {integrity: sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ==} dev: true - /ethereum-common/0.2.0: + /ethereum-common@0.2.0: resolution: {integrity: sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==} dev: true - /ethereum-cryptography/0.1.3: + /ethereum-cryptography@0.1.3: resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} dependencies: '@types/pbkdf2': 3.1.0 @@ -5082,7 +5114,7 @@ packages: setimmediate: 1.0.5 dev: true - /ethereum-cryptography/1.1.2: + /ethereum-cryptography@1.1.2: resolution: {integrity: sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==} dependencies: '@noble/hashes': 1.1.2 @@ -5091,13 +5123,13 @@ packages: '@scure/bip39': 1.1.0 dev: true - /ethereum-waffle/3.4.4_typescript@5.3.3: + /ethereum-waffle@3.4.4(typescript@5.3.3): resolution: {integrity: sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==} engines: {node: '>=10.0'} hasBin: true dependencies: '@ethereum-waffle/chai': 3.4.4 - '@ethereum-waffle/compiler': 3.4.4_typescript@5.3.3 + '@ethereum-waffle/compiler': 3.4.4(typescript@5.3.3) '@ethereum-waffle/mock-contract': 3.4.4 '@ethereum-waffle/provider': 3.4.4 ethers: 5.7.2 @@ -5109,21 +5141,21 @@ packages: - utf-8-validate dev: true - /ethereumjs-abi/0.6.5: + /ethereumjs-abi@0.6.5: resolution: {integrity: sha512-rCjJZ/AE96c/AAZc6O3kaog4FhOsAViaysBxqJNy2+LHP0ttH0zkZ7nXdVHOAyt6lFwLO0nlCwWszysG/ao1+g==} dependencies: bn.js: 4.12.0 ethereumjs-util: 4.5.0 dev: true - /ethereumjs-abi/0.6.8: + /ethereumjs-abi@0.6.8: resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} dependencies: bn.js: 4.12.0 ethereumjs-util: 6.2.1 dev: true - /ethereumjs-account/2.0.5: + /ethereumjs-account@2.0.5: resolution: {integrity: sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==} dependencies: ethereumjs-util: 5.2.1 @@ -5131,7 +5163,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-account/3.0.0: + /ethereumjs-account@3.0.0: resolution: {integrity: sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==} deprecated: Please use Util.Account class found on package ethereumjs-util@^7.0.6 https://github.com/ethereumjs/ethereumjs-util/releases/tag/v7.0.6 dependencies: @@ -5140,7 +5172,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-block/1.7.1: + /ethereumjs-block@1.7.1: resolution: {integrity: sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==} deprecated: 'New package name format for new versions: @ethereumjs/block. Please update.' dependencies: @@ -5151,7 +5183,7 @@ packages: merkle-patricia-tree: 2.3.2 dev: true - /ethereumjs-block/2.2.2: + /ethereumjs-block@2.2.2: resolution: {integrity: sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==} deprecated: 'New package name format for new versions: @ethereumjs/block. Please update.' dependencies: @@ -5162,7 +5194,7 @@ packages: merkle-patricia-tree: 2.3.2 dev: true - /ethereumjs-blockchain/4.0.4: + /ethereumjs-blockchain@4.0.4: resolution: {integrity: sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==} deprecated: 'New package name format for new versions: @ethereumjs/blockchain. Please update.' dependencies: @@ -5178,12 +5210,12 @@ packages: semaphore: 1.1.0 dev: true - /ethereumjs-common/1.5.0: + /ethereumjs-common@1.5.0: resolution: {integrity: sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ==} deprecated: 'New package name format for new versions: @ethereumjs/common. Please update.' dev: true - /ethereumjs-tx/1.3.7: + /ethereumjs-tx@1.3.7: resolution: {integrity: sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==} deprecated: 'New package name format for new versions: @ethereumjs/tx. Please update.' dependencies: @@ -5191,7 +5223,7 @@ packages: ethereumjs-util: 5.2.1 dev: true - /ethereumjs-tx/2.1.2: + /ethereumjs-tx@2.1.2: resolution: {integrity: sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==} deprecated: 'New package name format for new versions: @ethereumjs/tx. Please update.' dependencies: @@ -5199,7 +5231,7 @@ packages: ethereumjs-util: 6.2.1 dev: true - /ethereumjs-util/4.5.0: + /ethereumjs-util@4.5.0: resolution: {integrity: sha512-gT1zBY8aQKkexYu7XNeBZBnJsRLo+sWD1XWRLJOaDSz49/9kCOs6ERP52Bw/TA4uaVFKpM+O8ebWy44Ib5B6xw==} dependencies: bn.js: 4.12.0 @@ -5209,7 +5241,7 @@ packages: secp256k1: 3.7.1 dev: true - /ethereumjs-util/5.2.1: + /ethereumjs-util@5.2.1: resolution: {integrity: sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==} dependencies: bn.js: 4.12.0 @@ -5221,7 +5253,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-util/6.2.1: + /ethereumjs-util@6.2.1: resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} dependencies: '@types/bn.js': 4.11.6 @@ -5233,7 +5265,7 @@ packages: rlp: 2.2.7 dev: true - /ethereumjs-util/7.1.5: + /ethereumjs-util@7.1.5: resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} engines: {node: '>=10.0.0'} dependencies: @@ -5244,7 +5276,7 @@ packages: rlp: 2.2.7 dev: true - /ethereumjs-vm/2.6.0: + /ethereumjs-vm@2.6.0: resolution: {integrity: sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==} deprecated: 'New package name format for new versions: @ethereumjs/vm. Please update.' dependencies: @@ -5261,7 +5293,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-vm/4.2.0: + /ethereumjs-vm@4.2.0: resolution: {integrity: sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA==} deprecated: 'New package name format for new versions: @ethereumjs/vm. Please update.' dependencies: @@ -5282,7 +5314,7 @@ packages: util.promisify: 1.1.1 dev: true - /ethereumjs-wallet/0.6.5: + /ethereumjs-wallet@0.6.5: resolution: {integrity: sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==} requiresBuild: true dependencies: @@ -5298,7 +5330,7 @@ packages: dev: true optional: true - /ethers/4.0.49: + /ethers@4.0.49: resolution: {integrity: sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==} dependencies: aes-js: 3.0.0 @@ -5312,7 +5344,7 @@ packages: xmlhttprequest: 1.8.0 dev: true - /ethers/5.7.2: + /ethers@5.7.2: resolution: {integrity: sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==} dependencies: '@ethersproject/abi': 5.7.0 @@ -5349,7 +5381,7 @@ packages: - bufferutil - utf-8-validate - /ethjs-abi/0.2.1: + /ethjs-abi@0.2.1: resolution: {integrity: sha512-g2AULSDYI6nEJyJaEVEXtTimRY2aPC2fi7ddSy0W+LXvEVL8Fe1y76o43ecbgdUKwZD+xsmEgX1yJr1Ia3r1IA==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -5358,7 +5390,7 @@ packages: number-to-bn: 1.7.0 dev: true - /ethjs-unit/0.1.6: + /ethjs-unit@0.1.6: resolution: {integrity: sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -5366,7 +5398,7 @@ packages: number-to-bn: 1.7.0 dev: true - /ethjs-util/0.1.6: + /ethjs-util@0.1.6: resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -5374,23 +5406,23 @@ packages: strip-hex-prefix: 1.0.0 dev: true - /eventemitter3/4.0.4: + /eventemitter3@4.0.4: resolution: {integrity: sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==} dev: true - /events/3.3.0: + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} dev: true - /evp_bytestokey/1.0.3: + /evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} dependencies: md5.js: 1.3.5 safe-buffer: 5.2.1 dev: true - /execa/5.1.1: + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} dependencies: @@ -5405,7 +5437,7 @@ packages: strip-final-newline: 2.0.0 dev: true - /execa/7.2.0: + /execa@7.2.0: resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} dependencies: @@ -5420,7 +5452,7 @@ packages: strip-final-newline: 3.0.0 dev: true - /expand-brackets/2.1.4: + /expand-brackets@2.1.4: resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} engines: {node: '>=0.10.0'} dependencies: @@ -5435,7 +5467,7 @@ packages: - supports-color dev: true - /express/4.17.1: + /express@4.17.1: resolution: {integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==} engines: {node: '>= 0.10.0'} dependencies: @@ -5473,20 +5505,20 @@ packages: - supports-color dev: true - /ext/1.4.0: + /ext@1.4.0: resolution: {integrity: sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==} dependencies: type: 2.0.0 dev: true - /extend-shallow/2.0.1: + /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} dependencies: is-extendable: 0.1.1 dev: true - /extend-shallow/3.0.2: + /extend-shallow@3.0.2: resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} engines: {node: '>=0.10.0'} dependencies: @@ -5494,11 +5526,11 @@ packages: is-extendable: 1.0.1 dev: true - /extend/3.0.2: + /extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true - /extglob/2.0.4: + /extglob@2.0.4: resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} engines: {node: '>=0.10.0'} dependencies: @@ -5514,42 +5546,42 @@ packages: - supports-color dev: true - /extsprintf/1.3.0: + /extsprintf@1.3.0: resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} engines: {'0': node >=0.6.0} dev: true - /extsprintf/1.4.0: + /extsprintf@1.4.0: resolution: {integrity: sha512-6NW8DZ8pWBc5NbGYUiqqccj9dXnuSzilZYqprdKJBZsQodGH9IyUoFOGxIWVDcBzHMb8ET24aqx9p66tZEWZkA==} engines: {'0': node >=0.6.0} dev: true - /fake-merkle-patricia-tree/1.0.1: + /fake-merkle-patricia-tree@1.0.1: resolution: {integrity: sha512-Tgq37lkc9pUIgIKw5uitNUKcgcYL3R6JvXtKQbOf/ZSavXbidsksgp/pAY6p//uhw0I4yoMsvTSovvVIsk/qxA==} dependencies: checkpoint-store: 1.1.0 dev: true - /fast-base64-decode/1.0.0: + /fast-base64-decode@1.0.0: resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} dev: true - /fast-check/3.1.1: + /fast-check@3.1.1: resolution: {integrity: sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA==} engines: {node: '>=8.0.0'} dependencies: pure-rand: 5.0.3 dev: true - /fast-deep-equal/3.1.3: + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true - /fast-diff/1.2.0: + /fast-diff@1.2.0: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} dev: true - /fast-glob/3.3.1: + /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} dependencies: @@ -5560,38 +5592,38 @@ packages: micromatch: 4.0.5 dev: true - /fast-json-stable-stringify/2.1.0: + /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true - /fast-levenshtein/2.0.6: + /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true - /fastq/1.6.0: + /fastq@1.6.0: resolution: {integrity: sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==} dependencies: reusify: 1.0.4 dev: true - /fetch-ponyfill/4.1.0: + /fetch-ponyfill@4.1.0: resolution: {integrity: sha512-knK9sGskIg2T7OnYLdZ2hZXn0CtDrAIBxYQLpmEf0BqfdWnwmM1weccUl5+4EdA44tzNSFAuxITPbXtPehUB3g==} dependencies: node-fetch: 1.7.3 dev: true - /file-entry-cache/6.0.1: + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.0.4 dev: true - /file-uri-to-path/1.0.0: + /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} dev: true - /fill-range/4.0.0: + /fill-range@4.0.0: resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} engines: {node: '>=0.10.0'} dependencies: @@ -5601,14 +5633,14 @@ packages: to-regex-range: 2.1.1 dev: true - /fill-range/7.0.1: + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 dev: true - /finalhandler/1.1.2: + /finalhandler@1.1.2: resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} engines: {node: '>= 0.8'} dependencies: @@ -5623,7 +5655,7 @@ packages: - supports-color dev: true - /find-replace/1.0.3: + /find-replace@1.0.3: resolution: {integrity: sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==} engines: {node: '>=4.0.0'} dependencies: @@ -5631,14 +5663,14 @@ packages: test-value: 2.1.0 dev: true - /find-replace/3.0.0: + /find-replace@3.0.0: resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} engines: {node: '>=4.0.0'} dependencies: array-back: 3.1.0 dev: true - /find-up/1.1.2: + /find-up@1.1.2: resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} engines: {node: '>=0.10.0'} dependencies: @@ -5646,21 +5678,21 @@ packages: pinkie-promise: 2.0.1 dev: true - /find-up/2.1.0: + /find-up@2.1.0: resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} engines: {node: '>=4'} dependencies: locate-path: 2.0.0 dev: true - /find-up/3.0.0: + /find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} dependencies: locate-path: 3.0.0 dev: true - /find-up/4.1.0: + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} dependencies: @@ -5668,7 +5700,7 @@ packages: path-exists: 4.0.0 dev: true - /find-up/5.0.0: + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} dependencies: @@ -5676,7 +5708,7 @@ packages: path-exists: 4.0.0 dev: true - /find-yarn-workspace-root/1.2.1: + /find-yarn-workspace-root@1.2.1: resolution: {integrity: sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==} dependencies: fs-extra: 4.0.3 @@ -5685,13 +5717,13 @@ packages: - supports-color dev: true - /find-yarn-workspace-root/2.0.0: + /find-yarn-workspace-root@2.0.0: resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} dependencies: micromatch: 4.0.5 dev: true - /flat-cache/3.0.4: + /flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: @@ -5699,27 +5731,27 @@ packages: rimraf: 3.0.2 dev: true - /flat/4.1.1: + /flat@4.1.1: resolution: {integrity: sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==} hasBin: true dependencies: is-buffer: 2.0.5 dev: true - /flat/5.0.2: + /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true dev: true - /flatted/3.2.7: + /flatted@3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true - /flow-stoplight/1.0.0: + /flow-stoplight@1.0.0: resolution: {integrity: sha512-rDjbZUKpN8OYhB0IE/vY/I8UWO/602IIJEU/76Tv4LvYnwHCk0BCsvz4eRr9n+FQcri7L5cyaXOo0+/Kh4HisA==} dev: true - /follow-redirects/1.15.2_debug@4.3.4: + /follow-redirects@1.15.2(debug@4.3.4): resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} engines: {node: '>=4.0'} peerDependencies: @@ -5728,33 +5760,33 @@ packages: debug: optional: true dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) dev: true - /for-each/0.3.3: + /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: is-callable: 1.2.7 dev: true - /for-in/1.0.2: + /for-in@1.0.2: resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} engines: {node: '>=0.10.0'} dev: true - /foreach/2.0.5: + /foreach@2.0.5: resolution: {integrity: sha512-ZBbtRiapkZYLsqoPyZOR+uPfto0GRMNQN1GwzZtZt7iZvPPbDDQV0JF5Hx4o/QFQ5c0vyuoZ98T8RSBbopzWtA==} dev: true - /forever-agent/0.6.1: + /forever-agent@0.6.1: resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} dev: true - /form-data-encoder/1.7.1: + /form-data-encoder@1.7.1: resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==} dev: true - /form-data/2.3.3: + /form-data@2.3.3: resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} engines: {node: '>= 0.12'} dependencies: @@ -5763,7 +5795,7 @@ packages: mime-types: 2.1.27 dev: true - /form-data/3.0.1: + /form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} dependencies: @@ -5772,7 +5804,7 @@ packages: mime-types: 2.1.27 dev: true - /form-data/4.0.0: + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} dependencies: @@ -5781,28 +5813,28 @@ packages: mime-types: 2.1.27 dev: true - /forwarded/0.1.2: + /forwarded@0.1.2: resolution: {integrity: sha512-Ua9xNhH0b8pwE3yRbFfXJvfdWF0UHNCdeyb2sbi9Ul/M+r3PTdrz7Cv4SCfZRMjmzEM9PhraqfZFbGTIg3OMyA==} engines: {node: '>= 0.6'} dev: true - /fp-ts/1.19.3: + /fp-ts@1.19.3: resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} dev: true - /fragment-cache/0.2.1: + /fragment-cache@0.2.1: resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} engines: {node: '>=0.10.0'} dependencies: map-cache: 0.2.2 dev: true - /fresh/0.5.2: + /fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} dev: true - /fs-extra/0.30.0: + /fs-extra@0.30.0: resolution: {integrity: sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==} dependencies: graceful-fs: 4.2.10 @@ -5812,7 +5844,7 @@ packages: rimraf: 2.7.1 dev: true - /fs-extra/4.0.3: + /fs-extra@4.0.3: resolution: {integrity: sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==} dependencies: graceful-fs: 4.2.10 @@ -5820,7 +5852,7 @@ packages: universalify: 0.1.2 dev: true - /fs-extra/7.0.1: + /fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} dependencies: @@ -5829,7 +5861,7 @@ packages: universalify: 0.1.2 dev: true - /fs-extra/8.1.0: + /fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} dependencies: @@ -5838,7 +5870,7 @@ packages: universalify: 0.1.2 dev: true - /fs-extra/9.1.0: + /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} dependencies: @@ -5848,21 +5880,21 @@ packages: universalify: 2.0.0 dev: true - /fs-minipass/1.2.7: + /fs-minipass@1.2.7: resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} dependencies: minipass: 2.9.0 dev: true - /fs-readdir-recursive/1.1.0: + /fs-readdir-recursive@1.1.0: resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} dev: true - /fs.realpath/1.0.0: + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /fsevents/2.1.3: + /fsevents@2.1.3: resolution: {integrity: sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -5871,7 +5903,7 @@ packages: dev: true optional: true - /fsevents/2.3.2: + /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -5879,15 +5911,15 @@ packages: dev: true optional: true - /function-bind/1.1.1: + /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true - /function-bind/1.1.2: + /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true - /function.prototype.name/1.1.5: + /function.prototype.name@1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} engines: {node: '>= 0.4'} dependencies: @@ -5897,7 +5929,7 @@ packages: functions-have-names: 1.2.3 dev: true - /function.prototype.name/1.1.6: + /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: @@ -5907,15 +5939,15 @@ packages: functions-have-names: 1.2.3 dev: true - /functional-red-black-tree/1.0.1: + /functional-red-black-tree@1.0.1: resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} dev: true - /functions-have-names/1.2.3: + /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true - /ganache-core/2.13.2: + /ganache-core@2.13.2: resolution: {integrity: sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==} engines: {node: '>=8.9.0'} deprecated: ganache-core is now ganache; visit https://trfl.io/g7 for details @@ -5925,7 +5957,7 @@ packages: bip39: 2.5.0 cachedown: 1.0.0 clone: 2.1.2 - debug: 3.2.6 + debug: 3.2.6(supports-color@6.0.0) encoding-down: 5.0.4 eth-sig-util: 3.0.0 ethereumjs-abi: 0.6.8 @@ -5959,19 +5991,19 @@ packages: bundledDependencies: - keccak - /get-caller-file/1.0.3: + /get-caller-file@1.0.3: resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} dev: true - /get-caller-file/2.0.5: + /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-func-name/2.0.2: + /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - /get-intrinsic/1.1.3: + /get-intrinsic@1.1.3: resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} dependencies: function-bind: 1.1.1 @@ -5979,7 +6011,7 @@ packages: has-symbols: 1.0.3 dev: true - /get-intrinsic/1.2.2: + /get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: function-bind: 1.1.2 @@ -5988,36 +6020,36 @@ packages: hasown: 2.0.0 dev: true - /get-port/3.2.0: + /get-port@3.2.0: resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} engines: {node: '>=4'} dev: true - /get-stream/3.0.0: + /get-stream@3.0.0: resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} engines: {node: '>=4'} dev: true - /get-stream/4.1.0: + /get-stream@4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} dependencies: pump: 3.0.0 dev: true - /get-stream/5.1.0: + /get-stream@5.1.0: resolution: {integrity: sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==} engines: {node: '>=8'} dependencies: pump: 3.0.0 dev: true - /get-stream/6.0.1: + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} dev: true - /get-symbol-description/1.0.0: + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: @@ -6025,18 +6057,18 @@ packages: get-intrinsic: 1.1.3 dev: true - /get-value/2.0.6: + /get-value@2.0.6: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} dev: true - /getpass/0.1.7: + /getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} dependencies: assert-plus: 1.0.0 dev: true - /ghost-testrpc/0.0.2: + /ghost-testrpc@0.0.2: resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==} hasBin: true dependencies: @@ -6044,21 +6076,21 @@ packages: node-emoji: 1.11.0 dev: true - /glob-parent/5.1.2: + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 dev: true - /glob-parent/6.0.2: + /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 dev: true - /glob/5.0.15: + /glob@5.0.15: resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} dependencies: inflight: 1.0.6 @@ -6068,7 +6100,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.1.3: + /glob@7.1.3: resolution: {integrity: sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==} dependencies: fs.realpath: 1.0.0 @@ -6079,7 +6111,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.1.7: + /glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} dependencies: fs.realpath: 1.0.0 @@ -6090,7 +6122,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.2.0: + /glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} dependencies: fs.realpath: 1.0.0 @@ -6101,7 +6133,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.2.3: + /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: fs.realpath: 1.0.0 @@ -6112,7 +6144,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/8.1.0: + /glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} dependencies: @@ -6123,14 +6155,14 @@ packages: once: 1.4.0 dev: true - /global-modules/2.0.0: + /global-modules@2.0.0: resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} engines: {node: '>=6'} dependencies: global-prefix: 3.0.0 dev: true - /global-prefix/3.0.0: + /global-prefix@3.0.0: resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} engines: {node: '>=6'} dependencies: @@ -6139,33 +6171,33 @@ packages: which: 1.3.1 dev: true - /global/4.3.2: + /global@4.3.2: resolution: {integrity: sha512-/4AybdwIDU4HkCUbJkZdWpe4P6vuw/CUtu+0I1YlLIPe7OlUO7KNJ+q/rO70CW2/NW6Jc6I62++Hzsf5Alu6rQ==} dependencies: min-document: 2.19.0 process: 0.5.2 dev: true - /globals/13.20.0: + /globals@13.20.0: resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 dev: true - /globals/9.18.0: + /globals@9.18.0: resolution: {integrity: sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==} engines: {node: '>=0.10.0'} dev: true - /globalthis/1.0.3: + /globalthis@1.0.3: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} dependencies: define-properties: 1.2.1 dev: true - /globby/10.0.2: + /globby@10.0.2: resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} engines: {node: '>=8'} dependencies: @@ -6179,7 +6211,7 @@ packages: slash: 3.0.0 dev: true - /globby/11.1.0: + /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} dependencies: @@ -6191,13 +6223,13 @@ packages: slash: 3.0.0 dev: true - /gopd/1.0.1: + /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: get-intrinsic: 1.2.2 dev: true - /got/12.1.0: + /got@12.1.0: resolution: {integrity: sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==} engines: {node: '>=14.16'} dependencies: @@ -6216,7 +6248,7 @@ packages: responselike: 2.0.1 dev: true - /got/7.1.0: + /got@7.1.0: resolution: {integrity: sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==} engines: {node: '>=4'} dependencies: @@ -6238,7 +6270,7 @@ packages: url-to-options: 1.0.1 dev: true - /got/9.6.0: + /got@9.6.0: resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} engines: {node: '>=8.6'} dependencies: @@ -6257,24 +6289,24 @@ packages: url-parse-lax: 3.0.0 dev: true - /graceful-fs/4.2.10: + /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} dev: true - /grapheme-splitter/1.0.4: + /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true - /graphemer/1.4.0: + /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true - /growl/1.10.5: + /growl@1.10.5: resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} engines: {node: '>=4.x'} dev: true - /handlebars/4.7.7: + /handlebars@4.7.7: resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} engines: {node: '>=0.4.7'} hasBin: true @@ -6287,12 +6319,12 @@ packages: uglify-js: 3.17.3 dev: true - /har-schema/2.0.0: + /har-schema@2.0.0: resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} engines: {node: '>=4'} dev: true - /har-validator/5.1.5: + /har-validator@5.1.5: resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} engines: {node: '>=6'} deprecated: this library is no longer supported @@ -6301,7 +6333,7 @@ packages: har-schema: 2.0.0 dev: true - /hardhat-abi-exporter/2.10.1_hardhat@2.19.2: + /hardhat-abi-exporter@2.10.1(hardhat@2.19.2): resolution: {integrity: sha512-X8GRxUTtebMAd2k4fcPyVnCdPa6dYK4lBsrwzKP5yiSq4i+WadWPIumaLfce53TUf/o2TnLpLOduyO1ylE2NHQ==} engines: {node: '>=14.14.0'} peerDependencies: @@ -6309,34 +6341,34 @@ packages: dependencies: '@ethersproject/abi': 5.7.0 delete-empty: 3.0.0 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) dev: true - /hardhat-contract-sizer/2.10.0_hardhat@2.19.2: + /hardhat-contract-sizer@2.10.0(hardhat@2.19.2): resolution: {integrity: sha512-QiinUgBD5MqJZJh1hl1jc9dNnpJg7eE/w4/4GEnrcmZJJTDbVFNe3+/3Ep24XqISSkYxRz36czcPHKHd/a0dwA==} peerDependencies: hardhat: ^2.0.0 dependencies: chalk: 4.1.2 cli-table3: 0.6.3 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) strip-ansi: 6.0.1 dev: true - /hardhat-gas-reporter/1.0.9_hardhat@2.19.2: + /hardhat-gas-reporter@1.0.9(hardhat@2.19.2): resolution: {integrity: sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==} peerDependencies: hardhat: ^2.0.2 dependencies: array-uniq: 1.0.3 eth-gas-reporter: 0.2.25 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) sha1: 1.1.1 transitivePeerDependencies: - '@codechecks/client' dev: true - /hardhat-ignore-warnings/0.2.9: + /hardhat-ignore-warnings@0.2.9: resolution: {integrity: sha512-q1oj6/ixiAx+lgIyGLBajVCSC7qUtAoK7LS9Nr8UVHYo8Iuh5naBiVGo4RDJ6wxbDGYBkeSukUGZrMqzC2DWwA==} dependencies: minimatch: 5.1.6 @@ -6344,7 +6376,7 @@ packages: solidity-comments: 0.0.2 dev: true - /hardhat/2.19.2_scqxenvmgn24ljurjs2keb5hqa: + /hardhat@2.19.2(ts-node@10.9.2)(typescript@5.3.3): resolution: {integrity: sha512-CRU3+0Cc8Qh9UpxKd8cLADDPes7ZDtKj4dTK+ERtLBomEzhRPLWklJn4VKOwjre9/k8GNd/e9DYxpfuzcxbXPQ==} hasBin: true peerDependencies: @@ -6378,7 +6410,7 @@ packages: chalk: 2.4.2 chokidar: 3.5.3 ci-info: 2.0.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) enquirer: 2.3.6 env-paths: 2.2.1 ethereum-cryptography: 1.1.2 @@ -6397,10 +6429,10 @@ packages: raw-body: 2.5.1 resolve: 1.17.0 semver: 6.3.0 - solc: 0.7.3_debug@4.3.4 + solc: 0.7.3(debug@4.3.4) source-map-support: 0.5.21 stacktrace-parser: 0.1.10 - ts-node: 10.9.2_elefmx52zewn5giftcrxd6iwku + ts-node: 10.9.2(@types/node@16.18.68)(typescript@5.3.3) tsort: 0.0.1 typescript: 5.3.3 undici: 5.19.1 @@ -6412,66 +6444,66 @@ packages: - utf-8-validate dev: true - /has-ansi/2.0.0: + /has-ansi@2.0.0: resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} engines: {node: '>=0.10.0'} dependencies: ansi-regex: 2.1.1 dev: true - /has-bigints/1.0.2: + /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true - /has-flag/1.0.0: + /has-flag@1.0.0: resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} engines: {node: '>=0.10.0'} dev: true - /has-flag/3.0.0: + /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} dev: true - /has-flag/4.0.0: + /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} dev: true - /has-property-descriptors/1.0.0: + /has-property-descriptors@1.0.0: resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} dependencies: get-intrinsic: 1.1.3 dev: true - /has-proto/1.0.1: + /has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} engines: {node: '>= 0.4'} dev: true - /has-symbol-support-x/1.4.2: + /has-symbol-support-x@1.4.2: resolution: {integrity: sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==} dev: true - /has-symbols/1.0.3: + /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} dev: true - /has-to-string-tag-x/1.4.1: + /has-to-string-tag-x@1.4.1: resolution: {integrity: sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==} dependencies: has-symbol-support-x: 1.4.2 dev: true - /has-tostringtag/1.0.0: + /has-tostringtag@1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 dev: true - /has-value/0.3.1: + /has-value@0.3.1: resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} engines: {node: '>=0.10.0'} dependencies: @@ -6480,7 +6512,7 @@ packages: isobject: 2.1.0 dev: true - /has-value/1.0.0: + /has-value@1.0.0: resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} engines: {node: '>=0.10.0'} dependencies: @@ -6489,12 +6521,12 @@ packages: isobject: 3.0.1 dev: true - /has-values/0.1.4: + /has-values@0.1.4: resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} engines: {node: '>=0.10.0'} dev: true - /has-values/1.0.0: + /has-values@1.0.0: resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} engines: {node: '>=0.10.0'} dependencies: @@ -6502,14 +6534,14 @@ packages: kind-of: 4.0.0 dev: true - /has/1.0.3: + /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 dev: true - /hash-base/3.1.0: + /hash-base@3.1.0: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} engines: {node: '>=4'} dependencies: @@ -6518,58 +6550,58 @@ packages: safe-buffer: 5.2.1 dev: true - /hash.js/1.1.3: + /hash.js@1.1.3: resolution: {integrity: sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 dev: true - /hash.js/1.1.7: + /hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 - /hasown/2.0.0: + /hasown@2.0.0: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 dev: true - /he/1.2.0: + /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true dev: true - /header-case/1.0.1: + /header-case@1.0.1: resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 dev: true - /heap/0.2.6: + /heap@0.2.6: resolution: {integrity: sha512-MzzWcnfB1e4EG2vHi3dXHoBupmuXNZzx6pY6HldVS55JKKBoq3xOyzfSaZRkJp37HIhEYC78knabHff3zc4dQQ==} dev: true - /highlight.js/10.7.3: + /highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} dev: true - /highlightjs-solidity/2.0.5: + /highlightjs-solidity@2.0.5: resolution: {integrity: sha512-ReXxQSGQkODMUgHcWzVSnfDCDrL2HshOYgw3OlIYmfHeRzUPkfJTUIp95pK4CmbiNG2eMTOmNLpfCz9Zq7Cwmg==} dev: true - /hmac-drbg/1.0.1: + /hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} dependencies: hash.js: 1.1.7 minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - /home-or-tmp/2.0.0: + /home-or-tmp@2.0.0: resolution: {integrity: sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==} engines: {node: '>=0.10.0'} dependencies: @@ -6577,11 +6609,11 @@ packages: os-tmpdir: 1.0.2 dev: true - /hosted-git-info/2.8.9: + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true - /htmlparser2/8.0.1: + /htmlparser2@8.0.1: resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} dependencies: domelementtype: 2.3.0 @@ -6590,7 +6622,7 @@ packages: entities: 4.4.0 dev: true - /http-basic/8.1.3: + /http-basic@8.1.3: resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} engines: {node: '>=6.0.0'} dependencies: @@ -6600,11 +6632,11 @@ packages: parse-cache-control: 1.0.1 dev: true - /http-cache-semantics/4.0.3: + /http-cache-semantics@4.0.3: resolution: {integrity: sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==} dev: true - /http-errors/1.7.2: + /http-errors@1.7.2: resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==} engines: {node: '>= 0.6'} dependencies: @@ -6615,7 +6647,7 @@ packages: toidentifier: 1.0.0 dev: true - /http-errors/1.7.3: + /http-errors@1.7.3: resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} engines: {node: '>= 0.6'} dependencies: @@ -6626,7 +6658,7 @@ packages: toidentifier: 1.0.0 dev: true - /http-errors/2.0.0: + /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} dependencies: @@ -6637,17 +6669,17 @@ packages: toidentifier: 1.0.1 dev: true - /http-https/1.0.0: + /http-https@1.0.0: resolution: {integrity: sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==} dev: true - /http-response-object/3.0.2: + /http-response-object@3.0.2: resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} dependencies: '@types/node': 10.17.60 dev: true - /http-signature/1.2.0: + /http-signature@1.2.0: resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} engines: {node: '>=0.8', npm: '>=1.3.7'} dependencies: @@ -6656,7 +6688,7 @@ packages: sshpk: 1.16.1 dev: true - /http2-wrapper/2.1.11: + /http2-wrapper@2.1.11: resolution: {integrity: sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==} engines: {node: '>=10.19.0'} dependencies: @@ -6664,69 +6696,69 @@ packages: resolve-alpn: 1.2.1 dev: true - /https-proxy-agent/5.0.1: + /https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true - /human-signals/2.1.0: + /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} dev: true - /human-signals/4.3.1: + /human-signals@4.3.1: resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} engines: {node: '>=14.18.0'} dev: true - /iconv-lite/0.4.24: + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 dev: true - /iconv-lite/0.6.3: + /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 dev: true - /idna-uts46-hx/2.3.1: + /idna-uts46-hx@2.3.1: resolution: {integrity: sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==} engines: {node: '>=4.0.0'} dependencies: punycode: 2.1.0 dev: true - /ieee754/1.2.1: + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true - /ignore/5.2.4: + /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} dev: true - /immediate/3.2.3: + /immediate@3.2.3: resolution: {integrity: sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==} dev: true - /immediate/3.3.0: + /immediate@3.3.0: resolution: {integrity: sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==} dev: true - /immutable/4.1.0: + /immutable@4.1.0: resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} dev: true - /import-fresh/3.3.0: + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} dependencies: @@ -6734,35 +6766,35 @@ packages: resolve-from: 4.0.0 dev: true - /imurmurhash/0.1.4: + /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} dev: true - /indent-string/4.0.0: + /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} dev: true - /inflight/1.0.6: + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: once: 1.4.0 wrappy: 1.0.2 dev: true - /inherits/2.0.3: + /inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} dev: true - /inherits/2.0.4: + /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - /ini/1.3.8: + /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true - /internal-slot/1.0.3: + /internal-slot@1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} dependencies: @@ -6771,7 +6803,7 @@ packages: side-channel: 1.0.4 dev: true - /internal-slot/1.0.6: + /internal-slot@1.0.6: resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: @@ -6780,53 +6812,53 @@ packages: side-channel: 1.0.4 dev: true - /interpret/1.2.0: + /interpret@1.2.0: resolution: {integrity: sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==} engines: {node: '>= 0.10'} dev: true - /invariant/2.2.4: + /invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} dependencies: loose-envify: 1.4.0 dev: true - /invert-kv/1.0.0: + /invert-kv@1.0.0: resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} engines: {node: '>=0.10.0'} dev: true - /io-ts/1.10.4: + /io-ts@1.10.4: resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} dependencies: fp-ts: 1.19.3 dev: true - /ipaddr.js/1.9.0: + /ipaddr.js@1.9.0: resolution: {integrity: sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==} engines: {node: '>= 0.10'} dev: true - /is-accessor-descriptor/0.1.6: + /is-accessor-descriptor@0.1.6: resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /is-accessor-descriptor/1.0.0: + /is-accessor-descriptor@1.0.0: resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 6.0.3 dev: true - /is-arguments/1.0.4: + /is-arguments@1.0.4: resolution: {integrity: sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==} engines: {node: '>= 0.4'} dev: true - /is-array-buffer/3.0.2: + /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: call-bind: 1.0.5 @@ -6834,24 +6866,24 @@ packages: is-typed-array: 1.1.12 dev: true - /is-arrayish/0.2.1: + /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: true - /is-bigint/1.0.4: + /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: has-bigints: 1.0.2 dev: true - /is-binary-path/2.1.0: + /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 dev: true - /is-boolean-object/1.1.2: + /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: @@ -6859,53 +6891,53 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-buffer/1.1.6: + /is-buffer@1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} dev: true - /is-buffer/2.0.5: + /is-buffer@2.0.5: resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} engines: {node: '>=4'} dev: true - /is-callable/1.2.7: + /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} dev: true - /is-ci/2.0.0: + /is-ci@2.0.0: resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} hasBin: true dependencies: ci-info: 2.0.0 dev: true - /is-core-module/2.10.0: + /is-core-module@2.10.0: resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} dependencies: has: 1.0.3 dev: true - /is-data-descriptor/0.1.4: + /is-data-descriptor@0.1.4: resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /is-data-descriptor/1.0.0: + /is-data-descriptor@1.0.0: resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 6.0.3 dev: true - /is-date-object/1.0.2: + /is-date-object@1.0.2: resolution: {integrity: sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==} engines: {node: '>= 0.4'} dev: true - /is-descriptor/0.1.6: + /is-descriptor@0.1.6: resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} engines: {node: '>=0.10.0'} dependencies: @@ -6914,7 +6946,7 @@ packages: kind-of: 5.1.0 dev: true - /is-descriptor/1.0.2: + /is-descriptor@1.0.2: resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} engines: {node: '>=0.10.0'} dependencies: @@ -6923,84 +6955,84 @@ packages: kind-of: 6.0.3 dev: true - /is-docker/2.2.1: + /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} hasBin: true dev: true - /is-docker/3.0.0: + /is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true dev: true - /is-extendable/0.1.1: + /is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} dev: true - /is-extendable/1.0.1: + /is-extendable@1.0.1: resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} engines: {node: '>=0.10.0'} dependencies: is-plain-object: 2.0.4 dev: true - /is-extglob/2.1.1: + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} dev: true - /is-finite/1.1.0: + /is-finite@1.1.0: resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} engines: {node: '>=0.10.0'} dev: true - /is-fn/1.0.0: + /is-fn@1.0.0: resolution: {integrity: sha512-XoFPJQmsAShb3jEQRfzf2rqXavq7fIqF/jOekp308JlThqrODnMpweVSGilKTCXELfLhltGP2AGgbQGVP8F1dg==} engines: {node: '>=0.10.0'} dev: true - /is-fullwidth-code-point/1.0.0: + /is-fullwidth-code-point@1.0.0: resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} engines: {node: '>=0.10.0'} dependencies: number-is-nan: 1.0.1 dev: true - /is-fullwidth-code-point/2.0.0: + /is-fullwidth-code-point@2.0.0: resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} engines: {node: '>=4'} dev: true - /is-fullwidth-code-point/3.0.0: + /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} dev: true - /is-function/1.0.1: + /is-function@1.0.1: resolution: {integrity: sha512-coTeFCk0VaNTNO/FwMMaI30KOPOIkLp1q5M7dIVDn4Zop70KyGFZqXSgKClBisjrD3S2cVIuD7MD793/lyLGZQ==} dev: true - /is-generator-function/1.0.8: + /is-generator-function@1.0.8: resolution: {integrity: sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==} engines: {node: '>= 0.4'} dev: true - /is-glob/4.0.3: + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 dev: true - /is-hex-prefixed/1.0.0: + /is-hex-prefixed@1.0.0: resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} engines: {node: '>=6.5.0', npm: '>=3'} dev: true - /is-inside-container/1.0.0: + /is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} hasBin: true @@ -7008,63 +7040,63 @@ packages: is-docker: 3.0.0 dev: true - /is-lower-case/1.1.3: + /is-lower-case@1.1.3: resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} dependencies: lower-case: 1.1.4 dev: true - /is-negative-zero/2.0.2: + /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} dev: true - /is-number-object/1.0.7: + /is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: true - /is-number/3.0.0: + /is-number@3.0.0: resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /is-number/7.0.0: + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true - /is-object/1.0.1: + /is-object@1.0.1: resolution: {integrity: sha512-+XzmTRB/JXoIdK20Ge8K8PRsP5UlthLaVhIRxzIwQ73jRgER8iRw98DilvERx/tSjOHLy9JM4sKUfLRMB5ui0Q==} dev: true - /is-path-inside/3.0.3: + /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} dev: true - /is-plain-obj/1.1.0: + /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} dev: true - /is-plain-obj/2.1.0: + /is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} dev: true - /is-plain-object/2.0.4: + /is-plain-object@2.0.4: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 dev: true - /is-regex/1.1.4: + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: @@ -7072,54 +7104,54 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-retry-allowed/1.2.0: + /is-retry-allowed@1.2.0: resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} engines: {node: '>=0.10.0'} dev: true - /is-shared-array-buffer/1.0.2: + /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: call-bind: 1.0.2 dev: true - /is-stream/1.1.0: + /is-stream@1.1.0: resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} engines: {node: '>=0.10.0'} dev: true - /is-stream/2.0.1: + /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} dev: true - /is-stream/3.0.0: + /is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /is-string/1.0.7: + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: true - /is-symbol/1.0.3: + /is-symbol@1.0.3: resolution: {integrity: sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 dev: true - /is-typed-array/1.1.12: + /is-typed-array@1.1.12: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: which-typed-array: 1.1.13 dev: true - /is-typed-array/1.1.5: + /is-typed-array@1.1.5: resolution: {integrity: sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==} engines: {node: '>= 0.4'} dependencies: @@ -7130,76 +7162,76 @@ packages: has-symbols: 1.0.3 dev: true - /is-typedarray/1.0.0: + /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: true - /is-unicode-supported/0.1.0: + /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} dev: true - /is-upper-case/1.1.2: + /is-upper-case@1.1.2: resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==} dependencies: upper-case: 1.1.3 dev: true - /is-url/1.2.4: + /is-url@1.2.4: resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} dev: true - /is-utf8/0.2.1: + /is-utf8@0.2.1: resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} dev: true - /is-weakref/1.0.2: + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: true - /is-windows/1.0.2: + /is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} dev: true - /is-wsl/2.2.0: + /is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} dependencies: is-docker: 2.2.1 dev: true - /isarray/0.0.1: + /isarray@0.0.1: resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} dev: true - /isarray/1.0.0: + /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} dev: true - /isarray/2.0.5: + /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} dev: true - /isexe/2.0.0: + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isobject/2.1.0: + /isobject@2.1.0: resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} engines: {node: '>=0.10.0'} dependencies: isarray: 1.0.0 dev: true - /isobject/3.0.1: + /isobject@3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} dev: true - /isomorphic-unfetch/3.1.0: + /isomorphic-unfetch@3.1.0: resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} dependencies: node-fetch: 2.6.7 @@ -7208,11 +7240,11 @@ packages: - encoding dev: true - /isstream/0.1.2: + /isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: true - /istanbul/0.4.5: + /istanbul@0.4.5: resolution: {integrity: sha512-nMtdn4hvK0HjUlzr1DrKSUY8ychprt8dzHOgY2KXsIhHu5PuQQEOTM27gV9Xblyon7aUH/TSFIjRHEODF/FRPg==} deprecated: |- This module is no longer maintained, try this instead: @@ -7236,7 +7268,7 @@ packages: wordwrap: 1.0.0 dev: true - /isurl/1.0.0: + /isurl@1.0.0: resolution: {integrity: sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==} engines: {node: '>= 4'} dependencies: @@ -7244,38 +7276,38 @@ packages: is-object: 1.0.1 dev: true - /js-cookie/2.2.1: + /js-cookie@2.2.1: resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} dev: true - /js-sdsl/4.4.2: + /js-sdsl@4.4.2: resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==} dev: true - /js-sha3/0.5.5: + /js-sha3@0.5.5: resolution: {integrity: sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==} dev: true - /js-sha3/0.5.7: + /js-sha3@0.5.7: resolution: {integrity: sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==} dev: true - /js-sha3/0.6.1: + /js-sha3@0.6.1: resolution: {integrity: sha512-2OHj7sAZ9gnJS4lQsgIsTslmqVrNQdDC99bvwYGQKU1w6k/gwsTLeGBfWt8yHCuTOGqk7DXzuVlK8J+dDXnG7A==} dev: true - /js-sha3/0.8.0: + /js-sha3@0.8.0: resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} - /js-tokens/3.0.2: + /js-tokens@3.0.2: resolution: {integrity: sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==} dev: true - /js-tokens/4.0.0: + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true - /js-yaml/3.13.1: + /js-yaml@3.13.1: resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==} hasBin: true dependencies: @@ -7283,7 +7315,7 @@ packages: esprima: 4.0.1 dev: true - /js-yaml/3.14.1: + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true dependencies: @@ -7291,40 +7323,40 @@ packages: esprima: 4.0.1 dev: true - /js-yaml/4.1.0: + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true dependencies: argparse: 2.0.1 dev: true - /jsbn/0.1.1: + /jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} dev: true - /jsesc/0.5.0: + /jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true dev: true - /jsesc/1.3.0: + /jsesc@1.3.0: resolution: {integrity: sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==} hasBin: true dev: true - /json-buffer/3.0.0: + /json-buffer@3.0.0: resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} dev: true - /json-buffer/3.0.1: + /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true - /json-parse-even-better-errors/2.3.1: + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true - /json-rpc-engine/3.8.0: + /json-rpc-engine@3.8.0: resolution: {integrity: sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==} dependencies: async: 2.6.3 @@ -7337,43 +7369,43 @@ packages: - supports-color dev: true - /json-rpc-error/2.0.0: + /json-rpc-error@2.0.0: resolution: {integrity: sha512-EwUeWP+KgAZ/xqFpaP6YDAXMtCJi+o/QQpCQFIYyxr01AdADi2y413eM8hSqJcoQym9WMePAJWoaODEJufC4Ug==} dependencies: inherits: 2.0.4 dev: true - /json-rpc-random-id/1.0.1: + /json-rpc-random-id@1.0.1: resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} dev: true - /json-schema-traverse/0.4.1: + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true - /json-schema-traverse/1.0.0: + /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} dev: true - /json-schema/0.2.3: + /json-schema@0.2.3: resolution: {integrity: sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==} dev: true - /json-stable-stringify-without-jsonify/1.0.1: + /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true - /json-stable-stringify/1.0.1: + /json-stable-stringify@1.0.1: resolution: {integrity: sha512-i/J297TW6xyj7sDFa7AmBPkQvLIxWr2kKPWI26tXydnZrzVAocNqn5DMNT1Mzk0vit1V5UkRM7C1KdVNp7Lmcg==} dependencies: jsonify: 0.0.0 dev: true - /json-stringify-safe/5.0.1: + /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} dev: true - /json-to-ast/2.1.0: + /json-to-ast@2.1.0: resolution: {integrity: sha512-W9Lq347r8tA1DfMvAGn9QNcgYm4Wm7Yc+k8e6vezpMnRT+NHbtlxgNBXRVjXe9YM6eTn6+p/MKOlV/aABJcSnQ==} engines: {node: '>= 4'} dependencies: @@ -7381,24 +7413,24 @@ packages: grapheme-splitter: 1.0.4 dev: true - /json5/0.5.1: + /json5@0.5.1: resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==} hasBin: true dev: true - /jsonfile/2.4.0: + /jsonfile@2.4.0: resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} optionalDependencies: graceful-fs: 4.2.10 dev: true - /jsonfile/4.0.0: + /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: graceful-fs: 4.2.10 dev: true - /jsonfile/6.1.0: + /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: universalify: 2.0.0 @@ -7406,20 +7438,20 @@ packages: graceful-fs: 4.2.10 dev: true - /jsonify/0.0.0: + /jsonify@0.0.0: resolution: {integrity: sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==} dev: true - /jsonpointer/5.0.1: + /jsonpointer@5.0.1: resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} engines: {node: '>=0.10.0'} dev: true - /jsonschema/1.4.0: + /jsonschema@1.4.0: resolution: {integrity: sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==} dev: true - /jsprim/1.4.1: + /jsprim@1.4.1: resolution: {integrity: sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==} engines: {'0': node >=0.6.0} dependencies: @@ -7429,7 +7461,7 @@ packages: verror: 1.10.0 dev: true - /keccak/3.0.2: + /keccak@3.0.2: resolution: {integrity: sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==} engines: {node: '>=10.0.0'} requiresBuild: true @@ -7439,100 +7471,100 @@ packages: readable-stream: 3.6.0 dev: true - /keccakjs/0.2.3: + /keccakjs@0.2.3: resolution: {integrity: sha512-BjLkNDcfaZ6l8HBG9tH0tpmDv3sS2mA7FNQxFHpCdzP3Gb2MVruXBSuoM66SnVxKJpAr5dKGdkHD+bDokt8fTg==} dependencies: browserify-sha3: 0.0.4 sha3: 1.2.6 dev: true - /keyv/3.1.0: + /keyv@3.1.0: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} dependencies: json-buffer: 3.0.0 dev: true - /keyv/4.5.0: + /keyv@4.5.0: resolution: {integrity: sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==} dependencies: json-buffer: 3.0.1 dev: true - /kind-of/3.2.2: + /kind-of@3.2.2: resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} engines: {node: '>=0.10.0'} dependencies: is-buffer: 1.1.6 dev: true - /kind-of/4.0.0: + /kind-of@4.0.0: resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} engines: {node: '>=0.10.0'} dependencies: is-buffer: 1.1.6 dev: true - /kind-of/5.1.0: + /kind-of@5.1.0: resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} engines: {node: '>=0.10.0'} dev: true - /kind-of/6.0.3: + /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} dev: true - /klaw-sync/6.0.0: + /klaw-sync@6.0.0: resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} dependencies: graceful-fs: 4.2.10 dev: true - /klaw/1.3.1: + /klaw@1.3.1: resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} optionalDependencies: graceful-fs: 4.2.10 dev: true - /latest-version/7.0.0: + /latest-version@7.0.0: resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} engines: {node: '>=14.16'} dependencies: package-json: 8.1.1 dev: true - /lcid/1.0.0: + /lcid@1.0.0: resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} engines: {node: '>=0.10.0'} dependencies: invert-kv: 1.0.0 dev: true - /level-codec/7.0.1: + /level-codec@7.0.1: resolution: {integrity: sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==} dev: true - /level-codec/9.0.2: + /level-codec@9.0.2: resolution: {integrity: sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==} engines: {node: '>=6'} dependencies: buffer: 5.7.1 dev: true - /level-errors/1.0.5: + /level-errors@1.0.5: resolution: {integrity: sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==} dependencies: errno: 0.1.8 dev: true - /level-errors/2.0.1: + /level-errors@2.0.1: resolution: {integrity: sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==} engines: {node: '>=6'} dependencies: errno: 0.1.8 dev: true - /level-iterator-stream/1.3.1: + /level-iterator-stream@1.3.1: resolution: {integrity: sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==} dependencies: inherits: 2.0.4 @@ -7541,7 +7573,7 @@ packages: xtend: 4.0.2 dev: true - /level-iterator-stream/2.0.3: + /level-iterator-stream@2.0.3: resolution: {integrity: sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==} engines: {node: '>=4'} dependencies: @@ -7550,7 +7582,7 @@ packages: xtend: 4.0.2 dev: true - /level-iterator-stream/3.0.1: + /level-iterator-stream@3.0.1: resolution: {integrity: sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==} engines: {node: '>=6'} dependencies: @@ -7559,7 +7591,7 @@ packages: xtend: 4.0.2 dev: true - /level-mem/3.0.1: + /level-mem@3.0.1: resolution: {integrity: sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==} engines: {node: '>=6'} dependencies: @@ -7567,7 +7599,7 @@ packages: memdown: 3.0.0 dev: true - /level-packager/4.0.1: + /level-packager@4.0.1: resolution: {integrity: sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==} engines: {node: '>=6'} dependencies: @@ -7575,13 +7607,13 @@ packages: levelup: 3.1.1 dev: true - /level-post/1.0.7: + /level-post@1.0.7: resolution: {integrity: sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==} dependencies: ltgt: 2.2.1 dev: true - /level-sublevel/6.6.4: + /level-sublevel@6.6.4: resolution: {integrity: sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==} dependencies: bytewise: 1.1.0 @@ -7596,12 +7628,12 @@ packages: xtend: 4.0.2 dev: true - /level-supports/4.0.1: + /level-supports@4.0.1: resolution: {integrity: sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==} engines: {node: '>=12'} dev: true - /level-transcoder/1.0.1: + /level-transcoder@1.0.1: resolution: {integrity: sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==} engines: {node: '>=12'} dependencies: @@ -7609,14 +7641,14 @@ packages: module-error: 1.0.2 dev: true - /level-ws/0.0.0: + /level-ws@0.0.0: resolution: {integrity: sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==} dependencies: readable-stream: 1.0.34 xtend: 2.1.2 dev: true - /level-ws/1.0.0: + /level-ws@1.0.0: resolution: {integrity: sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==} engines: {node: '>=6'} dependencies: @@ -7625,7 +7657,7 @@ packages: xtend: 4.0.2 dev: true - /level/8.0.0: + /level@8.0.0: resolution: {integrity: sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==} engines: {node: '>=12'} dependencies: @@ -7633,7 +7665,7 @@ packages: classic-level: 1.2.0 dev: true - /levelup/1.3.9: + /levelup@1.3.9: resolution: {integrity: sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==} dependencies: deferred-leveldown: 1.2.2 @@ -7645,7 +7677,7 @@ packages: xtend: 4.0.2 dev: true - /levelup/3.1.1: + /levelup@3.1.1: resolution: {integrity: sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==} engines: {node: '>=6'} dependencies: @@ -7655,12 +7687,12 @@ packages: xtend: 4.0.2 dev: true - /leven/3.1.0: + /leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} dev: true - /levn/0.3.0: + /levn@0.3.0: resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} engines: {node: '>= 0.8.0'} dependencies: @@ -7668,7 +7700,7 @@ packages: type-check: 0.3.2 dev: true - /levn/0.4.1: + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} dependencies: @@ -7676,11 +7708,11 @@ packages: type-check: 0.4.0 dev: true - /lines-and-columns/1.2.4: + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true - /load-json-file/1.1.0: + /load-json-file@1.1.0: resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} engines: {node: '>=0.10.0'} dependencies: @@ -7691,7 +7723,7 @@ packages: strip-bom: 2.0.0 dev: true - /locate-path/2.0.0: + /locate-path@2.0.0: resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} engines: {node: '>=4'} dependencies: @@ -7699,7 +7731,7 @@ packages: path-exists: 3.0.0 dev: true - /locate-path/3.0.0: + /locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} dependencies: @@ -7707,60 +7739,60 @@ packages: path-exists: 3.0.0 dev: true - /locate-path/5.0.0: + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} dependencies: p-locate: 4.1.0 dev: true - /locate-path/6.0.0: + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} dependencies: p-locate: 5.0.0 dev: true - /lodash.assign/4.2.0: + /lodash.assign@4.2.0: resolution: {integrity: sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==} dev: true - /lodash.camelcase/4.3.0: + /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: true - /lodash.flatten/4.4.0: + /lodash.flatten@4.4.0: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: true - /lodash.mapvalues/4.6.0: + /lodash.mapvalues@4.6.0: resolution: {integrity: sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==} dev: true - /lodash.merge/4.6.2: + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true - /lodash.truncate/4.4.2: + /lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} dev: true - /lodash/4.17.20: + /lodash@4.17.20: resolution: {integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==} dev: true - /lodash/4.17.21: + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true - /log-symbols/3.0.0: + /log-symbols@3.0.0: resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} engines: {node: '>=8'} dependencies: chalk: 2.4.2 dev: true - /log-symbols/4.1.0: + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} dependencies: @@ -7768,108 +7800,108 @@ packages: is-unicode-supported: 0.1.0 dev: true - /looper/2.0.0: + /looper@2.0.0: resolution: {integrity: sha512-6DzMHJcjbQX/UPHc1rRCBfKlLwDkvuGZ715cIR36wSdYqWXFT35uLXq5P/2orl3tz+t+VOVPxw4yPinQlUDGDQ==} dev: true - /looper/3.0.0: + /looper@3.0.0: resolution: {integrity: sha512-LJ9wplN/uSn72oJRsXTx+snxPet5c8XiZmOKCm906NVYu+ag6SB6vUcnJcWxgnl2NfbIyeobAn7Bwv6xRj2XJg==} dev: true - /loose-envify/1.4.0: + /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true dependencies: js-tokens: 4.0.0 dev: true - /loupe/2.3.7: + /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: get-func-name: 2.0.2 - /lower-case-first/1.0.2: + /lower-case-first@1.0.2: resolution: {integrity: sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==} dependencies: lower-case: 1.1.4 dev: true - /lower-case/1.1.4: + /lower-case@1.1.4: resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} dev: true - /lowercase-keys/1.0.1: + /lowercase-keys@1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} engines: {node: '>=0.10.0'} dev: true - /lowercase-keys/2.0.0: + /lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} dev: true - /lowercase-keys/3.0.0: + /lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /lru-cache/3.2.0: + /lru-cache@3.2.0: resolution: {integrity: sha512-91gyOKTc2k66UG6kHiH4h3S2eltcPwE1STVfMYC/NG+nZwf8IIuiamfmpGZjpbbxzSyEJaLC0tNSmhjlQUTJow==} dependencies: pseudomap: 1.0.2 dev: true - /lru-cache/5.1.1: + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: yallist: 3.1.1 dev: true - /lru-cache/6.0.0: + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} dependencies: yallist: 4.0.0 dev: true - /lru_map/0.3.3: + /lru_map@0.3.3: resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} dev: true - /ltgt/2.1.3: + /ltgt@2.1.3: resolution: {integrity: sha512-5VjHC5GsENtIi5rbJd+feEpDKhfr7j0odoUR2Uh978g+2p93nd5o34cTjQWohXsPsCZeqoDnIqEf88mPCe0Pfw==} dev: true - /ltgt/2.2.1: + /ltgt@2.2.1: resolution: {integrity: sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==} dev: true - /make-error/1.3.6: + /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true - /map-cache/0.2.2: + /map-cache@0.2.2: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} engines: {node: '>=0.10.0'} dev: true - /map-visit/1.0.0: + /map-visit@1.0.0: resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} engines: {node: '>=0.10.0'} dependencies: object-visit: 1.0.1 dev: true - /markdown-table/1.1.3: + /markdown-table@1.1.3: resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} dev: true - /mcl-wasm/0.7.9: + /mcl-wasm@0.7.9: resolution: {integrity: sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==} engines: {node: '>=8.9.0'} dev: true - /md5.js/1.3.5: + /md5.js@1.3.5: resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} dependencies: hash-base: 3.1.0 @@ -7877,12 +7909,12 @@ packages: safe-buffer: 5.2.1 dev: true - /media-typer/0.3.0: + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} dev: true - /memdown/1.4.1: + /memdown@1.4.1: resolution: {integrity: sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==} dependencies: abstract-leveldown: 2.7.2 @@ -7893,7 +7925,7 @@ packages: safe-buffer: 5.1.2 dev: true - /memdown/3.0.0: + /memdown@3.0.0: resolution: {integrity: sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==} engines: {node: '>=6'} dependencies: @@ -7905,7 +7937,7 @@ packages: safe-buffer: 5.1.2 dev: true - /memory-level/1.0.0: + /memory-level@1.0.0: resolution: {integrity: sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==} engines: {node: '>=12'} dependencies: @@ -7914,25 +7946,25 @@ packages: module-error: 1.0.2 dev: true - /memorystream/0.3.1: + /memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} dev: true - /merge-descriptors/1.0.1: + /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} dev: true - /merge-stream/2.0.0: + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true - /merge2/1.4.1: + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} dev: true - /merkle-patricia-tree/2.3.2: + /merkle-patricia-tree@2.3.2: resolution: {integrity: sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==} dependencies: async: 1.5.2 @@ -7945,7 +7977,7 @@ packages: semaphore: 1.1.0 dev: true - /merkle-patricia-tree/3.0.0: + /merkle-patricia-tree@3.0.0: resolution: {integrity: sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==} dependencies: async: 2.6.3 @@ -7957,12 +7989,12 @@ packages: semaphore: 1.1.0 dev: true - /methods/1.1.2: + /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} dev: true - /micromatch/3.1.10: + /micromatch@3.1.10: resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} engines: {node: '>=0.10.0'} dependencies: @@ -7983,7 +8015,7 @@ packages: - supports-color dev: true - /micromatch/4.0.5: + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} dependencies: @@ -7991,7 +8023,7 @@ packages: picomatch: 2.3.1 dev: true - /miller-rabin/4.0.1: + /miller-rabin@4.0.1: resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} hasBin: true dependencies: @@ -7999,111 +8031,111 @@ packages: brorand: 1.1.0 dev: true - /mime-db/1.44.0: + /mime-db@1.44.0: resolution: {integrity: sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==} engines: {node: '>= 0.6'} dev: true - /mime-types/2.1.27: + /mime-types@2.1.27: resolution: {integrity: sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.44.0 dev: true - /mime/1.6.0: + /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} hasBin: true dev: true - /mimic-fn/2.1.0: + /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} dev: true - /mimic-fn/4.0.0: + /mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} dev: true - /mimic-response/1.0.1: + /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} dev: true - /mimic-response/3.1.0: + /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} dev: true - /min-document/2.19.0: + /min-document@2.19.0: resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} dependencies: dom-walk: 0.1.1 dev: true - /minimalistic-assert/1.0.1: + /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - /minimalistic-crypto-utils/1.0.1: + /minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - /minimatch/3.0.4: + /minimatch@3.0.4: resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} dependencies: brace-expansion: 1.1.11 dev: true - /minimatch/3.1.2: + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 dev: true - /minimatch/5.0.1: + /minimatch@5.0.1: resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 dev: true - /minimatch/5.1.6: + /minimatch@5.1.6: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 dev: true - /minimatch/9.0.3: + /minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 dev: true - /minimist/1.2.6: + /minimist@1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} dev: true - /minimist/1.2.8: + /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: true - /minipass/2.9.0: + /minipass@2.9.0: resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} dependencies: safe-buffer: 5.2.1 yallist: 3.1.1 dev: true - /minizlib/1.3.3: + /minizlib@1.3.3: resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} dependencies: minipass: 2.9.0 dev: true - /mixin-deep/1.3.2: + /mixin-deep@1.3.2: resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} engines: {node: '>=0.10.0'} dependencies: @@ -8111,7 +8143,7 @@ packages: is-extendable: 1.0.1 dev: true - /mkdirp-promise/5.0.1: + /mkdirp-promise@5.0.1: resolution: {integrity: sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==} engines: {node: '>=4'} deprecated: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that. @@ -8119,33 +8151,33 @@ packages: mkdirp: 1.0.4 dev: true - /mkdirp/0.5.5: + /mkdirp@0.5.5: resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} hasBin: true dependencies: minimist: 1.2.8 dev: true - /mkdirp/0.5.6: + /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true dependencies: minimist: 1.2.6 dev: true - /mkdirp/1.0.4: + /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true dev: true - /mnemonist/0.38.5: + /mnemonist@0.38.5: resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} dependencies: obliterator: 2.0.4 dev: true - /mocha/10.2.0: + /mocha@10.2.0: resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} engines: {node: '>= 14.0.0'} hasBin: true @@ -8153,7 +8185,7 @@ packages: ansi-colors: 4.1.1 browser-stdout: 1.3.1 chokidar: 3.5.3 - debug: 4.3.4_supports-color@8.1.1 + debug: 4.3.4(supports-color@8.1.1) diff: 5.0.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 @@ -8173,7 +8205,7 @@ packages: yargs-unparser: 2.0.0 dev: true - /mocha/7.2.0: + /mocha@7.2.0: resolution: {integrity: sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==} engines: {node: '>= 8.10.0'} hasBin: true @@ -8181,7 +8213,7 @@ packages: ansi-colors: 3.2.3 browser-stdout: 1.3.1 chokidar: 3.3.0 - debug: 3.2.6_supports-color@6.0.0 + debug: 3.2.6(supports-color@6.0.0) diff: 3.5.0 escape-string-regexp: 1.0.5 find-up: 3.0.0 @@ -8204,36 +8236,36 @@ packages: yargs-unparser: 1.6.0 dev: true - /mock-fs/4.12.0: + /mock-fs@4.12.0: resolution: {integrity: sha512-/P/HtrlvBxY4o/PzXY9cCNBrdylDNxg7gnrv2sMNxj+UJ2m8jSpl0/A6fuJeNAWr99ZvGWH8XCbE0vmnM5KupQ==} dev: true - /module-error/1.0.2: + /module-error@1.0.2: resolution: {integrity: sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==} engines: {node: '>=10'} dev: true - /moment/2.29.4: + /moment@2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} dev: true - /ms/2.0.0: + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: true - /ms/2.1.1: + /ms@2.1.1: resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} dev: true - /ms/2.1.2: + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true - /ms/2.1.3: + /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true - /multibase/0.6.1: + /multibase@0.6.1: resolution: {integrity: sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==} deprecated: This module has been superseded by the multiformats module dependencies: @@ -8241,7 +8273,7 @@ packages: buffer: 5.7.1 dev: true - /multibase/0.7.0: + /multibase@0.7.0: resolution: {integrity: sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==} deprecated: This module has been superseded by the multiformats module dependencies: @@ -8249,14 +8281,14 @@ packages: buffer: 5.7.1 dev: true - /multicodec/0.5.7: + /multicodec@0.5.7: resolution: {integrity: sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==} deprecated: This module has been superseded by the multiformats module dependencies: varint: 5.0.2 dev: true - /multicodec/1.0.4: + /multicodec@1.0.4: resolution: {integrity: sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==} deprecated: This module has been superseded by the multiformats module dependencies: @@ -8264,7 +8296,7 @@ packages: varint: 5.0.2 dev: true - /multihashes/0.4.21: + /multihashes@0.4.21: resolution: {integrity: sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==} dependencies: buffer: 5.7.1 @@ -8272,29 +8304,29 @@ packages: varint: 5.0.2 dev: true - /nan/2.13.2: + /nan@2.13.2: resolution: {integrity: sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==} dev: true - /nan/2.16.0: + /nan@2.16.0: resolution: {integrity: sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==} dev: true - /nano-base32/1.0.1: + /nano-base32@1.0.1: resolution: {integrity: sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==} dev: true - /nano-json-stream-parser/0.1.2: + /nano-json-stream-parser@0.1.2: resolution: {integrity: sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==} dev: true - /nanoid/3.3.3: + /nanoid@3.3.3: resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true - /nanomatch/1.2.13: + /nanomatch@1.2.13: resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} engines: {node: '>=0.10.0'} dependencies: @@ -8313,68 +8345,68 @@ packages: - supports-color dev: true - /napi-macros/2.0.0: + /napi-macros@2.0.0: resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} dev: true - /natural-compare/1.4.0: + /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /negotiator/0.6.2: + /negotiator@0.6.2: resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==} engines: {node: '>= 0.6'} dev: true - /neo-async/2.6.2: + /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} dev: true - /neodoc/2.0.2: + /neodoc@2.0.2: resolution: {integrity: sha512-NAppJ0YecKWdhSXFYCHbo6RutiX8vOt/Jo3l46mUg6pQlpJNaqc5cGxdrW2jITQm5JIYySbFVPDl3RrREXNyPw==} dependencies: ansi-regex: 2.1.1 dev: true - /next-tick/1.1.0: + /next-tick@1.1.0: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} dev: true - /nice-try/1.0.5: + /nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} dev: true - /no-case/2.3.2: + /no-case@2.3.2: resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} dependencies: lower-case: 1.1.4 dev: true - /node-addon-api/2.0.2: + /node-addon-api@2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} dev: true - /node-emoji/1.11.0: + /node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} dependencies: lodash: 4.17.21 dev: true - /node-environment-flags/1.0.6: + /node-environment-flags@1.0.6: resolution: {integrity: sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==} dependencies: object.getownpropertydescriptors: 2.1.4 semver: 5.7.1 dev: true - /node-fetch/1.7.3: + /node-fetch@1.7.3: resolution: {integrity: sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==} dependencies: encoding: 0.1.13 is-stream: 1.1.0 dev: true - /node-fetch/2.6.7: + /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} peerDependencies: @@ -8386,36 +8418,36 @@ packages: whatwg-url: 5.0.0 dev: true - /node-gyp-build/4.5.0: + /node-gyp-build@4.5.0: resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} hasBin: true dev: true - /node-interval-tree/2.1.2: + /node-interval-tree@2.1.2: resolution: {integrity: sha512-bJ9zMDuNGzVQg1xv0bCPzyEDxHgbrx7/xGj6CDokvizZZmastPsOh0JJLuY8wA5q2SfX1TLNMk7XNV8WxbGxzA==} engines: {node: '>= 14.0.0'} dependencies: shallowequal: 1.1.0 dev: true - /nofilter/1.0.4: + /nofilter@1.0.4: resolution: {integrity: sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==} engines: {node: '>=8'} dev: true - /nofilter/3.1.0: + /nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} dev: true - /nopt/3.0.6: + /nopt@3.0.6: resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} hasBin: true dependencies: abbrev: 1.1.1 dev: true - /normalize-package-data/2.5.0: + /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 @@ -8424,47 +8456,47 @@ packages: validate-npm-package-license: 3.0.4 dev: true - /normalize-path/3.0.0: + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} dev: true - /normalize-url/4.5.1: + /normalize-url@4.5.1: resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==} engines: {node: '>=8'} dev: true - /normalize-url/6.1.0: + /normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} dev: true - /npm-run-path/4.0.1: + /npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} dependencies: path-key: 3.1.1 dev: true - /npm-run-path/5.1.0: + /npm-run-path@5.1.0: resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: path-key: 4.0.0 dev: true - /nth-check/2.1.1: + /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: boolbase: 1.0.0 dev: true - /number-is-nan/1.0.1: + /number-is-nan@1.0.1: resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} engines: {node: '>=0.10.0'} dev: true - /number-to-bn/1.7.0: + /number-to-bn@1.7.0: resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -8472,16 +8504,16 @@ packages: strip-hex-prefix: 1.0.0 dev: true - /oauth-sign/0.9.0: + /oauth-sign@0.9.0: resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} dev: true - /object-assign/4.1.1: + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} dev: true - /object-copy/0.1.0: + /object-copy@0.1.0: resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} engines: {node: '>=0.10.0'} dependencies: @@ -8490,15 +8522,15 @@ packages: kind-of: 3.2.2 dev: true - /object-inspect/1.12.2: + /object-inspect@1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} dev: true - /object-inspect/1.13.1: + /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: true - /object-is/1.1.5: + /object-is@1.1.5: resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} engines: {node: '>= 0.4'} dependencies: @@ -8506,23 +8538,23 @@ packages: define-properties: 1.2.1 dev: true - /object-keys/0.4.0: + /object-keys@0.4.0: resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==} dev: true - /object-keys/1.1.1: + /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} dev: true - /object-visit/1.0.1: + /object-visit@1.0.1: resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 dev: true - /object.assign/4.1.0: + /object.assign@4.1.0: resolution: {integrity: sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==} engines: {node: '>= 0.4'} dependencies: @@ -8532,7 +8564,7 @@ packages: object-keys: 1.1.1 dev: true - /object.assign/4.1.4: + /object.assign@4.1.4: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} dependencies: @@ -8542,7 +8574,7 @@ packages: object-keys: 1.1.1 dev: true - /object.getownpropertydescriptors/2.1.4: + /object.getownpropertydescriptors@2.1.4: resolution: {integrity: sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==} engines: {node: '>= 0.8'} dependencies: @@ -8552,58 +8584,58 @@ packages: es-abstract: 1.20.3 dev: true - /object.pick/1.3.0: + /object.pick@1.3.0: resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 dev: true - /obliterator/2.0.4: + /obliterator@2.0.4: resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} dev: true - /oboe/2.1.4: + /oboe@2.1.4: resolution: {integrity: sha512-ymBJ4xSC6GBXLT9Y7lirj+xbqBLa+jADGJldGEYG7u8sZbS9GyG+u1Xk9c5cbriKwSpCg41qUhPjvU5xOpvIyQ==} dependencies: http-https: 1.0.0 dev: true optional: true - /oboe/2.1.5: + /oboe@2.1.5: resolution: {integrity: sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==} dependencies: http-https: 1.0.0 dev: true - /on-finished/2.3.0: + /on-finished@2.3.0: resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} dependencies: ee-first: 1.1.1 dev: true - /once/1.4.0: + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 dev: true - /onetime/5.1.2: + /onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 dev: true - /onetime/6.0.0: + /onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} dependencies: mimic-fn: 4.0.0 dev: true - /open/7.4.2: + /open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} dependencies: @@ -8611,7 +8643,7 @@ packages: is-wsl: 2.2.0 dev: true - /open/9.1.0: + /open@9.1.0: resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} engines: {node: '>=14.16'} dependencies: @@ -8621,7 +8653,7 @@ packages: is-wsl: 2.2.0 dev: true - /optionator/0.8.3: + /optionator@0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} dependencies: @@ -8633,7 +8665,7 @@ packages: word-wrap: 1.2.3 dev: true - /optionator/0.9.3: + /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} dependencies: @@ -8645,117 +8677,117 @@ packages: type-check: 0.4.0 dev: true - /os-homedir/1.0.2: + /os-homedir@1.0.2: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} dev: true - /os-locale/1.4.0: + /os-locale@1.4.0: resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} engines: {node: '>=0.10.0'} dependencies: lcid: 1.0.0 dev: true - /os-tmpdir/1.0.2: + /os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} dev: true - /p-cancelable/0.3.0: + /p-cancelable@0.3.0: resolution: {integrity: sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==} engines: {node: '>=4'} dev: true - /p-cancelable/1.1.0: + /p-cancelable@1.1.0: resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} engines: {node: '>=6'} dev: true - /p-cancelable/3.0.0: + /p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} dev: true - /p-finally/1.0.0: + /p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} dev: true - /p-limit/1.3.0: + /p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} engines: {node: '>=4'} dependencies: p-try: 1.0.0 dev: true - /p-limit/2.3.0: + /p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} dependencies: p-try: 2.2.0 dev: true - /p-limit/3.1.0: + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 dev: true - /p-locate/2.0.0: + /p-locate@2.0.0: resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} engines: {node: '>=4'} dependencies: p-limit: 1.3.0 dev: true - /p-locate/3.0.0: + /p-locate@3.0.0: resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} engines: {node: '>=6'} dependencies: p-limit: 2.3.0 dev: true - /p-locate/4.1.0: + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} dependencies: p-limit: 2.3.0 dev: true - /p-locate/5.0.0: + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} dependencies: p-limit: 3.1.0 dev: true - /p-map/4.0.0: + /p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} dependencies: aggregate-error: 3.1.0 dev: true - /p-timeout/1.2.1: + /p-timeout@1.2.1: resolution: {integrity: sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==} engines: {node: '>=4'} dependencies: p-finally: 1.0.0 dev: true - /p-try/1.0.0: + /p-try@1.0.0: resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} engines: {node: '>=4'} dev: true - /p-try/2.2.0: + /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} dev: true - /package-json/8.1.1: + /package-json@8.1.1: resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} engines: {node: '>=14.16'} dependencies: @@ -8765,20 +8797,20 @@ packages: semver: 7.5.4 dev: true - /param-case/2.1.1: + /param-case@2.1.1: resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} dependencies: no-case: 2.3.2 dev: true - /parent-module/1.0.1: + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} dependencies: callsites: 3.1.0 dev: true - /parse-asn1/5.1.5: + /parse-asn1@5.1.5: resolution: {integrity: sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==} dependencies: asn1.js: 4.10.1 @@ -8789,22 +8821,22 @@ packages: safe-buffer: 5.2.1 dev: true - /parse-cache-control/1.0.1: + /parse-cache-control@1.0.1: resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} dev: true - /parse-headers/2.0.3: + /parse-headers@2.0.3: resolution: {integrity: sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==} dev: true - /parse-json/2.2.0: + /parse-json@2.2.0: resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} engines: {node: '>=0.10.0'} dependencies: error-ex: 1.3.2 dev: true - /parse-json/5.2.0: + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: @@ -8814,37 +8846,37 @@ packages: lines-and-columns: 1.2.4 dev: true - /parse5-htmlparser2-tree-adapter/7.0.0: + /parse5-htmlparser2-tree-adapter@7.0.0: resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} dependencies: domhandler: 5.0.3 parse5: 7.1.1 dev: true - /parse5/7.1.1: + /parse5@7.1.1: resolution: {integrity: sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==} dependencies: entities: 4.4.0 dev: true - /parseurl/1.3.3: + /parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} dev: true - /pascal-case/2.0.1: + /pascal-case@2.0.1: resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} dependencies: camel-case: 3.0.0 upper-case-first: 1.1.2 dev: true - /pascalcase/0.1.1: + /pascalcase@0.1.1: resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} engines: {node: '>=0.10.0'} dev: true - /patch-package/6.2.2: + /patch-package@6.2.2: resolution: {integrity: sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg==} engines: {npm: '>5'} hasBin: true @@ -8865,7 +8897,7 @@ packages: - supports-color dev: true - /patch-package/6.4.7: + /patch-package@6.4.7: resolution: {integrity: sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==} engines: {npm: '>5'} hasBin: true @@ -8885,67 +8917,67 @@ packages: tmp: 0.0.33 dev: true - /path-browserify/1.0.1: + /path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: true - /path-case/2.1.1: + /path-case@2.1.1: resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} dependencies: no-case: 2.3.2 dev: true - /path-exists/2.1.0: + /path-exists@2.1.0: resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} engines: {node: '>=0.10.0'} dependencies: pinkie-promise: 2.0.1 dev: true - /path-exists/3.0.0: + /path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} dev: true - /path-exists/4.0.0: + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} dev: true - /path-is-absolute/1.0.1: + /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} dev: true - /path-key/2.0.1: + /path-key@2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} engines: {node: '>=4'} dev: true - /path-key/3.1.1: + /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} dev: true - /path-key/4.0.0: + /path-key@4.0.0: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} dev: true - /path-parse/1.0.7: + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true - /path-starts-with/2.0.1: + /path-starts-with@2.0.1: resolution: {integrity: sha512-wZ3AeiRBRlNwkdUxvBANh0+esnt38DLffHDujZyRHkqkaKHTglnY2EP5UX3b8rdeiSutgO4y9NEJwXezNP5vHg==} engines: {node: '>=8'} dev: true - /path-to-regexp/0.1.7: + /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: true - /path-type/1.1.0: + /path-type@1.1.0: resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} engines: {node: '>=0.10.0'} dependencies: @@ -8954,15 +8986,15 @@ packages: pinkie-promise: 2.0.1 dev: true - /path-type/4.0.0: + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} dev: true - /pathval/1.1.1: + /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - /pbkdf2/3.1.2: + /pbkdf2@3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} dependencies: @@ -8973,89 +9005,89 @@ packages: sha.js: 2.4.11 dev: true - /performance-now/2.1.0: + /performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: true - /picocolors/1.0.0: + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: true - /picomatch/2.3.1: + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: true - /pify/2.3.0: + /pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} dev: true - /pify/4.0.1: + /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} dev: true - /pinkie-promise/2.0.1: + /pinkie-promise@2.0.1: resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} engines: {node: '>=0.10.0'} dependencies: pinkie: 2.0.4 dev: true - /pinkie/2.0.4: + /pinkie@2.0.4: resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} engines: {node: '>=0.10.0'} dev: true - /pluralize/8.0.0: + /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} dev: true - /posix-character-classes/0.1.1: + /posix-character-classes@0.1.1: resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} engines: {node: '>=0.10.0'} dev: true - /postinstall-postinstall/2.1.0: + /postinstall-postinstall@2.1.0: resolution: {integrity: sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==} requiresBuild: true dev: true - /precond/0.2.3: + /precond@0.2.3: resolution: {integrity: sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==} engines: {node: '>= 0.6'} dev: true - /prelude-ls/1.1.2: + /prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} engines: {node: '>= 0.8.0'} dev: true - /prelude-ls/1.2.1: + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} dev: true - /prepend-http/1.0.4: + /prepend-http@1.0.4: resolution: {integrity: sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==} engines: {node: '>=0.10.0'} dev: true - /prepend-http/2.0.0: + /prepend-http@2.0.0: resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} engines: {node: '>=4'} dev: true - /prettier-linter-helpers/1.0.0: + /prettier-linter-helpers@1.0.0: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} dependencies: fast-diff: 1.2.0 dev: true - /prettier-plugin-solidity/1.2.0_prettier@2.8.8: + /prettier-plugin-solidity@1.2.0(prettier@2.8.8): resolution: {integrity: sha512-fgxcUZpVAP+LlRfy5JI5oaAkXGkmsje2VJ5krv/YMm+rcTZbIUwFguSw5f+WFuttMjpDm6wB4UL7WVkArEfiVA==} engines: {node: '>=16'} peerDependencies: @@ -9068,7 +9100,7 @@ packages: dev: true optional: true - /prettier-plugin-solidity/1.2.0_prettier@3.2.1: + /prettier-plugin-solidity@1.2.0(prettier@3.2.1): resolution: {integrity: sha512-fgxcUZpVAP+LlRfy5JI5oaAkXGkmsje2VJ5krv/YMm+rcTZbIUwFguSw5f+WFuttMjpDm6wB4UL7WVkArEfiVA==} engines: {node: '>=16'} peerDependencies: @@ -9080,33 +9112,33 @@ packages: solidity-comments-extractor: 0.0.7 dev: true - /prettier/2.8.8: + /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true dev: true - /prettier/3.2.1: + /prettier@3.2.1: resolution: {integrity: sha512-qSUWshj1IobVbKc226Gw2pync27t0Kf0EdufZa9j7uBSJay1CC+B3K5lAAZoqgX3ASiKuWsk6OmzKRetXNObWg==} engines: {node: '>=14'} hasBin: true dev: true - /private/0.1.8: + /private@0.1.8: resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} engines: {node: '>= 0.6'} dev: true - /process-nextick-args/2.0.1: + /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true - /process/0.5.2: + /process@0.5.2: resolution: {integrity: sha512-oNpcutj+nYX2FjdEW7PGltWhXulAnFlM0My/k48L90hARCOJtvBbQXc/6itV2jDvU5xAAtonP+r6wmQgCcbAUA==} engines: {node: '>= 0.6.0'} dev: true - /promise-to-callback/1.0.0: + /promise-to-callback@1.0.0: resolution: {integrity: sha512-uhMIZmKM5ZteDMfLgJnoSq9GCwsNKrYau73Awf1jIy6/eUcuuZ3P+CD9zUv0kJsIUbU+x6uLNIhXhLHDs1pNPA==} engines: {node: '>=0.10.0'} dependencies: @@ -9114,13 +9146,13 @@ packages: set-immediate-shim: 1.0.1 dev: true - /promise/8.3.0: + /promise@8.3.0: resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} dependencies: asap: 2.0.6 dev: true - /proper-lockfile/4.1.2: + /proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} dependencies: graceful-fs: 4.2.10 @@ -9128,11 +9160,11 @@ packages: signal-exit: 3.0.7 dev: true - /proto-list/1.2.4: + /proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} dev: true - /proxy-addr/2.0.5: + /proxy-addr@2.0.5: resolution: {integrity: sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==} engines: {node: '>= 0.10'} dependencies: @@ -9140,23 +9172,23 @@ packages: ipaddr.js: 1.9.0 dev: true - /proxy-from-env/1.1.0: + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: true - /prr/1.0.1: + /prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} dev: true - /pseudomap/1.0.2: + /pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true - /psl/1.9.0: + /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: true - /public-encrypt/4.0.3: + /public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} dependencies: bn.js: 4.12.0 @@ -9167,15 +9199,15 @@ packages: safe-buffer: 5.2.1 dev: true - /pull-cat/1.1.11: + /pull-cat@1.1.11: resolution: {integrity: sha512-i3w+xZ3DCtTVz8S62hBOuNLRHqVDsHMNZmgrZsjPnsxXUgbWtXEee84lo1XswE7W2a3WHyqsNuDJTjVLAQR8xg==} dev: true - /pull-defer/0.2.3: + /pull-defer@0.2.3: resolution: {integrity: sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==} dev: true - /pull-level/2.0.4: + /pull-level@2.0.4: resolution: {integrity: sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==} dependencies: level-post: 1.0.7 @@ -9187,70 +9219,70 @@ packages: stream-to-pull-stream: 1.7.3 dev: true - /pull-live/1.0.1: + /pull-live@1.0.1: resolution: {integrity: sha512-tkNz1QT5gId8aPhV5+dmwoIiA1nmfDOzJDlOOUpU5DNusj6neNd3EePybJ5+sITr2FwyCs/FVpx74YMCfc8YeA==} dependencies: pull-cat: 1.1.11 pull-stream: 3.6.14 dev: true - /pull-pushable/2.2.0: + /pull-pushable@2.2.0: resolution: {integrity: sha512-M7dp95enQ2kaHvfCt2+DJfyzgCSpWVR2h2kWYnVsW6ZpxQBx5wOu0QWOvQPVoPnBLUZYitYP2y7HyHkLQNeGXg==} dev: true - /pull-stream/3.6.14: + /pull-stream@3.6.14: resolution: {integrity: sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==} dev: true - /pull-window/2.1.4: + /pull-window@2.1.4: resolution: {integrity: sha512-cbDzN76BMlcGG46OImrgpkMf/VkCnupj8JhsrpBw3aWBM9ye345aYnqitmZCgauBkc0HbbRRn9hCnsa3k2FNUg==} dependencies: looper: 2.0.0 dev: true - /pump/3.0.0: + /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 dev: true - /punycode/1.3.2: + /punycode@1.3.2: resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} dev: true - /punycode/2.1.0: + /punycode@2.1.0: resolution: {integrity: sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==} engines: {node: '>=6'} dev: true - /punycode/2.1.1: + /punycode@2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} dev: true - /pure-rand/5.0.3: + /pure-rand@5.0.3: resolution: {integrity: sha512-9N8x1h8dptBQpHyC7aZMS+iNOAm97WMGY0AFrguU1cpfW3I5jINkWe5BIY5md0ofy+1TCIELsVcm/GJXZSaPbw==} dev: true - /qs/6.11.0: + /qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} dependencies: side-channel: 1.0.4 dev: true - /qs/6.5.3: + /qs@6.5.3: resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} engines: {node: '>=0.6'} dev: true - /qs/6.7.0: + /qs@6.7.0: resolution: {integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==} engines: {node: '>=0.6'} dev: true - /query-string/5.1.1: + /query-string@5.1.1: resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} engines: {node: '>=0.10.0'} dependencies: @@ -9259,40 +9291,40 @@ packages: strict-uri-encode: 1.1.0 dev: true - /querystring/0.2.0: + /querystring@0.2.0: resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} engines: {node: '>=0.4.x'} deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. dev: true - /queue-microtask/1.2.3: + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true - /quick-lru/5.1.1: + /quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} dev: true - /randombytes/2.1.0: + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 dev: true - /randomfill/1.0.4: + /randomfill@1.0.4: resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} dependencies: randombytes: 2.1.0 safe-buffer: 5.2.1 dev: true - /range-parser/1.2.1: + /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} dev: true - /raw-body/2.4.0: + /raw-body@2.4.0: resolution: {integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==} engines: {node: '>= 0.8'} dependencies: @@ -9302,7 +9334,7 @@ packages: unpipe: 1.0.0 dev: true - /raw-body/2.5.1: + /raw-body@2.5.1: resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} engines: {node: '>= 0.8'} dependencies: @@ -9312,7 +9344,7 @@ packages: unpipe: 1.0.0 dev: true - /rc/1.2.8: + /rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true dependencies: @@ -9322,7 +9354,7 @@ packages: strip-json-comments: 2.0.1 dev: true - /read-pkg-up/1.0.1: + /read-pkg-up@1.0.1: resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} engines: {node: '>=0.10.0'} dependencies: @@ -9330,7 +9362,7 @@ packages: read-pkg: 1.1.0 dev: true - /read-pkg/1.1.0: + /read-pkg@1.1.0: resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} engines: {node: '>=0.10.0'} dependencies: @@ -9339,7 +9371,7 @@ packages: path-type: 1.1.0 dev: true - /readable-stream/1.0.34: + /readable-stream@1.0.34: resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} dependencies: core-util-is: 1.0.3 @@ -9348,7 +9380,7 @@ packages: string_decoder: 0.10.31 dev: true - /readable-stream/2.3.7: + /readable-stream@2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} dependencies: core-util-is: 1.0.3 @@ -9360,7 +9392,7 @@ packages: util-deprecate: 1.0.2 dev: true - /readable-stream/3.6.0: + /readable-stream@3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} engines: {node: '>= 6'} dependencies: @@ -9369,52 +9401,52 @@ packages: util-deprecate: 1.0.2 dev: true - /readdirp/3.2.0: + /readdirp@3.2.0: resolution: {integrity: sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==} engines: {node: '>= 8'} dependencies: picomatch: 2.3.1 dev: true - /readdirp/3.6.0: + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 dev: true - /rechoir/0.6.2: + /rechoir@0.6.2: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} dependencies: resolve: 1.22.1 dev: true - /recursive-readdir/2.2.2: + /recursive-readdir@2.2.2: resolution: {integrity: sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==} engines: {node: '>=0.10.0'} dependencies: minimatch: 3.0.4 dev: true - /reduce-flatten/2.0.0: + /reduce-flatten@2.0.0: resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} engines: {node: '>=6'} dev: true - /regenerate/1.4.2: + /regenerate@1.4.2: resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} dev: true - /regenerator-runtime/0.11.1: + /regenerator-runtime@0.11.1: resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} dev: true - /regenerator-runtime/0.13.9: + /regenerator-runtime@0.13.9: resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} dev: true - /regenerator-transform/0.10.1: + /regenerator-transform@0.10.1: resolution: {integrity: sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==} dependencies: babel-runtime: 6.26.0 @@ -9422,7 +9454,7 @@ packages: private: 0.1.8 dev: true - /regex-not/1.0.2: + /regex-not@1.0.2: resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} engines: {node: '>=0.10.0'} dependencies: @@ -9430,7 +9462,7 @@ packages: safe-regex: 1.1.0 dev: true - /regexp.prototype.flags/1.4.3: + /regexp.prototype.flags@1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} engines: {node: '>= 0.4'} dependencies: @@ -9439,7 +9471,7 @@ packages: functions-have-names: 1.2.3 dev: true - /regexp.prototype.flags/1.5.1: + /regexp.prototype.flags@1.5.1: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} dependencies: @@ -9448,7 +9480,7 @@ packages: set-function-name: 2.0.1 dev: true - /regexpu-core/2.0.0: + /regexpu-core@2.0.0: resolution: {integrity: sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==} dependencies: regenerate: 1.4.2 @@ -9456,63 +9488,63 @@ packages: regjsparser: 0.1.5 dev: true - /registry-auth-token/5.0.2: + /registry-auth-token@5.0.2: resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} engines: {node: '>=14'} dependencies: '@pnpm/npm-conf': 2.2.2 dev: true - /registry-url/6.0.1: + /registry-url@6.0.1: resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} engines: {node: '>=12'} dependencies: rc: 1.2.8 dev: true - /regjsgen/0.2.0: + /regjsgen@0.2.0: resolution: {integrity: sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==} dev: true - /regjsparser/0.1.5: + /regjsparser@0.1.5: resolution: {integrity: sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==} hasBin: true dependencies: jsesc: 0.5.0 dev: true - /repeat-element/1.1.4: + /repeat-element@1.1.4: resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} engines: {node: '>=0.10.0'} dev: true - /repeat-string/1.6.1: + /repeat-string@1.6.1: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} dev: true - /repeating/2.0.1: + /repeating@2.0.1: resolution: {integrity: sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==} engines: {node: '>=0.10.0'} dependencies: is-finite: 1.1.0 dev: true - /req-cwd/2.0.0: + /req-cwd@2.0.0: resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} engines: {node: '>=4'} dependencies: req-from: 2.0.0 dev: true - /req-from/2.0.0: + /req-from@2.0.0: resolution: {integrity: sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==} engines: {node: '>=4'} dependencies: resolve-from: 3.0.0 dev: true - /request-promise-core/1.1.4_request@2.88.2: + /request-promise-core@1.1.4(request@2.88.2): resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} engines: {node: '>=0.10.0'} peerDependencies: @@ -9522,7 +9554,7 @@ packages: request: 2.88.2 dev: true - /request-promise-native/1.0.9_request@2.88.2: + /request-promise-native@1.0.9(request@2.88.2): resolution: {integrity: sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==} engines: {node: '>=0.12.0'} deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 @@ -9530,12 +9562,12 @@ packages: request: ^2.34 dependencies: request: 2.88.2 - request-promise-core: 1.1.4_request@2.88.2 + request-promise-core: 1.1.4(request@2.88.2) stealthy-require: 1.1.1 tough-cookie: 2.5.0 dev: true - /request/2.88.2: + /request@2.88.2: resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} engines: {node: '>= 6'} deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 @@ -9562,59 +9594,59 @@ packages: uuid: 3.4.0 dev: true - /require-directory/2.1.1: + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} dev: true - /require-from-string/1.2.1: + /require-from-string@1.2.1: resolution: {integrity: sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==} engines: {node: '>=0.10.0'} dev: true - /require-from-string/2.0.2: + /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} dev: true - /require-main-filename/1.0.1: + /require-main-filename@1.0.1: resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} dev: true - /require-main-filename/2.0.0: + /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true - /resolve-alpn/1.2.1: + /resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} dev: true - /resolve-from/3.0.0: + /resolve-from@3.0.0: resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} engines: {node: '>=4'} dev: true - /resolve-from/4.0.0: + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} dev: true - /resolve-url/0.2.1: + /resolve-url@0.2.1: resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} deprecated: https://github.com/lydell/resolve-url#deprecated dev: true - /resolve/1.1.7: + /resolve@1.1.7: resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} dev: true - /resolve/1.17.0: + /resolve@1.17.0: resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} dependencies: path-parse: 1.0.7 dev: true - /resolve/1.22.1: + /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} hasBin: true dependencies: @@ -9623,99 +9655,99 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true - /responselike/1.0.2: + /responselike@1.0.2: resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} dependencies: lowercase-keys: 1.0.1 dev: true - /responselike/2.0.1: + /responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} dependencies: lowercase-keys: 2.0.0 dev: true - /resumer/0.0.0: + /resumer@0.0.0: resolution: {integrity: sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w==} dependencies: through: 2.3.8 dev: true - /ret/0.1.15: + /ret@0.1.15: resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} engines: {node: '>=0.12'} dev: true - /retry/0.12.0: + /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} dev: true - /retry/0.13.1: + /retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} dev: true - /reusify/1.0.4: + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true - /rimraf/2.7.1: + /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} hasBin: true dependencies: glob: 7.2.3 dev: true - /rimraf/3.0.2: + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true dependencies: glob: 7.2.3 dev: true - /ripemd160-min/0.0.6: + /ripemd160-min@0.0.6: resolution: {integrity: sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==} engines: {node: '>=8'} dev: true - /ripemd160/2.0.2: + /ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} dependencies: hash-base: 3.1.0 inherits: 2.0.4 dev: true - /rlp/2.2.7: + /rlp@2.2.7: resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} hasBin: true dependencies: bn.js: 5.2.1 dev: true - /run-applescript/5.0.0: + /run-applescript@5.0.0: resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} engines: {node: '>=12'} dependencies: execa: 5.1.1 dev: true - /run-parallel-limit/1.1.0: + /run-parallel-limit@1.1.0: resolution: {integrity: sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==} dependencies: queue-microtask: 1.2.3 dev: true - /run-parallel/1.1.9: + /run-parallel@1.1.9: resolution: {integrity: sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==} dev: true - /rustbn.js/0.2.0: + /rustbn.js@0.2.0: resolution: {integrity: sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==} dev: true - /safe-array-concat/1.0.1: + /safe-array-concat@1.0.1: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} dependencies: @@ -9725,22 +9757,22 @@ packages: isarray: 2.0.5 dev: true - /safe-buffer/5.1.2: + /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} dev: true - /safe-buffer/5.2.1: + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true - /safe-event-emitter/1.0.1: + /safe-event-emitter@1.0.1: resolution: {integrity: sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==} deprecated: Renamed to @metamask/safe-event-emitter dependencies: events: 3.3.0 dev: true - /safe-regex-test/1.0.0: + /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: call-bind: 1.0.2 @@ -9748,17 +9780,17 @@ packages: is-regex: 1.1.4 dev: true - /safe-regex/1.1.0: + /safe-regex@1.1.0: resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} dependencies: ret: 0.1.15 dev: true - /safer-buffer/2.1.2: + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true - /sc-istanbul/0.4.6: + /sc-istanbul@0.4.6: resolution: {integrity: sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==} hasBin: true dependencies: @@ -9778,21 +9810,21 @@ packages: wordwrap: 1.0.0 dev: true - /scrypt-js/2.0.4: + /scrypt-js@2.0.4: resolution: {integrity: sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==} dev: true - /scrypt-js/3.0.1: + /scrypt-js@3.0.1: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} - /scryptsy/1.2.1: + /scryptsy@1.2.1: resolution: {integrity: sha512-aldIRgMozSJ/Gl6K6qmJZysRP82lz83Wb42vl4PWN8SaLFHIaOzLPc9nUUW2jQN88CuGm5q5HefJ9jZ3nWSmTw==} dependencies: pbkdf2: 3.1.2 dev: true optional: true - /secp256k1/3.7.1: + /secp256k1@3.7.1: resolution: {integrity: sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==} engines: {node: '>=4.0.0'} requiresBuild: true @@ -9807,7 +9839,7 @@ packages: safe-buffer: 5.2.1 dev: true - /secp256k1/4.0.3: + /secp256k1@4.0.3: resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} engines: {node: '>=10.0.0'} requiresBuild: true @@ -9817,31 +9849,31 @@ packages: node-gyp-build: 4.5.0 dev: true - /seedrandom/3.0.1: + /seedrandom@3.0.1: resolution: {integrity: sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==} dev: true - /semaphore/1.1.0: + /semaphore@1.1.0: resolution: {integrity: sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==} engines: {node: '>=0.8.0'} dev: true - /semver/5.4.1: + /semver@5.4.1: resolution: {integrity: sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==} hasBin: true dev: true - /semver/5.7.1: + /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true dev: true - /semver/6.3.0: + /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true dev: true - /semver/7.3.7: + /semver@7.3.7: resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} engines: {node: '>=10'} hasBin: true @@ -9849,7 +9881,7 @@ packages: lru-cache: 6.0.0 dev: true - /semver/7.5.4: + /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} hasBin: true @@ -9857,7 +9889,7 @@ packages: lru-cache: 6.0.0 dev: true - /send/0.17.1: + /send@0.17.1: resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==} engines: {node: '>= 0.8.0'} dependencies: @@ -9878,20 +9910,20 @@ packages: - supports-color dev: true - /sentence-case/2.1.1: + /sentence-case@2.1.1: resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==} dependencies: no-case: 2.3.2 upper-case-first: 1.1.2 dev: true - /serialize-javascript/6.0.0: + /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: randombytes: 2.1.0 dev: true - /serve-static/1.14.1: + /serve-static@1.14.1: resolution: {integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==} engines: {node: '>= 0.8.0'} dependencies: @@ -9903,7 +9935,7 @@ packages: - supports-color dev: true - /servify/0.1.12: + /servify@0.1.12: resolution: {integrity: sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==} engines: {node: '>=6'} dependencies: @@ -9916,11 +9948,11 @@ packages: - supports-color dev: true - /set-blocking/2.0.0: + /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true - /set-function-length/1.1.1: + /set-function-length@1.1.1: resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} engines: {node: '>= 0.4'} dependencies: @@ -9930,7 +9962,7 @@ packages: has-property-descriptors: 1.0.0 dev: true - /set-function-name/2.0.1: + /set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} dependencies: @@ -9939,12 +9971,12 @@ packages: has-property-descriptors: 1.0.0 dev: true - /set-immediate-shim/1.0.1: + /set-immediate-shim@1.0.1: resolution: {integrity: sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ==} engines: {node: '>=0.10.0'} dev: true - /set-value/2.0.1: + /set-value@2.0.1: resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} engines: {node: '>=0.10.0'} dependencies: @@ -9954,23 +9986,23 @@ packages: split-string: 3.1.0 dev: true - /setimmediate/1.0.4: + /setimmediate@1.0.4: resolution: {integrity: sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==} dev: true - /setimmediate/1.0.5: + /setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} dev: true - /setprototypeof/1.1.1: + /setprototypeof@1.1.1: resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} dev: true - /setprototypeof/1.2.0: + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: true - /sha.js/2.4.11: + /sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true dependencies: @@ -9978,55 +10010,55 @@ packages: safe-buffer: 5.2.1 dev: true - /sha1/1.1.1: + /sha1@1.1.1: resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} dependencies: charenc: 0.0.2 crypt: 0.0.2 dev: true - /sha3/1.2.6: + /sha3@1.2.6: resolution: {integrity: sha512-KgLGmJGrmNB4JWVsAV11Yk6KbvsAiygWJc7t5IebWva/0NukNrjJqhtKhzy3Eiv2AKuGvhZZt7dt1mDo7HkoiQ==} requiresBuild: true dependencies: nan: 2.13.2 dev: true - /sha3/2.1.4: + /sha3@2.1.4: resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} dependencies: buffer: 6.0.3 dev: true - /shallowequal/1.1.0: + /shallowequal@1.1.0: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} dev: true - /shebang-command/1.2.0: + /shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} dependencies: shebang-regex: 1.0.0 dev: true - /shebang-command/2.0.0: + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 dev: true - /shebang-regex/1.0.0: + /shebang-regex@1.0.0: resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} engines: {node: '>=0.10.0'} dev: true - /shebang-regex/3.0.0: + /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} dev: true - /shelljs/0.8.3: + /shelljs@0.8.3: resolution: {integrity: sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==} engines: {node: '>=4'} hasBin: true @@ -10036,7 +10068,7 @@ packages: rechoir: 0.6.2 dev: true - /side-channel/1.0.4: + /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: call-bind: 1.0.2 @@ -10044,15 +10076,15 @@ packages: object-inspect: 1.12.2 dev: true - /signal-exit/3.0.7: + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true - /simple-concat/1.0.0: + /simple-concat@1.0.0: resolution: {integrity: sha512-pgxq9iGMSS24atefsqEznXW1Te610qB4pwMdrEg6mxczHh7sPtPyiixkP/VaQic8JjZofnIvT7CDeKlHqfbPBg==} dev: true - /simple-get/2.8.1: + /simple-get@2.8.1: resolution: {integrity: sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==} dependencies: decompress-response: 3.3.0 @@ -10060,22 +10092,22 @@ packages: simple-concat: 1.0.0 dev: true - /slash/1.0.0: + /slash@1.0.0: resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} engines: {node: '>=0.10.0'} dev: true - /slash/2.0.0: + /slash@2.0.0: resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} engines: {node: '>=6'} dev: true - /slash/3.0.0: + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} dev: true - /slice-ansi/4.0.0: + /slice-ansi@4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} dependencies: @@ -10084,13 +10116,13 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true - /snake-case/2.1.0: + /snake-case@2.1.0: resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} dependencies: no-case: 2.3.2 dev: true - /snapdragon-node/2.1.1: + /snapdragon-node@2.1.1: resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} engines: {node: '>=0.10.0'} dependencies: @@ -10099,14 +10131,14 @@ packages: snapdragon-util: 3.0.1 dev: true - /snapdragon-util/3.0.1: + /snapdragon-util@3.0.1: resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /snapdragon/0.8.2: + /snapdragon@0.8.2: resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} engines: {node: '>=0.10.0'} dependencies: @@ -10122,7 +10154,7 @@ packages: - supports-color dev: true - /solc/0.4.26: + /solc@0.4.26: resolution: {integrity: sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==} hasBin: true dependencies: @@ -10133,7 +10165,7 @@ packages: yargs: 4.8.1 dev: true - /solc/0.6.12: + /solc@0.6.12: resolution: {integrity: sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==} engines: {node: '>=8.0.0'} hasBin: true @@ -10148,14 +10180,14 @@ packages: tmp: 0.0.33 dev: true - /solc/0.7.3_debug@4.3.4: + /solc@0.7.3(debug@4.3.4): resolution: {integrity: sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==} engines: {node: '>=8.0.0'} hasBin: true dependencies: command-exists: 1.2.9 commander: 3.0.2 - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2(debug@4.3.4) fs-extra: 0.30.0 js-sha3: 0.8.0 memorystream: 0.3.1 @@ -10166,19 +10198,19 @@ packages: - debug dev: true - /solhint-plugin-prettier/0.1.0_sl2subkwtlymlyf3uzoc3og3za: + /solhint-plugin-prettier@0.1.0(prettier-plugin-solidity@1.2.0)(prettier@3.2.1): resolution: {integrity: sha512-SDOTSM6tZxZ6hamrzl3GUgzF77FM6jZplgL2plFBclj/OjKP8Z3eIPojKU73gRr0MvOS8ACZILn8a5g0VTz/Gw==} peerDependencies: prettier: ^3.0.0 prettier-plugin-solidity: ^1.0.0 dependencies: - '@prettier/sync': 0.3.0_prettier@3.2.1 + '@prettier/sync': 0.3.0(prettier@3.2.1) prettier: 3.2.1 prettier-linter-helpers: 1.0.0 - prettier-plugin-solidity: 1.2.0_prettier@3.2.1 + prettier-plugin-solidity: 1.2.0(prettier@3.2.1) dev: true - /solhint/4.0.0: + /solhint@4.0.0: resolution: {integrity: sha512-bFViMcFvhqVd/HK3Roo7xZXX5nbujS7Bxeg5vnZc9QvH0yCWCrQ38Yrn1pbAY9tlKROc6wFr+rK1mxYgYrjZgA==} hasBin: true dependencies: @@ -10204,13 +10236,13 @@ packages: prettier: 2.8.8 dev: true - /solidity-ast/0.4.55: + /solidity-ast@0.4.55: resolution: {integrity: sha512-qeEU/r/K+V5lrAw8iswf2/yfWAnSGs3WKPHI+zAFKFjX0dIBVXEU/swQ8eJQYHf6PJWUZFO2uWV4V1wEOkeQbA==} dependencies: array.prototype.findlast: 1.2.3 dev: true - /solidity-comments-darwin-arm64/0.0.2: + /solidity-comments-darwin-arm64@0.0.2: resolution: {integrity: sha512-HidWkVLSh7v+Vu0CA7oI21GWP/ZY7ro8g8OmIxE8oTqyMwgMbE8F1yc58Sj682Hj199HCZsjmtn1BE4PCbLiGA==} engines: {node: '>= 10'} cpu: [arm64] @@ -10219,7 +10251,7 @@ packages: dev: true optional: true - /solidity-comments-darwin-x64/0.0.2: + /solidity-comments-darwin-x64@0.0.2: resolution: {integrity: sha512-Zjs0Ruz6faBTPT6fBecUt6qh4CdloT8Bwoc0+qxRoTn9UhYscmbPQkUgQEbS0FQPysYqVzzxJB4h1Ofbf4wwtA==} engines: {node: '>= 10'} cpu: [x64] @@ -10228,11 +10260,11 @@ packages: dev: true optional: true - /solidity-comments-extractor/0.0.7: + /solidity-comments-extractor@0.0.7: resolution: {integrity: sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==} dev: true - /solidity-comments-freebsd-x64/0.0.2: + /solidity-comments-freebsd-x64@0.0.2: resolution: {integrity: sha512-8Qe4mpjuAxFSwZJVk7B8gAoLCdbtS412bQzBwk63L8dmlHogvE39iT70aAk3RHUddAppT5RMBunlPUCFYJ3ZTw==} engines: {node: '>= 10'} cpu: [x64] @@ -10241,7 +10273,7 @@ packages: dev: true optional: true - /solidity-comments-linux-arm64-gnu/0.0.2: + /solidity-comments-linux-arm64-gnu@0.0.2: resolution: {integrity: sha512-spkb0MZZnmrP+Wtq4UxP+nyPAVRe82idOjqndolcNR0S9Xvu4ebwq+LvF4HiUgjTDmeiqYiFZQ8T9KGdLSIoIg==} engines: {node: '>= 10'} cpu: [arm64] @@ -10250,7 +10282,7 @@ packages: dev: true optional: true - /solidity-comments-linux-arm64-musl/0.0.2: + /solidity-comments-linux-arm64-musl@0.0.2: resolution: {integrity: sha512-guCDbHArcjE+JDXYkxx5RZzY1YF6OnAKCo+sTC5fstyW/KGKaQJNPyBNWuwYsQiaEHpvhW1ha537IvlGek8GqA==} engines: {node: '>= 10'} cpu: [arm64] @@ -10259,7 +10291,7 @@ packages: dev: true optional: true - /solidity-comments-linux-x64-gnu/0.0.2: + /solidity-comments-linux-x64-gnu@0.0.2: resolution: {integrity: sha512-zIqLehBK/g7tvrFmQljrfZXfkEeLt2v6wbe+uFu6kH/qAHZa7ybt8Vc0wYcmjo2U0PeBm15d79ee3AkwbIjFdQ==} engines: {node: '>= 10'} cpu: [x64] @@ -10268,7 +10300,7 @@ packages: dev: true optional: true - /solidity-comments-linux-x64-musl/0.0.2: + /solidity-comments-linux-x64-musl@0.0.2: resolution: {integrity: sha512-R9FeDloVlFGTaVkOlELDVC7+1Tjx5WBPI5L8r0AGOPHK3+jOcRh6sKYpI+VskSPDc3vOO46INkpDgUXrKydlIw==} engines: {node: '>= 10'} cpu: [x64] @@ -10277,7 +10309,7 @@ packages: dev: true optional: true - /solidity-comments-win32-arm64-msvc/0.0.2: + /solidity-comments-win32-arm64-msvc@0.0.2: resolution: {integrity: sha512-QnWJoCQcJj+rnutULOihN9bixOtYWDdF5Rfz9fpHejL1BtNjdLW1om55XNVHGAHPqBxV4aeQQ6OirKnp9zKsug==} engines: {node: '>= 10'} cpu: [arm64] @@ -10286,7 +10318,7 @@ packages: dev: true optional: true - /solidity-comments-win32-ia32-msvc/0.0.2: + /solidity-comments-win32-ia32-msvc@0.0.2: resolution: {integrity: sha512-vUg4nADtm/NcOtlIymG23NWJUSuMsvX15nU7ynhGBsdKtt8xhdP3C/zA6vjDk8Jg+FXGQL6IHVQ++g/7rSQi0w==} engines: {node: '>= 10'} cpu: [ia32] @@ -10295,7 +10327,7 @@ packages: dev: true optional: true - /solidity-comments-win32-x64-msvc/0.0.2: + /solidity-comments-win32-x64-msvc@0.0.2: resolution: {integrity: sha512-36j+KUF4V/y0t3qatHm/LF5sCUCBx2UndxE1kq5bOzh/s+nQgatuyB+Pd5BfuPQHdWu2KaExYe20FlAa6NL7+Q==} engines: {node: '>= 10'} cpu: [x64] @@ -10304,7 +10336,7 @@ packages: dev: true optional: true - /solidity-comments/0.0.2: + /solidity-comments@0.0.2: resolution: {integrity: sha512-G+aK6qtyUfkn1guS8uzqUeua1dURwPlcOjoTYW/TwmXAcE7z/1+oGCfZUdMSe4ZMKklNbVZNiG5ibnF8gkkFfw==} engines: {node: '>= 12'} optionalDependencies: @@ -10320,7 +10352,7 @@ packages: solidity-comments-win32-x64-msvc: 0.0.2 dev: true - /solidity-coverage/0.8.5_hardhat@2.19.2: + /solidity-coverage@0.8.5(hardhat@2.19.2): resolution: {integrity: sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ==} hasBin: true peerDependencies: @@ -10336,7 +10368,7 @@ packages: ghost-testrpc: 0.0.2 global-modules: 2.0.0 globby: 10.0.2 - hardhat: 2.19.2_scqxenvmgn24ljurjs2keb5hqa + hardhat: 2.19.2(ts-node@10.9.2)(typescript@5.3.3) jsonschema: 1.4.0 lodash: 4.17.21 mocha: 10.2.0 @@ -10351,13 +10383,13 @@ packages: - supports-color dev: true - /sort-any/2.0.0: + /sort-any@2.0.0: resolution: {integrity: sha512-T9JoiDewQEmWcnmPn/s9h/PH9t3d/LSWi0RgVmXSuDYeZXTZOZ1/wrK2PHaptuR1VXe3clLLt0pD6sgVOwjNEA==} dependencies: lodash: 4.17.21 dev: true - /source-map-resolve/0.5.3: + /source-map-resolve@0.5.3: resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} deprecated: See https://github.com/lydell/source-map-resolve#deprecated dependencies: @@ -10368,32 +10400,32 @@ packages: urix: 0.1.0 dev: true - /source-map-support/0.4.18: + /source-map-support@0.4.18: resolution: {integrity: sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==} dependencies: source-map: 0.5.7 dev: true - /source-map-support/0.5.12: + /source-map-support@0.5.12: resolution: {integrity: sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==} dependencies: buffer-from: 1.1.2 source-map: 0.6.1 dev: true - /source-map-support/0.5.21: + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: buffer-from: 1.1.2 source-map: 0.6.1 dev: true - /source-map-url/0.4.1: + /source-map-url@0.4.1: resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} deprecated: See https://github.com/lydell/source-map-url#deprecated dev: true - /source-map/0.2.0: + /source-map@0.2.0: resolution: {integrity: sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==} engines: {node: '>=0.8.0'} requiresBuild: true @@ -10402,50 +10434,50 @@ packages: dev: true optional: true - /source-map/0.5.7: + /source-map@0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} dev: true - /source-map/0.6.1: + /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} dev: true - /spdx-correct/3.1.1: + /spdx-correct@3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids: 3.0.12 dev: true - /spdx-exceptions/2.3.0: + /spdx-exceptions@2.3.0: resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} dev: true - /spdx-expression-parse/3.0.1: + /spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} dependencies: spdx-exceptions: 2.3.0 spdx-license-ids: 3.0.12 dev: true - /spdx-license-ids/3.0.12: + /spdx-license-ids@3.0.12: resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} dev: true - /split-string/3.1.0: + /split-string@3.1.0: resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} engines: {node: '>=0.10.0'} dependencies: extend-shallow: 3.0.2 dev: true - /sprintf-js/1.0.3: + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true - /sshpk/1.16.1: + /sshpk@1.16.1: resolution: {integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==} engines: {node: '>=0.10.0'} hasBin: true @@ -10461,14 +10493,14 @@ packages: tweetnacl: 0.14.5 dev: true - /stacktrace-parser/0.1.10: + /stacktrace-parser@0.1.10: resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} engines: {node: '>=6'} dependencies: type-fest: 0.7.1 dev: true - /static-extend/0.1.2: + /static-extend@0.1.2: resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} engines: {node: '>=0.10.0'} dependencies: @@ -10476,43 +10508,43 @@ packages: object-copy: 0.1.0 dev: true - /statuses/1.5.0: + /statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} dev: true - /statuses/2.0.1: + /statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} dev: true - /stealthy-require/1.1.1: + /stealthy-require@1.1.1: resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==} engines: {node: '>=0.10.0'} dev: true - /stream-to-pull-stream/1.7.3: + /stream-to-pull-stream@1.7.3: resolution: {integrity: sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==} dependencies: looper: 3.0.0 pull-stream: 3.6.14 dev: true - /streamsearch/1.1.0: + /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} dev: true - /strict-uri-encode/1.1.0: + /strict-uri-encode@1.1.0: resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} engines: {node: '>=0.10.0'} dev: true - /string-format/2.0.0: + /string-format@2.0.0: resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} dev: true - /string-width/1.0.2: + /string-width@1.0.2: resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} engines: {node: '>=0.10.0'} dependencies: @@ -10521,7 +10553,7 @@ packages: strip-ansi: 3.0.1 dev: true - /string-width/2.1.1: + /string-width@2.1.1: resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} engines: {node: '>=4'} dependencies: @@ -10529,7 +10561,7 @@ packages: strip-ansi: 4.0.0 dev: true - /string-width/3.1.0: + /string-width@3.1.0: resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} engines: {node: '>=6'} dependencies: @@ -10538,7 +10570,7 @@ packages: strip-ansi: 5.2.0 dev: true - /string-width/4.2.3: + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} dependencies: @@ -10547,7 +10579,7 @@ packages: strip-ansi: 6.0.1 dev: true - /string.prototype.trim/1.2.8: + /string.prototype.trim@1.2.8: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: @@ -10556,7 +10588,7 @@ packages: es-abstract: 1.22.3 dev: true - /string.prototype.trimend/1.0.5: + /string.prototype.trimend@1.0.5: resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} dependencies: call-bind: 1.0.2 @@ -10564,7 +10596,7 @@ packages: es-abstract: 1.20.3 dev: true - /string.prototype.trimend/1.0.7: + /string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: call-bind: 1.0.5 @@ -10572,7 +10604,7 @@ packages: es-abstract: 1.22.3 dev: true - /string.prototype.trimstart/1.0.5: + /string.prototype.trimstart@1.0.5: resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} dependencies: call-bind: 1.0.2 @@ -10580,7 +10612,7 @@ packages: es-abstract: 1.20.3 dev: true - /string.prototype.trimstart/1.0.7: + /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: call-bind: 1.0.5 @@ -10588,142 +10620,142 @@ packages: es-abstract: 1.22.3 dev: true - /string_decoder/0.10.31: + /string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} dev: true - /string_decoder/1.1.1: + /string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 dev: true - /string_decoder/1.3.0: + /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 dev: true - /strip-ansi/3.0.1: + /strip-ansi@3.0.1: resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} engines: {node: '>=0.10.0'} dependencies: ansi-regex: 2.1.1 dev: true - /strip-ansi/4.0.0: + /strip-ansi@4.0.0: resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} engines: {node: '>=4'} dependencies: ansi-regex: 3.0.1 dev: true - /strip-ansi/5.2.0: + /strip-ansi@5.2.0: resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} engines: {node: '>=6'} dependencies: ansi-regex: 4.1.1 dev: true - /strip-ansi/6.0.1: + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 dev: true - /strip-bom/2.0.0: + /strip-bom@2.0.0: resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} engines: {node: '>=0.10.0'} dependencies: is-utf8: 0.2.1 dev: true - /strip-final-newline/2.0.0: + /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} dev: true - /strip-final-newline/3.0.0: + /strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} dev: true - /strip-hex-prefix/1.0.0: + /strip-hex-prefix@1.0.0: resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: is-hex-prefixed: 1.0.0 dev: true - /strip-indent/2.0.0: + /strip-indent@2.0.0: resolution: {integrity: sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==} engines: {node: '>=4'} dev: true - /strip-json-comments/2.0.1: + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} dev: true - /strip-json-comments/3.1.1: + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: true - /supports-color/2.0.0: + /supports-color@2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} engines: {node: '>=0.8.0'} dev: true - /supports-color/3.2.3: + /supports-color@3.2.3: resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} engines: {node: '>=0.8.0'} dependencies: has-flag: 1.0.0 dev: true - /supports-color/5.5.0: + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 dev: true - /supports-color/6.0.0: + /supports-color@6.0.0: resolution: {integrity: sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==} engines: {node: '>=6'} dependencies: has-flag: 3.0.0 dev: true - /supports-color/7.2.0: + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} dependencies: has-flag: 4.0.0 dev: true - /supports-color/8.1.1: + /supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} dependencies: has-flag: 4.0.0 dev: true - /supports-preserve-symlinks-flag/1.0.0: + /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} dev: true - /swap-case/1.1.2: + /swap-case@1.1.2: resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} dependencies: lower-case: 1.1.4 upper-case: 1.1.3 dev: true - /swarm-js/0.1.40: + /swarm-js@0.1.40: resolution: {integrity: sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==} dependencies: bluebird: 3.7.2 @@ -10743,7 +10775,7 @@ packages: - utf-8-validate dev: true - /sync-request/6.1.0: + /sync-request@6.1.0: resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} engines: {node: '>=8.0.0'} dependencies: @@ -10752,13 +10784,13 @@ packages: then-request: 6.0.2 dev: true - /sync-rpc/1.3.6: + /sync-rpc@1.3.6: resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} dependencies: get-port: 3.2.0 dev: true - /synckit/0.8.5: + /synckit@0.8.5: resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} engines: {node: ^14.18.0 || >=16.0.0} dependencies: @@ -10766,7 +10798,7 @@ packages: tslib: 2.6.2 dev: true - /table-layout/1.0.2: + /table-layout@1.0.2: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} dependencies: @@ -10776,7 +10808,7 @@ packages: wordwrapjs: 4.0.1 dev: true - /table/6.8.1: + /table@6.8.1: resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} engines: {node: '>=10.0.0'} dependencies: @@ -10787,7 +10819,7 @@ packages: strip-ansi: 6.0.1 dev: true - /tape/4.16.1: + /tape@4.16.1: resolution: {integrity: sha512-U4DWOikL5gBYUrlzx+J0oaRedm2vKLFbtA/+BRAXboGWpXO7bMP8ddxlq3Cse2bvXFQ0jZMOj6kk3546mvCdFg==} hasBin: true dependencies: @@ -10808,7 +10840,7 @@ packages: through: 2.3.8 dev: true - /tar/4.4.19: + /tar@4.4.19: resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==} engines: {node: '>=4.5'} dependencies: @@ -10821,7 +10853,7 @@ packages: yallist: 3.1.1 dev: true - /test-value/2.1.0: + /test-value@2.1.0: resolution: {integrity: sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==} engines: {node: '>=0.10.0'} dependencies: @@ -10829,16 +10861,16 @@ packages: typical: 2.6.1 dev: true - /testrpc/0.0.1: + /testrpc@0.0.1: resolution: {integrity: sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==} deprecated: testrpc has been renamed to ganache-cli, please use this package from now on. dev: true - /text-table/0.2.0: + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true - /then-request/6.0.2: + /then-request@6.0.2: resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} engines: {node: '>=6.0.0'} dependencies: @@ -10855,66 +10887,66 @@ packages: qs: 6.11.0 dev: true - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - - /through2/2.0.5: + /through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: readable-stream: 2.3.7 xtend: 4.0.2 dev: true - /timed-out/4.0.1: + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /timed-out@4.0.1: resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} engines: {node: '>=0.10.0'} dev: true - /title-case/2.1.1: + /title-case@2.1.1: resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 dev: true - /titleize/3.0.0: + /titleize@3.0.0: resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} engines: {node: '>=12'} dev: true - /tmp/0.0.33: + /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} dependencies: os-tmpdir: 1.0.2 dev: true - /tmp/0.1.0: + /tmp@0.1.0: resolution: {integrity: sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==} engines: {node: '>=6'} dependencies: rimraf: 2.7.1 dev: true - /to-fast-properties/1.0.3: + /to-fast-properties@1.0.3: resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} engines: {node: '>=0.10.0'} dev: true - /to-object-path/0.3.0: + /to-object-path@0.3.0: resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /to-readable-stream/1.0.0: + /to-readable-stream@1.0.0: resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} engines: {node: '>=6'} dev: true - /to-regex-range/2.1.1: + /to-regex-range@2.1.1: resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} engines: {node: '>=0.10.0'} dependencies: @@ -10922,14 +10954,14 @@ packages: repeat-string: 1.6.1 dev: true - /to-regex-range/5.0.1: + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 dev: true - /to-regex/3.0.2: + /to-regex@3.0.2: resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} engines: {node: '>=0.10.0'} dependencies: @@ -10939,17 +10971,17 @@ packages: safe-regex: 1.1.0 dev: true - /toidentifier/1.0.0: + /toidentifier@1.0.0: resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} engines: {node: '>=0.6'} dev: true - /toidentifier/1.0.1: + /toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} dev: true - /tough-cookie/2.5.0: + /tough-cookie@2.5.0: resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} engines: {node: '>=0.8'} dependencies: @@ -10957,16 +10989,16 @@ packages: punycode: 2.1.1 dev: true - /tr46/0.0.3: + /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: true - /trim-right/1.0.1: + /trim-right@1.0.1: resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} engines: {node: '>=0.10.0'} dev: true - /ts-api-utils/1.0.3_typescript@5.3.3: + /ts-api-utils@1.0.3(typescript@5.3.3): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: @@ -10975,7 +11007,7 @@ packages: typescript: 5.3.3 dev: true - /ts-command-line-args/2.5.1: + /ts-command-line-args@2.5.1: resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} hasBin: true dependencies: @@ -10985,11 +11017,11 @@ packages: string-format: 2.0.0 dev: true - /ts-essentials/1.0.4: + /ts-essentials@1.0.4: resolution: {integrity: sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==} dev: true - /ts-essentials/6.0.7_typescript@5.3.3: + /ts-essentials@6.0.7(typescript@5.3.3): resolution: {integrity: sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==} peerDependencies: typescript: '>=3.7.0' @@ -10997,7 +11029,7 @@ packages: typescript: 5.3.3 dev: true - /ts-essentials/7.0.3_typescript@5.3.3: + /ts-essentials@7.0.3(typescript@5.3.3): resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} peerDependencies: typescript: '>=3.7.0' @@ -11005,7 +11037,7 @@ packages: typescript: 5.3.3 dev: true - /ts-generator/0.1.1: + /ts-generator@0.1.1: resolution: {integrity: sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==} hasBin: true dependencies: @@ -11020,7 +11052,7 @@ packages: ts-essentials: 1.0.4 dev: true - /ts-node/10.9.2_elefmx52zewn5giftcrxd6iwku: + /ts-node@10.9.2(@types/node@16.18.68)(typescript@5.3.3): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: @@ -11051,70 +11083,70 @@ packages: yn: 3.1.1 dev: true - /tslib/1.14.1: + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true - /tslib/2.6.2: + /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: true - /tsort/0.0.1: + /tsort@0.0.1: resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} dev: true - /tunnel-agent/0.6.0: + /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 dev: true - /tweetnacl-util/0.15.1: + /tweetnacl-util@0.15.1: resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} dev: true - /tweetnacl/0.14.5: + /tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} dev: true - /tweetnacl/1.0.3: + /tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} dev: true - /type-check/0.3.2: + /type-check@0.3.2: resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.1.2 dev: true - /type-check/0.4.0: + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 dev: true - /type-detect/4.0.8: + /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - /type-fest/0.20.2: + /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} dev: true - /type-fest/0.21.3: + /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} dev: true - /type-fest/0.7.1: + /type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} dev: true - /type-is/1.6.18: + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} dependencies: @@ -11122,38 +11154,38 @@ packages: mime-types: 2.1.27 dev: true - /type/1.2.0: + /type@1.2.0: resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} dev: true - /type/2.0.0: + /type@2.0.0: resolution: {integrity: sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==} dev: true - /typechain/3.0.0_typescript@5.3.3: + /typechain@3.0.0(typescript@5.3.3): resolution: {integrity: sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==} hasBin: true dependencies: command-line-args: 4.0.7 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) fs-extra: 7.0.1 js-sha3: 0.8.0 lodash: 4.17.21 - ts-essentials: 6.0.7_typescript@5.3.3 + ts-essentials: 6.0.7(typescript@5.3.3) ts-generator: 0.1.1 transitivePeerDependencies: - supports-color - typescript dev: true - /typechain/8.3.2_typescript@5.3.3: + /typechain@8.3.2(typescript@5.3.3): resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} hasBin: true peerDependencies: typescript: '>=4.3.0' dependencies: '@types/prettier': 2.7.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) fs-extra: 7.0.1 glob: 7.1.7 js-sha3: 0.8.0 @@ -11161,13 +11193,13 @@ packages: mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3_typescript@5.3.3 + ts-essentials: 7.0.3(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /typed-array-buffer/1.0.0: + /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} dependencies: @@ -11176,7 +11208,7 @@ packages: is-typed-array: 1.1.12 dev: true - /typed-array-byte-length/1.0.0: + /typed-array-byte-length@1.0.0: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} dependencies: @@ -11186,7 +11218,7 @@ packages: is-typed-array: 1.1.12 dev: true - /typed-array-byte-offset/1.0.0: + /typed-array-byte-offset@1.0.0: resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} engines: {node: '>= 0.4'} dependencies: @@ -11197,7 +11229,7 @@ packages: is-typed-array: 1.1.12 dev: true - /typed-array-length/1.0.4: + /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: call-bind: 1.0.5 @@ -11205,51 +11237,51 @@ packages: is-typed-array: 1.1.12 dev: true - /typedarray-to-buffer/3.1.5: + /typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: is-typedarray: 1.0.0 dev: true - /typedarray/0.0.6: + /typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} dev: true - /typescript/5.3.3: + /typescript@5.3.3: resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true dev: true - /typewise-core/1.2.0: + /typewise-core@1.2.0: resolution: {integrity: sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==} dev: true - /typewise/1.0.3: + /typewise@1.0.3: resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} dependencies: typewise-core: 1.2.0 dev: true - /typewiselite/1.0.0: + /typewiselite@1.0.0: resolution: {integrity: sha512-J9alhjVHupW3Wfz6qFRGgQw0N3gr8hOkw6zm7FZ6UR1Cse/oD9/JVok7DNE9TT9IbciDHX2Ex9+ksE6cRmtymw==} dev: true - /typical/2.6.1: + /typical@2.6.1: resolution: {integrity: sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==} dev: true - /typical/4.0.0: + /typical@4.0.0: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} dev: true - /typical/5.2.0: + /typical@5.2.0: resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} engines: {node: '>=8'} dev: true - /uglify-js/3.17.3: + /uglify-js@3.17.3: resolution: {integrity: sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==} engines: {node: '>=0.8.0'} hasBin: true @@ -11257,11 +11289,11 @@ packages: dev: true optional: true - /ultron/1.1.1: + /ultron@1.1.1: resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} dev: true - /unbox-primitive/1.0.2: + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: call-bind: 1.0.2 @@ -11270,23 +11302,23 @@ packages: which-boxed-primitive: 1.0.2 dev: true - /underscore/1.9.1: + /underscore@1.9.1: resolution: {integrity: sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==} dev: true optional: true - /undici/5.19.1: + /undici@5.19.1: resolution: {integrity: sha512-YiZ61LPIgY73E7syxCDxxa3LV2yl3sN8spnIuTct60boiiRaE1J8mNWHO8Im2Zi/sFrPusjLlmRPrsyraSqX6A==} engines: {node: '>=12.18'} dependencies: busboy: 1.6.0 dev: true - /unfetch/4.2.0: + /unfetch@4.2.0: resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} dev: true - /union-value/1.0.1: + /union-value@1.0.1: resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} engines: {node: '>=0.10.0'} dependencies: @@ -11296,27 +11328,27 @@ packages: set-value: 2.0.1 dev: true - /universalify/0.1.2: + /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} dev: true - /universalify/2.0.0: + /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} dev: true - /unorm/1.6.0: + /unorm@1.6.0: resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} engines: {node: '>= 0.4.0'} dev: true - /unpipe/1.0.0: + /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} dev: true - /unset-value/1.0.0: + /unset-value@1.0.0: resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} engines: {node: '>=0.10.0'} dependencies: @@ -11324,68 +11356,68 @@ packages: isobject: 3.0.1 dev: true - /untildify/4.0.0: + /untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} dev: true - /upper-case-first/1.1.2: + /upper-case-first@1.1.2: resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==} dependencies: upper-case: 1.1.3 dev: true - /upper-case/1.1.3: + /upper-case@1.1.3: resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} dev: true - /uri-js/4.4.1: + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.1.1 dev: true - /urix/0.1.0: + /urix@0.1.0: resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} deprecated: Please see https://github.com/lydell/urix#deprecated dev: true - /url-parse-lax/1.0.0: + /url-parse-lax@1.0.0: resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} engines: {node: '>=0.10.0'} dependencies: prepend-http: 1.0.4 dev: true - /url-parse-lax/3.0.0: + /url-parse-lax@3.0.0: resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} engines: {node: '>=4'} dependencies: prepend-http: 2.0.0 dev: true - /url-set-query/1.0.0: + /url-set-query@1.0.0: resolution: {integrity: sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==} dev: true - /url-to-options/1.0.1: + /url-to-options@1.0.1: resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==} engines: {node: '>= 4'} dev: true - /url/0.11.0: + /url@0.11.0: resolution: {integrity: sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==} dependencies: punycode: 1.3.2 querystring: 0.2.0 dev: true - /use/3.1.1: + /use@3.1.1: resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} engines: {node: '>=0.10.0'} dev: true - /utf-8-validate/5.0.9: + /utf-8-validate@5.0.9: resolution: {integrity: sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==} engines: {node: '>=6.14.2'} requiresBuild: true @@ -11393,15 +11425,15 @@ packages: node-gyp-build: 4.5.0 dev: true - /utf8/3.0.0: + /utf8@3.0.0: resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} dev: true - /util-deprecate/1.0.2: + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true - /util.promisify/1.1.1: + /util.promisify@1.1.1: resolution: {integrity: sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==} dependencies: call-bind: 1.0.5 @@ -11411,7 +11443,7 @@ packages: object.getownpropertydescriptors: 2.1.4 dev: true - /util/0.12.3: + /util@0.12.3: resolution: {integrity: sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==} dependencies: inherits: 2.0.4 @@ -11422,54 +11454,54 @@ packages: which-typed-array: 1.1.4 dev: true - /utils-merge/1.0.1: + /utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} dev: true - /uuid/2.0.1: + /uuid@2.0.1: resolution: {integrity: sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. dev: true - /uuid/3.3.2: + /uuid@3.3.2: resolution: {integrity: sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. hasBin: true dev: true - /uuid/3.4.0: + /uuid@3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. hasBin: true dev: true - /uuid/8.3.2: + /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true dev: true - /v8-compile-cache-lib/3.0.1: + /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true - /validate-npm-package-license/3.0.4: + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: spdx-correct: 3.1.1 spdx-expression-parse: 3.0.1 dev: true - /varint/5.0.2: + /varint@5.0.2: resolution: {integrity: sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==} dev: true - /vary/1.1.2: + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} dev: true - /verror/1.10.0: + /verror@1.10.0: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} dependencies: @@ -11478,7 +11510,7 @@ packages: extsprintf: 1.4.0 dev: true - /web3-bzz/1.2.11: + /web3-bzz@1.2.11: resolution: {integrity: sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==} engines: {node: '>=8.0.0'} dependencies: @@ -11493,7 +11525,7 @@ packages: dev: true optional: true - /web3-bzz/1.7.4: + /web3-bzz@1.7.4: resolution: {integrity: sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -11507,7 +11539,7 @@ packages: - utf-8-validate dev: true - /web3-bzz/1.8.0: + /web3-bzz@1.8.0: resolution: {integrity: sha512-caDtdKeLi7+2Vb+y+cq2yyhkNjnxkFzVW0j1DtemarBg3dycG1iEl75CVQMLNO6Wkg+HH9tZtRnUyFIe5LIUeQ==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -11521,7 +11553,7 @@ packages: - utf-8-validate dev: true - /web3-core-helpers/1.2.11: + /web3-core-helpers@1.2.11: resolution: {integrity: sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==} engines: {node: '>=8.0.0'} dependencies: @@ -11531,7 +11563,7 @@ packages: dev: true optional: true - /web3-core-helpers/1.7.4: + /web3-core-helpers@1.7.4: resolution: {integrity: sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==} engines: {node: '>=8.0.0'} dependencies: @@ -11539,7 +11571,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-core-helpers/1.8.0: + /web3-core-helpers@1.8.0: resolution: {integrity: sha512-nMAVwZB3rEp/khHI2BvFy0e/xCryf501p5NGjswmJtEM+Zrd3Biaw52JrB1qAZZIzCA8cmLKaOgdfamoDOpWdw==} engines: {node: '>=8.0.0'} dependencies: @@ -11547,7 +11579,7 @@ packages: web3-utils: 1.8.0 dev: true - /web3-core-method/1.2.11: + /web3-core-method@1.2.11: resolution: {integrity: sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==} engines: {node: '>=8.0.0'} dependencies: @@ -11560,7 +11592,7 @@ packages: dev: true optional: true - /web3-core-method/1.7.4: + /web3-core-method@1.7.4: resolution: {integrity: sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11571,7 +11603,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-core-method/1.8.0: + /web3-core-method@1.8.0: resolution: {integrity: sha512-c94RAzo3gpXwf2rf8rL8C77jOzNWF4mXUoUfZYYsiY35cJFd46jQDPI00CB5+ZbICTiA5mlVzMj4e7jAsTqiLA==} engines: {node: '>=8.0.0'} dependencies: @@ -11582,7 +11614,7 @@ packages: web3-utils: 1.8.0 dev: true - /web3-core-promievent/1.2.11: + /web3-core-promievent@1.2.11: resolution: {integrity: sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==} engines: {node: '>=8.0.0'} dependencies: @@ -11590,21 +11622,21 @@ packages: dev: true optional: true - /web3-core-promievent/1.7.4: + /web3-core-promievent@1.7.4: resolution: {integrity: sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==} engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.4 dev: true - /web3-core-promievent/1.8.0: + /web3-core-promievent@1.8.0: resolution: {integrity: sha512-FGLyjAuOaAQ+ZhV6iuw9tg/9WvIkSZXKHQ4mdTyQ8MxVraOtFivOCbuLLsGgapfHYX+RPxsc1j1YzQjKoupagQ==} engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.4 dev: true - /web3-core-requestmanager/1.2.11: + /web3-core-requestmanager@1.2.11: resolution: {integrity: sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==} engines: {node: '>=8.0.0'} dependencies: @@ -11618,7 +11650,7 @@ packages: dev: true optional: true - /web3-core-requestmanager/1.7.4: + /web3-core-requestmanager@1.7.4: resolution: {integrity: sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==} engines: {node: '>=8.0.0'} dependencies: @@ -11631,7 +11663,7 @@ packages: - supports-color dev: true - /web3-core-requestmanager/1.8.0: + /web3-core-requestmanager@1.8.0: resolution: {integrity: sha512-2AoYCs3Owl5foWcf4uKPONyqFygSl9T54L8b581U16nsUirjhoTUGK/PBhMDVcLCmW4QQmcY5A8oPFpkQc1TTg==} engines: {node: '>=8.0.0'} dependencies: @@ -11645,7 +11677,7 @@ packages: - supports-color dev: true - /web3-core-subscriptions/1.2.11: + /web3-core-subscriptions@1.2.11: resolution: {integrity: sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==} engines: {node: '>=8.0.0'} dependencies: @@ -11655,7 +11687,7 @@ packages: dev: true optional: true - /web3-core-subscriptions/1.7.4: + /web3-core-subscriptions@1.7.4: resolution: {integrity: sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==} engines: {node: '>=8.0.0'} dependencies: @@ -11663,7 +11695,7 @@ packages: web3-core-helpers: 1.7.4 dev: true - /web3-core-subscriptions/1.8.0: + /web3-core-subscriptions@1.8.0: resolution: {integrity: sha512-7lHVRzDdg0+Gcog55lG6Q3D8JV+jN+4Ly6F8cSn9xFUAwOkdbgdWsjknQG7t7CDWy21DQkvdiY2BJF8S68AqOA==} engines: {node: '>=8.0.0'} dependencies: @@ -11671,7 +11703,7 @@ packages: web3-core-helpers: 1.8.0 dev: true - /web3-core/1.2.11: + /web3-core@1.2.11: resolution: {integrity: sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11687,7 +11719,7 @@ packages: dev: true optional: true - /web3-core/1.7.4: + /web3-core@1.7.4: resolution: {integrity: sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==} engines: {node: '>=8.0.0'} dependencies: @@ -11702,7 +11734,7 @@ packages: - supports-color dev: true - /web3-core/1.8.0: + /web3-core@1.8.0: resolution: {integrity: sha512-9sCA+Z02ci6zoY2bAquFiDjujRwmSKHiSGi4B8IstML8okSytnzXk1izHYSynE7ahIkguhjWAuXFvX76F5rAbA==} engines: {node: '>=8.0.0'} dependencies: @@ -11718,7 +11750,7 @@ packages: - supports-color dev: true - /web3-eth-abi/1.2.11: + /web3-eth-abi@1.2.11: resolution: {integrity: sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==} engines: {node: '>=8.0.0'} dependencies: @@ -11728,7 +11760,7 @@ packages: dev: true optional: true - /web3-eth-abi/1.7.4: + /web3-eth-abi@1.7.4: resolution: {integrity: sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==} engines: {node: '>=8.0.0'} dependencies: @@ -11736,7 +11768,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-eth-abi/1.8.0: + /web3-eth-abi@1.8.0: resolution: {integrity: sha512-xPeMb2hS9YLQK/Q5YZpkcmzoRGM+/R8bogSrYHhNC3hjZSSU0YRH+1ZKK0f9YF4qDZaPMI8tKWIMSCDIpjG6fg==} engines: {node: '>=8.0.0'} dependencies: @@ -11744,7 +11776,7 @@ packages: web3-utils: 1.8.0 dev: true - /web3-eth-accounts/1.2.11: + /web3-eth-accounts@1.2.11: resolution: {integrity: sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==} engines: {node: '>=8.0.0'} dependencies: @@ -11764,7 +11796,7 @@ packages: dev: true optional: true - /web3-eth-accounts/1.7.4: + /web3-eth-accounts@1.7.4: resolution: {integrity: sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==} engines: {node: '>=8.0.0'} dependencies: @@ -11783,7 +11815,7 @@ packages: - supports-color dev: true - /web3-eth-accounts/1.8.0: + /web3-eth-accounts@1.8.0: resolution: {integrity: sha512-HQ/MDSv4bexwJLvnqsM6xpGE7c2NVOqyhzOZFyMUKXbIwIq85T3TaLnM9pCN7XqMpDcfxqiZ3q43JqQVkzHdmw==} engines: {node: '>=8.0.0'} dependencies: @@ -11803,7 +11835,7 @@ packages: - supports-color dev: true - /web3-eth-contract/1.2.11: + /web3-eth-contract@1.2.11: resolution: {integrity: sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==} engines: {node: '>=8.0.0'} dependencies: @@ -11821,7 +11853,7 @@ packages: dev: true optional: true - /web3-eth-contract/1.7.4: + /web3-eth-contract@1.7.4: resolution: {integrity: sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11837,7 +11869,7 @@ packages: - supports-color dev: true - /web3-eth-contract/1.8.0: + /web3-eth-contract@1.8.0: resolution: {integrity: sha512-6xeXhW2YoCrz2Ayf2Vm4srWiMOB6LawkvxWJDnUWJ8SMATg4Pgu42C/j8rz/enXbYWt2IKuj0kk8+QszxQbK+Q==} engines: {node: '>=8.0.0'} dependencies: @@ -11854,7 +11886,7 @@ packages: - supports-color dev: true - /web3-eth-ens/1.2.11: + /web3-eth-ens@1.2.11: resolution: {integrity: sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==} engines: {node: '>=8.0.0'} dependencies: @@ -11872,7 +11904,7 @@ packages: dev: true optional: true - /web3-eth-ens/1.7.4: + /web3-eth-ens@1.7.4: resolution: {integrity: sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==} engines: {node: '>=8.0.0'} dependencies: @@ -11888,7 +11920,7 @@ packages: - supports-color dev: true - /web3-eth-ens/1.8.0: + /web3-eth-ens@1.8.0: resolution: {integrity: sha512-/eFbQEwvsMOEiOhw9/iuRXCsPkqAmHHWuFOrThQkozRgcnSTRnvxkkRC/b6koiT5/HaKeUs4yQDg+/ixsIxZxA==} engines: {node: '>=8.0.0'} dependencies: @@ -11905,7 +11937,7 @@ packages: - supports-color dev: true - /web3-eth-iban/1.2.11: + /web3-eth-iban@1.2.11: resolution: {integrity: sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11914,7 +11946,7 @@ packages: dev: true optional: true - /web3-eth-iban/1.7.4: + /web3-eth-iban@1.7.4: resolution: {integrity: sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==} engines: {node: '>=8.0.0'} dependencies: @@ -11922,7 +11954,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-eth-iban/1.8.0: + /web3-eth-iban@1.8.0: resolution: {integrity: sha512-4RbvUxcMpo/e5811sE3a6inJ2H4+FFqUVmlRYs0RaXaxiHweahSRBNcpO0UWgmlePTolj0rXqPT2oEr0DuC8kg==} engines: {node: '>=8.0.0'} dependencies: @@ -11930,7 +11962,7 @@ packages: web3-utils: 1.8.0 dev: true - /web3-eth-personal/1.2.11: + /web3-eth-personal@1.2.11: resolution: {integrity: sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==} engines: {node: '>=8.0.0'} dependencies: @@ -11945,7 +11977,7 @@ packages: dev: true optional: true - /web3-eth-personal/1.7.4: + /web3-eth-personal@1.7.4: resolution: {integrity: sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==} engines: {node: '>=8.0.0'} dependencies: @@ -11959,7 +11991,7 @@ packages: - supports-color dev: true - /web3-eth-personal/1.8.0: + /web3-eth-personal@1.8.0: resolution: {integrity: sha512-L7FT4nR3HmsfZyIAhFpEctKkYGOjRC2h6iFKs9gnFCHZga8yLcYcGaYOBIoYtaKom99MuGBoosayWt/Twh7F5A==} engines: {node: '>=8.0.0'} dependencies: @@ -11974,7 +12006,7 @@ packages: - supports-color dev: true - /web3-eth/1.2.11: + /web3-eth@1.2.11: resolution: {integrity: sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11996,7 +12028,7 @@ packages: dev: true optional: true - /web3-eth/1.7.4: + /web3-eth@1.7.4: resolution: {integrity: sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==} engines: {node: '>=8.0.0'} dependencies: @@ -12016,7 +12048,7 @@ packages: - supports-color dev: true - /web3-eth/1.8.0: + /web3-eth@1.8.0: resolution: {integrity: sha512-hist52os3OT4TQFB/GxPSMxTh3995sz6LPvQpPvj7ktSbpg9RNSFaSsPlCT63wUAHA3PZb1FemkAIeQM5t72Lw==} engines: {node: '>=8.0.0'} dependencies: @@ -12037,7 +12069,7 @@ packages: - supports-color dev: true - /web3-net/1.2.11: + /web3-net@1.2.11: resolution: {integrity: sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==} engines: {node: '>=8.0.0'} dependencies: @@ -12049,7 +12081,7 @@ packages: dev: true optional: true - /web3-net/1.7.4: + /web3-net@1.7.4: resolution: {integrity: sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==} engines: {node: '>=8.0.0'} dependencies: @@ -12060,7 +12092,7 @@ packages: - supports-color dev: true - /web3-net/1.8.0: + /web3-net@1.8.0: resolution: {integrity: sha512-kX6EAacK7QrOe7DOh0t5yHS5q2kxZmTCxPVwSz9io9xBeE4n4UhmzGJ/VfhP2eM3OPKYeypcR3LEO6zZ8xn2vw==} engines: {node: '>=8.0.0'} dependencies: @@ -12072,7 +12104,7 @@ packages: - supports-color dev: true - /web3-provider-engine/14.2.1: + /web3-provider-engine@14.2.1: resolution: {integrity: sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw==} dependencies: async: 2.6.3 @@ -12102,7 +12134,7 @@ packages: - utf-8-validate dev: true - /web3-providers-http/1.2.11: + /web3-providers-http@1.2.11: resolution: {integrity: sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==} engines: {node: '>=8.0.0'} dependencies: @@ -12111,7 +12143,7 @@ packages: dev: true optional: true - /web3-providers-http/1.7.4: + /web3-providers-http@1.7.4: resolution: {integrity: sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==} engines: {node: '>=8.0.0'} dependencies: @@ -12119,7 +12151,7 @@ packages: xhr2-cookies: 1.1.0 dev: true - /web3-providers-http/1.8.0: + /web3-providers-http@1.8.0: resolution: {integrity: sha512-/MqxwRzExohBWW97mqlCSW/+NHydGRyoEDUS1bAIF2YjfKFwyRtHgrEzOojzkC9JvB+8LofMvbXk9CcltpZapw==} engines: {node: '>=8.0.0'} dependencies: @@ -12131,7 +12163,7 @@ packages: - encoding dev: true - /web3-providers-ipc/1.2.11: + /web3-providers-ipc@1.2.11: resolution: {integrity: sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==} engines: {node: '>=8.0.0'} dependencies: @@ -12141,7 +12173,7 @@ packages: dev: true optional: true - /web3-providers-ipc/1.7.4: + /web3-providers-ipc@1.7.4: resolution: {integrity: sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==} engines: {node: '>=8.0.0'} dependencies: @@ -12149,7 +12181,7 @@ packages: web3-core-helpers: 1.7.4 dev: true - /web3-providers-ipc/1.8.0: + /web3-providers-ipc@1.8.0: resolution: {integrity: sha512-tAXHtVXNUOgehaBU8pzAlB3qhjn/PRpjdzEjzHNFqtRRTwzSEKOJxFeEhaUA4FzHnTlbnrs8ujHWUitcp1elfg==} engines: {node: '>=8.0.0'} dependencies: @@ -12157,7 +12189,7 @@ packages: web3-core-helpers: 1.8.0 dev: true - /web3-providers-ws/1.2.11: + /web3-providers-ws@1.2.11: resolution: {integrity: sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==} engines: {node: '>=8.0.0'} dependencies: @@ -12170,7 +12202,7 @@ packages: dev: true optional: true - /web3-providers-ws/1.7.4: + /web3-providers-ws@1.7.4: resolution: {integrity: sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==} engines: {node: '>=8.0.0'} dependencies: @@ -12181,7 +12213,7 @@ packages: - supports-color dev: true - /web3-providers-ws/1.8.0: + /web3-providers-ws@1.8.0: resolution: {integrity: sha512-bcZtSifsqyJxwkfQYamfdIRp4nhj9eJd7cxHg1uUkfLJK125WP96wyJL1xbPt7qt0MpfnTFn8/UuIqIB6nFENg==} engines: {node: '>=8.0.0'} dependencies: @@ -12192,7 +12224,7 @@ packages: - supports-color dev: true - /web3-shh/1.2.11: + /web3-shh@1.2.11: resolution: {integrity: sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==} engines: {node: '>=8.0.0'} dependencies: @@ -12205,7 +12237,7 @@ packages: dev: true optional: true - /web3-shh/1.7.4: + /web3-shh@1.7.4: resolution: {integrity: sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -12218,7 +12250,7 @@ packages: - supports-color dev: true - /web3-shh/1.8.0: + /web3-shh@1.8.0: resolution: {integrity: sha512-DNRgSa9Jf9xYFUGKSMylrf+zt3MPjhI2qF+UWX07o0y3+uf8zalDGiJOWvIS4upAsdPiKKVJ7co+Neof47OMmg==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -12232,7 +12264,7 @@ packages: - supports-color dev: true - /web3-utils/1.2.11: + /web3-utils@1.2.11: resolution: {integrity: sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==} engines: {node: '>=8.0.0'} dependencies: @@ -12247,7 +12279,7 @@ packages: dev: true optional: true - /web3-utils/1.7.4: + /web3-utils@1.7.4: resolution: {integrity: sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==} engines: {node: '>=8.0.0'} dependencies: @@ -12260,7 +12292,7 @@ packages: utf8: 3.0.0 dev: true - /web3-utils/1.8.0: + /web3-utils@1.8.0: resolution: {integrity: sha512-7nUIl7UWpLVka2f09CMbKOSEvorvHnaugIabU4mj7zfMvm0tSByLcEu3eyV9qgS11qxxLuOkzBIwCstTflhmpQ==} engines: {node: '>=8.0.0'} dependencies: @@ -12273,7 +12305,7 @@ packages: utf8: 3.0.0 dev: true - /web3/1.2.11: + /web3@1.2.11: resolution: {integrity: sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -12292,7 +12324,7 @@ packages: dev: true optional: true - /web3/1.7.4: + /web3@1.7.4: resolution: {integrity: sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -12310,7 +12342,7 @@ packages: - utf-8-validate dev: true - /web3/1.8.0: + /web3@1.8.0: resolution: {integrity: sha512-sldr9stK/SALSJTgI/8qpnDuBJNMGjVR84hJ+AcdQ+MLBGLMGsCDNubCoyO6qgk1/Y9SQ7ignegOI/7BPLoiDA==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -12329,11 +12361,11 @@ packages: - utf-8-validate dev: true - /webidl-conversions/3.0.1: + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true - /websocket/1.0.32: + /websocket@1.0.32: resolution: {integrity: sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==} engines: {node: '>=4.0.0'} dependencies: @@ -12347,7 +12379,7 @@ packages: - supports-color dev: true - /websocket/1.0.34: + /websocket@1.0.34: resolution: {integrity: sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==} engines: {node: '>=4.0.0'} dependencies: @@ -12361,18 +12393,18 @@ packages: - supports-color dev: true - /whatwg-fetch/2.0.4: + /whatwg-fetch@2.0.4: resolution: {integrity: sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==} dev: true - /whatwg-url/5.0.0: + /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 dev: true - /which-boxed-primitive/1.0.2: + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: is-bigint: 1.0.4 @@ -12382,15 +12414,15 @@ packages: is-symbol: 1.0.3 dev: true - /which-module/1.0.0: + /which-module@1.0.0: resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==} dev: true - /which-module/2.0.0: + /which-module@2.0.0: resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} dev: true - /which-typed-array/1.1.13: + /which-typed-array@1.1.13: resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} dependencies: @@ -12401,7 +12433,7 @@ packages: has-tostringtag: 1.0.0 dev: true - /which-typed-array/1.1.4: + /which-typed-array@1.1.4: resolution: {integrity: sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==} engines: {node: '>= 0.4'} dependencies: @@ -12414,14 +12446,14 @@ packages: is-typed-array: 1.1.12 dev: true - /which/1.3.1: + /which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true dependencies: isexe: 2.0.0 dev: true - /which/2.0.2: + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true @@ -12429,28 +12461,28 @@ packages: isexe: 2.0.0 dev: true - /wide-align/1.1.3: + /wide-align@1.1.3: resolution: {integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==} dependencies: string-width: 2.1.1 dev: true - /window-size/0.2.0: + /window-size@0.2.0: resolution: {integrity: sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==} engines: {node: '>= 0.10.0'} hasBin: true dev: true - /word-wrap/1.2.3: + /word-wrap@1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} dev: true - /wordwrap/1.0.0: + /wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: true - /wordwrapjs/4.0.1: + /wordwrapjs@4.0.1: resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} engines: {node: '>=8.0.0'} dependencies: @@ -12458,11 +12490,11 @@ packages: typical: 5.2.0 dev: true - /workerpool/6.2.1: + /workerpool@6.2.1: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: true - /wrap-ansi/2.1.0: + /wrap-ansi@2.1.0: resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} engines: {node: '>=0.10.0'} dependencies: @@ -12470,7 +12502,7 @@ packages: strip-ansi: 3.0.1 dev: true - /wrap-ansi/5.1.0: + /wrap-ansi@5.1.0: resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} engines: {node: '>=6'} dependencies: @@ -12479,7 +12511,7 @@ packages: strip-ansi: 5.2.0 dev: true - /wrap-ansi/7.0.0: + /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} dependencies: @@ -12488,11 +12520,11 @@ packages: strip-ansi: 6.0.1 dev: true - /wrappy/1.0.2: + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true - /ws/3.3.3: + /ws@3.3.3: resolution: {integrity: sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==} peerDependencies: bufferutil: ^4.0.1 @@ -12508,7 +12540,7 @@ packages: ultron: 1.1.1 dev: true - /ws/5.2.3: + /ws@5.2.3: resolution: {integrity: sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==} peerDependencies: bufferutil: ^4.0.1 @@ -12522,7 +12554,7 @@ packages: async-limiter: 1.0.1 dev: true - /ws/7.4.6: + /ws@7.4.6: resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} engines: {node: '>=8.3.0'} peerDependencies: @@ -12534,7 +12566,7 @@ packages: utf-8-validate: optional: true - /ws/7.5.9: + /ws@7.5.9: resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} engines: {node: '>=8.3.0'} peerDependencies: @@ -12547,13 +12579,13 @@ packages: optional: true dev: true - /xhr-request-promise/0.1.2: + /xhr-request-promise@0.1.2: resolution: {integrity: sha512-yAQlCCNLwPgoGxw4k+IdRp1uZ7MZibS4kFw2boSUOesjnmvcxxj73j5a8KavE5Bzas++8P49OpJ4m8qjWGiDsA==} dependencies: xhr-request: 1.1.0 dev: true - /xhr-request/1.1.0: + /xhr-request@1.1.0: resolution: {integrity: sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==} dependencies: buffer-to-arraybuffer: 0.0.5 @@ -12565,7 +12597,13 @@ packages: xhr: 2.5.0 dev: true - /xhr/2.5.0: + /xhr2-cookies@1.1.0: + resolution: {integrity: sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==} + dependencies: + cookiejar: 2.1.2 + dev: true + + /xhr@2.5.0: resolution: {integrity: sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==} dependencies: global: 4.3.2 @@ -12574,75 +12612,69 @@ packages: xtend: 4.0.2 dev: true - /xhr2-cookies/1.1.0: - resolution: {integrity: sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==} - dependencies: - cookiejar: 2.1.2 - dev: true - - /xmlhttprequest/1.8.0: + /xmlhttprequest@1.8.0: resolution: {integrity: sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==} engines: {node: '>=0.4.0'} dev: true - /xtend/2.1.2: + /xtend@2.1.2: resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==} engines: {node: '>=0.4'} dependencies: object-keys: 0.4.0 dev: true - /xtend/4.0.2: + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} dev: true - /y18n/3.2.2: + /y18n@3.2.2: resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} dev: true - /y18n/4.0.3: + /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} dev: true - /y18n/5.0.8: + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} dev: true - /yaeti/0.0.6: + /yaeti@0.0.6: resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} engines: {node: '>=0.10.32'} dev: true - /yallist/3.1.1: + /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} dev: true - /yallist/4.0.0: + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true - /yargs-parser/13.1.2: + /yargs-parser@13.1.2: resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} dependencies: camelcase: 5.3.1 decamelize: 1.2.0 dev: true - /yargs-parser/2.4.1: + /yargs-parser@2.4.1: resolution: {integrity: sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==} dependencies: camelcase: 3.0.0 lodash.assign: 4.2.0 dev: true - /yargs-parser/20.2.4: + /yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} dev: true - /yargs-unparser/1.6.0: + /yargs-unparser@1.6.0: resolution: {integrity: sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==} engines: {node: '>=6'} dependencies: @@ -12651,7 +12683,7 @@ packages: yargs: 13.3.2 dev: true - /yargs-unparser/2.0.0: + /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} dependencies: @@ -12661,7 +12693,7 @@ packages: is-plain-obj: 2.1.0 dev: true - /yargs/13.3.2: + /yargs@13.3.2: resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} dependencies: cliui: 5.0.0 @@ -12676,7 +12708,7 @@ packages: yargs-parser: 13.1.2 dev: true - /yargs/16.2.0: + /yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} dependencies: @@ -12689,7 +12721,7 @@ packages: yargs-parser: 20.2.4 dev: true - /yargs/4.8.1: + /yargs@4.8.1: resolution: {integrity: sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==} dependencies: cliui: 3.2.0 @@ -12708,12 +12740,12 @@ packages: yargs-parser: 2.4.1 dev: true - /yn/3.1.1: + /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} dev: true - /yocto-queue/0.1.0: + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true From ce84ce5057024e4cc13d400a31d418db9fba2a27 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 13 Feb 2024 10:50:27 -0500 Subject: [PATCH 12/98] Add go:generate directive for protobuf (#11997) * Add go:generate directive for protobuf * Add protoc to Makefile * Add protoc binary * Attempt install protoc-gen-go-wsrpc * w * w * w * executable * Update versions --- .github/workflows/ci-core.yml | 2 + .tool-versions | 2 +- GNUmakefile | 7 ++- core/scripts/install-protoc.sh | 54 +++++++++++++++++++ .../relay/evm/mercury/wsrpc/pb/generate.go | 2 + .../relay/evm/mercury/wsrpc/pb/mercury.pb.go | 2 +- .../evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go | 2 +- 7 files changed, 67 insertions(+), 4 deletions(-) create mode 100755 core/scripts/install-protoc.sh create mode 100644 core/services/relay/evm/mercury/wsrpc/pb/generate.go diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index e681f887700..25fbc62e268 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -258,6 +258,8 @@ jobs: uses: ./.github/actions/setup-go with: only-modules: "true" + - name: Install protoc-gen-go-wsrpc + run: curl https://github.com/smartcontractkit/wsrpc/raw/main/cmd/protoc-gen-go-wsrpc/protoc-gen-go-wsrpc --output $HOME/go/bin/protoc-gen-go-wsrpc && chmod +x $HOME/go/bin/protoc-gen-go-wsrpc - name: Setup NodeJS uses: ./.github/actions/setup-nodejs - run: make generate # generate install go deps diff --git a/.tool-versions b/.tool-versions index 2a2362dcfa0..e52a1f25a81 100644 --- a/.tool-versions +++ b/.tool-versions @@ -5,4 +5,4 @@ postgres 13.3 helm 3.10.3 zig 0.10.1 golangci-lint 1.55.2 -protoc 23.2 +protoc 25.1 diff --git a/GNUmakefile b/GNUmakefile index 1a5fe5f24aa..5d804a75a5c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -88,7 +88,7 @@ abigen: ## Build & install abigen. ./tools/bin/build_abigen .PHONY: generate -generate: abigen codecgen mockery ## Execute all go:generate commands. +generate: abigen codecgen mockery protoc ## Execute all go:generate commands. go generate -x ./... .PHONY: testscripts @@ -124,6 +124,11 @@ mockery: $(mockery) ## Install mockery. codecgen: $(codecgen) ## Install codecgen go install github.com/ugorji/go/codec/codecgen@v1.2.10 +.PHONY: protoc +protoc: ## Install protoc + core/scripts/install-protoc.sh 25.1 / + go install google.golang.org/protobuf/cmd/protoc-gen-go@`go list -m -json google.golang.org/protobuf | jq -r .Version` + .PHONY: telemetry-protobuf telemetry-protobuf: $(telemetry-protobuf) ## Generate telemetry protocol buffers. protoc \ diff --git a/core/scripts/install-protoc.sh b/core/scripts/install-protoc.sh new file mode 100755 index 00000000000..8d9dc4085c6 --- /dev/null +++ b/core/scripts/install-protoc.sh @@ -0,0 +1,54 @@ +#!/bin/bash +set -x + + +VERSION=$1 + +if [ "$VERSION" == "" ]; then + echo "version required" + exit 1 +fi + +os=$(uname) +arch=$(uname -m) + +install_dir=$HOME/.local +$install_dir/bin/protoc --version | grep $VERSION +rc=$? +if [ $rc -eq 0 ]; then + # we have the current VERSION + echo "protoc up-to-date @ $VERSION" + exit 0 +fi + + +if [ "$os" == "Linux" ] ; then + os="linux" + if [$arch != "x86_64"]; then + echo "unsupported os $os-$arch update $0" + exit 1 + fi +elif [ "$os" == "Darwin" ] ; then + os="osx" + # make life simply and download the universal binary + arch="universal_binary" +else + echo "unsupported os $os. update $0" + exit 1 +fi + +workdir=$(mktemp -d) +pushd $workdir +pb_url="https://github.com/protocolbuffers/protobuf/releases" +artifact=protoc-$VERSION-$os-$arch.zip +curl -LO $pb_url/download/v${VERSION}/$artifact +if [[ ! -d $install_dir ]]; then + mkdir $install_dir +fi +unzip -uo $artifact -d $install_dir +rm $artifact + +echo "protoc $VERSION installed in $install_dir" +echo "Add $install_dir/bin to PATH" +export PATH=$install_dir/bin:$PATH +popd diff --git a/core/services/relay/evm/mercury/wsrpc/pb/generate.go b/core/services/relay/evm/mercury/wsrpc/pb/generate.go new file mode 100644 index 00000000000..2bb95012d1c --- /dev/null +++ b/core/services/relay/evm/mercury/wsrpc/pb/generate.go @@ -0,0 +1,2 @@ +//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-wsrpc_out=. --go-wsrpc_opt=paths=source_relative mercury.proto +package pb diff --git a/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go b/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go index 2f421931a18..ce4125bd579 100644 --- a/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go +++ b/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.32.0 -// protoc v4.23.2 +// protoc v4.25.1 // source: mercury.proto package pb diff --git a/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go b/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go index 23c78abf533..0c31a1d7ac9 100644 --- a/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go +++ b/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-wsrpc. DO NOT EDIT. // versions: // - protoc-gen-go-wsrpc v0.0.1 -// - protoc v4.23.2 +// - protoc v4.25.1 package pb From e78d3b81fa50dc05d3f7b6c2777a9dbc8a00f1ad Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:57:19 +0100 Subject: [PATCH 13/98] do not call an RPC if it's not Alive (#11999) --- common/client/multi_node.go | 26 +++++++++--- common/client/multi_node_test.go | 70 +++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/common/client/multi_node.go b/common/client/multi_node.go index c03c3fbcd61..ed1a2700c71 100644 --- a/common/client/multi_node.go +++ b/common/client/multi_node.go @@ -406,6 +406,10 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP // main node is used at the end for the return value continue } + + if n.State() != nodeStateAlive { + continue + } // Parallel call made to all other nodes with ignored return value wg.Add(1) go func(n SendOnlyNode[CHAIN_ID, RPC_CLIENT]) { @@ -575,11 +579,14 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } // collectTxResults - refer to SendTransaction comment for implementation details, -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) collectTxResults(ctx context.Context, tx TX, txResults <-chan sendTxResult) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) collectTxResults(ctx context.Context, tx TX, healthyNodesNum int, txResults <-chan sendTxResult) error { + if healthyNodesNum == 0 { + return ErroringNodeError + } // combine context and stop channel to ensure we stop, when signal received ctx, cancel := c.chStop.Ctx(ctx) defer cancel() - requiredResults := int(math.Ceil(float64(len(c.nodes)) * sendTxQuorum)) + requiredResults := int(math.Ceil(float64(healthyNodesNum) * sendTxQuorum)) errorsByCode := map[SendTxReturnCode][]error{} var softTimeoutChan <-chan time.Time var resultsCount int @@ -685,12 +692,16 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return ErroringNodeError } + healthyNodesNum := 0 txResults := make(chan sendTxResult, len(c.nodes)) // Must wrap inside IfNotStopped to avoid waitgroup racing with Close ok := c.IfNotStopped(func() { - c.wg.Add(len(c.sendonlys)) // fire-n-forget, as sendOnlyNodes can not be trusted with result reporting for _, n := range c.sendonlys { + if n.State() != nodeStateAlive { + continue + } + c.wg.Add(1) go func(n SendOnlyNode[CHAIN_ID, RPC_CLIENT]) { defer c.wg.Done() c.broadcastTxAsync(ctx, n, tx) @@ -698,9 +709,14 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } var primaryBroadcastWg sync.WaitGroup - primaryBroadcastWg.Add(len(c.nodes)) txResultsToReport := make(chan sendTxResult, len(c.nodes)) for _, n := range c.nodes { + if n.State() != nodeStateAlive { + continue + } + + healthyNodesNum++ + primaryBroadcastWg.Add(1) go func(n SendOnlyNode[CHAIN_ID, RPC_CLIENT]) { defer primaryBroadcastWg.Done() result := c.broadcastTxAsync(ctx, n, tx) @@ -727,7 +743,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return fmt.Errorf("aborted while broadcasting tx - multiNode is stopped: %w", context.Canceled) } - return c.collectTxResults(ctx, tx, txResults) + return c.collectTxResults(ctx, tx, healthyNodesNum, txResults) } // findFirstIn - returns first existing value for the slice of keys diff --git a/common/client/multi_node_test.go b/common/client/multi_node_test.go index 3ffc82572c2..dabaae57c5d 100644 --- a/common/client/multi_node_test.go +++ b/common/client/multi_node_test.go @@ -535,8 +535,10 @@ func TestMultiNode_BatchCallContextAll(t *testing.T) { // setup ok and failed auxiliary nodes okNode := newMockSendOnlyNode[types.ID, multiNodeRPCClient](t) okNode.On("RPC").Return(okRPC).Once() + okNode.On("State").Return(nodeStateAlive) failedNode := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) failedNode.On("RPC").Return(failedRPC).Once() + failedNode.On("State").Return(nodeStateAlive) // setup main node mainNode := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) @@ -557,6 +559,34 @@ func TestMultiNode_BatchCallContextAll(t *testing.T) { require.NoError(t, err) tests.RequireLogMessage(t, observedLogs, "Secondary node BatchCallContext failed") }) + t.Run("Does not call BatchCallContext for unhealthy nodes", func(t *testing.T) { + // setup RPCs + okRPC := newMultiNodeRPCClient(t) + okRPC.On("BatchCallContext", mock.Anything, mock.Anything).Return(nil).Twice() + + // setup ok and failed auxiliary nodes + healthyNode := newMockSendOnlyNode[types.ID, multiNodeRPCClient](t) + healthyNode.On("RPC").Return(okRPC).Once() + healthyNode.On("State").Return(nodeStateAlive) + deadNode := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) + deadNode.On("State").Return(nodeStateUnreachable) + + // setup main node + mainNode := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) + mainNode.On("RPC").Return(okRPC) + nodeSelector := newMockNodeSelector[types.ID, types.Head[Hashable], multiNodeRPCClient](t) + nodeSelector.On("Select").Return(mainNode).Once() + mn := newTestMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: types.RandomID(), + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{deadNode, mainNode}, + sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{healthyNode, deadNode}, + }) + mn.nodeSelector = nodeSelector + + err := mn.BatchCallContextAll(tests.Context(t), nil) + require.NoError(t, err) + }) } func TestMultiNode_SendTransaction(t *testing.T) { @@ -568,15 +598,20 @@ func TestMultiNode_SendTransaction(t *testing.T) { return Successful } - newNode := func(t *testing.T, txErr error, sendTxRun func(args mock.Arguments)) *mockNode[types.ID, types.Head[Hashable], multiNodeRPCClient] { + newNodeWithState := func(t *testing.T, state nodeState, txErr error, sendTxRun func(args mock.Arguments)) *mockNode[types.ID, types.Head[Hashable], multiNodeRPCClient] { rpc := newMultiNodeRPCClient(t) rpc.On("SendTransaction", mock.Anything, mock.Anything).Return(txErr).Run(sendTxRun).Maybe() node := newMockNode[types.ID, types.Head[Hashable], multiNodeRPCClient](t) node.On("String").Return("node name").Maybe() node.On("RPC").Return(rpc).Maybe() + node.On("State").Return(state).Maybe() node.On("Close").Return(nil).Once() return node } + + newNode := func(t *testing.T, txErr error, sendTxRun func(args mock.Arguments)) *mockNode[types.ID, types.Head[Hashable], multiNodeRPCClient] { + return newNodeWithState(t, nodeStateAlive, txErr, sendTxRun) + } newStartedMultiNode := func(t *testing.T, opts multiNodeOpts) testMultiNode { mn := newTestMultiNode(t, opts) err := mn.StartOnce("startedTestMultiNode", func() error { return nil }) @@ -714,6 +749,39 @@ func TestMultiNode_SendTransaction(t *testing.T) { err = mn.SendTransaction(tests.Context(t), nil) require.EqualError(t, err, "aborted while broadcasting tx - multiNode is stopped: context canceled") }) + t.Run("Returns error if there is no healthy primary nodes", func(t *testing.T) { + mn := newStartedMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: types.RandomID(), + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{newNodeWithState(t, nodeStateUnreachable, nil, nil)}, + sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{newNodeWithState(t, nodeStateUnreachable, nil, nil)}, + classifySendTxError: classifySendTxError, + }) + err := mn.SendTransaction(tests.Context(t), nil) + assert.EqualError(t, err, ErroringNodeError.Error()) + }) + t.Run("Transaction success even if one of the nodes is unhealthy", func(t *testing.T) { + chainID := types.RandomID() + mainNode := newNode(t, nil, nil) + unexpectedCall := func(args mock.Arguments) { + panic("SendTx must not be called for unhealthy node") + } + unhealthyNode := newNodeWithState(t, nodeStateUnreachable, nil, unexpectedCall) + unhealthySendOnlyNode := newNodeWithState(t, nodeStateUnreachable, nil, unexpectedCall) + lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) + mn := newStartedMultiNode(t, multiNodeOpts{ + selectionMode: NodeSelectionModeRoundRobin, + chainID: chainID, + nodes: []Node[types.ID, types.Head[Hashable], multiNodeRPCClient]{mainNode, unhealthyNode}, + sendonlys: []SendOnlyNode[types.ID, multiNodeRPCClient]{unhealthySendOnlyNode, newNode(t, errors.New("unexpected error"), nil)}, + classifySendTxError: classifySendTxError, + logger: lggr, + }) + err := mn.SendTransaction(tests.Context(t), nil) + require.NoError(t, err) + tests.AssertLogCountEventually(t, observedLogs, "Node sent transaction", 2) + tests.AssertLogCountEventually(t, observedLogs, "RPC returned error", 1) + }) } func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { From c97d3c5438d3810f447b05150772133569917214 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 13 Feb 2024 11:13:39 -0500 Subject: [PATCH 14/98] Make logging 'err' consistent (#12011) --- core/services/gateway/connector/connector.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/services/gateway/connector/connector.go b/core/services/gateway/connector/connector.go index 9f809a326c8..a05652607ba 100644 --- a/core/services/gateway/connector/connector.go +++ b/core/services/gateway/connector/connector.go @@ -159,7 +159,7 @@ func (c *gatewayConnector) readLoop(gatewayState *gatewayState) { break } if err = msg.Validate(); err != nil { - c.lggr.Errorw("failed to validate message signature", "id", gatewayState.config.Id, "error", err) + c.lggr.Errorw("failed to validate message signature", "id", gatewayState.config.Id, "err", err) break } c.handler.HandleGatewayMessage(ctx, gatewayState.config.Id, msg) @@ -175,7 +175,7 @@ func (c *gatewayConnector) reconnectLoop(gatewayState *gatewayState) { for { conn, err := gatewayState.wsClient.Connect(ctx, gatewayState.url) if err != nil { - c.lggr.Errorw("connection error", "url", gatewayState.url, "error", err) + c.lggr.Errorw("connection error", "url", gatewayState.url, "err", err) } else { c.lggr.Infow("connected successfully", "url", gatewayState.url) closeCh := gatewayState.conn.Reset(conn) From 453153df6761a6531e60800eeec035cc2f8ac792 Mon Sep 17 00:00:00 2001 From: jinhoonbang Date: Tue, 13 Feb 2024 11:27:28 -0500 Subject: [PATCH 15/98] test vrf listener processes old requests on start up (#11554) * test vrf listener processes old requests on start up * fix linting error * minor build error * fix build * fix build --- .../vrf/v2/integration_helpers_test.go | 143 ++++++++++++++++++ .../vrf/v2/integration_v2_plus_test.go | 21 +++ core/services/vrf/v2/integration_v2_test.go | 21 +++ 3 files changed, 185 insertions(+) diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go index 8dea8177a73..b0ae4266b12 100644 --- a/core/services/vrf/v2/integration_helpers_test.go +++ b/core/services/vrf/v2/integration_helpers_test.go @@ -32,6 +32,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" v22 "github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" @@ -1736,3 +1737,145 @@ func testMaliciousConsumer( } require.Equal(t, 1, len(requests)) } + +func testReplayOldRequestsOnStartUp( + t *testing.T, + ownerKey ethkey.KeyV2, + uni coordinatorV2UniverseCommon, + consumer *bind.TransactOpts, + consumerContract vrftesthelpers.VRFConsumerContract, + consumerContractAddress common.Address, + coordinator v22.CoordinatorV2_X, + coordinatorAddress common.Address, + batchCoordinatorAddress common.Address, + vrfOwnerAddress *common.Address, + vrfVersion vrfcommon.Version, + nativePayment bool, + assertions ...func( + t *testing.T, + coordinator v22.CoordinatorV2_X, + rwfe v22.RandomWordsFulfilled, + subID *big.Int), +) { + sendingKey := cltest.MustGenerateRandomKey(t) + gasLanePriceWei := assets.GWei(10) + config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + simulatedOverrides(t, assets.GWei(10), toml.KeySpecific{ + // Gas lane. + Key: ptr(sendingKey.EIP55Address), + GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, + })(c, s) + c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) + c.Feature.LogPoller = ptr(true) + c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) + }) + app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, sendingKey) + + // Create a subscription and fund with 5 LINK. + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), coordinator, uni.backend, nativePayment) + + // Fund gas lanes. + sendEth(t, ownerKey, uni.backend, sendingKey.Address, 10) + require.NoError(t, app.Start(testutils.Context(t))) + + // Create VRF Key, register it to coordinator and export + vrfkey, err := app.GetKeyStore().VRF().Create() + require.NoError(t, err) + registerProvingKeyHelper(t, uni, coordinator, vrfkey, &defaultMaxGasPrice) + keyHash := vrfkey.PublicKey.MustHash() + + encodedVrfKey, err := app.GetKeyStore().VRF().Export(vrfkey.ID(), testutils.Password) + require.NoError(t, err) + + // Shut down the node before making the randomness request + require.NoError(t, app.Stop()) + + // Make the first randomness request. + numWords := uint32(20) + requestID1, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment) + + // number of blocks to mine before restarting the node + nBlocks := 100 + for i := 0; i < nBlocks; i++ { + uni.backend.Commit() + } + + config, db := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + simulatedOverrides(t, assets.GWei(10), toml.KeySpecific{ + // Gas lane. + Key: ptr(sendingKey.EIP55Address), + GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, + })(c, s) + c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) + c.Feature.LogPoller = ptr(true) + c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) + }) + + // Start a new app and create VRF job using the same VRF key created above + app = cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, sendingKey) + + require.NoError(t, app.Start(testutils.Context(t))) + + vrfKey, err := app.GetKeyStore().VRF().Import(encodedVrfKey, testutils.Password) + require.NoError(t, err) + + incomingConfs := 2 + var vrfOwnerString string + if vrfOwnerAddress != nil { + vrfOwnerString = vrfOwnerAddress.Hex() + } + + spec := testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{ + Name: "vrf-primary", + VRFVersion: vrfVersion, + CoordinatorAddress: coordinatorAddress.Hex(), + BatchCoordinatorAddress: batchCoordinatorAddress.Hex(), + MinIncomingConfirmations: incomingConfs, + PublicKey: vrfKey.PublicKey.String(), + FromAddresses: []string{sendingKey.Address.String()}, + BackoffInitialDelay: 10 * time.Millisecond, + BackoffMaxDelay: time.Second, + V2: true, + GasLanePrice: gasLanePriceWei, + VRFOwnerAddress: vrfOwnerString, + EVMChainID: testutils.SimulatedChainID.String(), + }).Toml() + + jb, err := vrfcommon.ValidatedVRFSpec(spec) + require.NoError(t, err) + t.Log(jb.VRFSpec.PublicKey.MustHash(), vrfKey.PublicKey.MustHash()) + err = app.JobSpawner().CreateJob(&jb) + require.NoError(t, err) + + // Wait until all jobs are active and listening for logs + gomega.NewWithT(t).Eventually(func() bool { + jbs := app.JobSpawner().ActiveJobs() + for _, jb := range jbs { + if jb.Type == job.VRF { + return true + } + } + return false + }, testutils.WaitTimeout(t), 100*time.Millisecond).Should(gomega.BeTrue()) + + // Wait for fulfillment to be queued. + gomega.NewGomegaWithT(t).Eventually(func() bool { + uni.backend.Commit() + runs, err := app.PipelineORM().GetAllRuns() + require.NoError(t, err) + t.Log("runs", len(runs)) + return len(runs) == 1 + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) + + // Mine the fulfillment that was queued. + mine(t, requestID1, subID, uni.backend, db, vrfVersion, testutils.SimulatedChainID) + + // Assert correct state of RandomWordsFulfilled event. + // In particular: + // * success should be true + // * payment should be exactly the amount specified as the premium in the coordinator fee config + rwfe := assertRandomWordsFulfilled(t, requestID1, true, coordinator, nativePayment) + if len(assertions) > 0 { + assertions[0](t, coordinator, rwfe, subID) + } +} diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index a4bb3a9439a..9d89911f0f2 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -1346,3 +1346,24 @@ func TestVRFV2PlusIntegration_CancelSubscription(t *testing.T) { AssertLinkBalance(t, uni.linkContract, uni.neil.From, linkBalanceBeforeCancel.Add(linkBalanceBeforeCancel, linkAmount)) AssertNativeBalance(t, uni.backend, uni.neil.From, nativeBalanceBeforeCancel.Add(nativeBalanceBeforeCancel, nativeAmount)) } + +func TestVRFV2PlusIntegration_ReplayOldRequestsOnStartUp(t *testing.T) { + t.Parallel() + ownerKey := cltest.MustGenerateRandomKey(t) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) + + testReplayOldRequestsOnStartUp( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2Plus, + false, + ) +} diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 79c73059406..39acc3da3e5 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -2231,6 +2231,27 @@ func TestStartingCountsV1(t *testing.T) { assert.Equal(t, uint64(2), countsV2[big.NewInt(0x12).String()]) } +func TestVRFV2Integration_ReplayOldRequestsOnStartUp(t *testing.T) { + t.Parallel() + ownerKey := cltest.MustGenerateRandomKey(t) + uni := newVRFCoordinatorV2Universe(t, ownerKey, 1) + + testReplayOldRequestsOnStartUp( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2, + false, + ) +} + func FindLatestRandomnessRequestedLog(t *testing.T, coordContract v22.CoordinatorV2_X, keyHash [32]byte, From 6ef15c5ba74c6ceac2399a9a639221a3779b361c Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Tue, 13 Feb 2024 17:41:43 +0100 Subject: [PATCH 16/98] Fix lock file version and minor NPM bumps (#11980) * fix lock file version * bump linters * bump solhint * increase solhint --- contracts/package.json | 20 +- contracts/pnpm-lock.yaml | 486 +++++++++++++-------------------------- 2 files changed, 168 insertions(+), 338 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 5d4b6324eee..654ec1d8958 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -18,7 +18,7 @@ "prepublishOnly": "pnpm compile && ./scripts/prepublish_generate_abi_folder", "publish-beta": "pnpm publish --tag beta", "publish-prod": "npm dist-tag add @chainlink/contracts@0.8.0 latest", - "solhint": "solhint --max-warnings 33 \"./src/v0.8/**/*.sol\"" + "solhint": "solhint --max-warnings 20 \"./src/v0.8/**/*.sol\"" }, "files": [ "src/v0.8", @@ -51,17 +51,17 @@ "@types/debug": "^4.1.12", "@types/deep-equal-in-any-order": "^1.0.3", "@types/mocha": "^10.0.6", - "@types/node": "^16.18.68", - "@typescript-eslint/eslint-plugin": "^6.14.0", - "@typescript-eslint/parser": "^6.14.0", + "@types/node": "^16.18.80", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "abi-to-sol": "^0.6.6", "cbor": "^5.2.0", "chai": "^4.3.10", "debug": "^4.3.4", - "eslint": "^8.55.0", + "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "deep-equal-in-any-order": "^2.0.6", - "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-prettier": "^5.1.3", "ethereum-waffle": "^3.4.4", "ethers": "~5.7.2", "hardhat": "~2.19.2", @@ -71,11 +71,11 @@ "hardhat-ignore-warnings": "^0.2.6", "istanbul": "^0.4.5", "moment": "^2.29.4", - "prettier": "^3.1.1", - "prettier-plugin-solidity": "1.2.0", + "prettier": "^3.2.5", + "prettier-plugin-solidity": "1.3.1", "rlp": "^2.2.7", - "solhint": "^4.0.0", - "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.0", + "solhint": "^4.1.1", + "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1", "solhint-plugin-prettier": "^0.1.0", "solidity-coverage": "^0.8.5", "ts-node": "^10.9.2", diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index b8c12e24ea1..e272d62ab4a 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -80,14 +80,14 @@ devDependencies: specifier: ^10.0.6 version: 10.0.6 '@types/node': - specifier: ^16.18.68 - version: 16.18.68 + specifier: ^16.18.80 + version: 16.18.80 '@typescript-eslint/eslint-plugin': - specifier: ^6.14.0 - version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.55.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.14.0 - version: 6.18.1(eslint@8.55.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(eslint@8.56.0)(typescript@5.3.3) abi-to-sol: specifier: ^0.6.6 version: 0.6.6 @@ -104,14 +104,14 @@ devDependencies: specifier: ^2.0.6 version: 2.0.6 eslint: - specifier: ^8.55.0 - version: 8.55.0 + specifier: ^8.56.0 + version: 8.56.0 eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@8.55.0) + version: 9.1.0(eslint@8.56.0) eslint-plugin-prettier: - specifier: ^5.0.1 - version: 5.0.1(eslint-config-prettier@9.1.0)(eslint@8.55.0)(prettier@3.2.1) + specifier: ^5.1.3 + version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.5) ethereum-waffle: specifier: ^3.4.4 version: 3.4.4(typescript@5.3.3) @@ -140,29 +140,29 @@ devDependencies: specifier: ^2.29.4 version: 2.29.4 prettier: - specifier: ^3.1.1 - version: 3.2.1 + specifier: ^3.2.5 + version: 3.2.5 prettier-plugin-solidity: - specifier: 1.2.0 - version: 1.2.0(prettier@3.2.1) + specifier: 1.3.1 + version: 1.3.1(prettier@3.2.5) rlp: specifier: ^2.2.7 version: 2.2.7 solhint: - specifier: ^4.0.0 - version: 4.0.0 + specifier: ^4.1.1 + version: 4.1.1 solhint-plugin-chainlink-solidity: - specifier: git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.0 - version: github.com/smartcontractkit/chainlink-solhint-rules/cfc50b32f95b730304a50deb2e27e88d87115874 + specifier: git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1 + version: github.com/smartcontractkit/chainlink-solhint-rules/1b4c0c2663fcd983589d4f33a2e73908624ed43c solhint-plugin-prettier: specifier: ^0.1.0 - version: 0.1.0(prettier-plugin-solidity@1.2.0)(prettier@3.2.1) + version: 0.1.0(prettier-plugin-solidity@1.3.1)(prettier@3.2.5) solidity-coverage: specifier: ^0.8.5 version: 0.8.5(hardhat@2.19.2) ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@16.18.68)(typescript@5.3.3) + version: 10.9.2(@types/node@16.18.80)(typescript@5.3.3) tslib: specifier: ^2.6.2 version: 2.6.2 @@ -327,13 +327,13 @@ packages: deprecated: Please use @ensdomains/ens-contracts dev: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.55.0 + eslint: 8.56.0 eslint-visitor-keys: 3.4.3 dev: true @@ -359,8 +359,8 @@ packages: - supports-color dev: true - /@eslint/js@8.55.0: - resolution: {integrity: sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==} + /@eslint/js@8.56.0: + resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -493,6 +493,7 @@ packages: /@ethersproject/abi@5.0.0-beta.153: resolution: {integrity: sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==} + requiresBuild: true dependencies: '@ethersproject/address': 5.7.0 '@ethersproject/bignumber': 5.7.0 @@ -1294,16 +1295,9 @@ packages: - supports-color dev: true - /@pkgr/utils@2.4.2: - resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==} + /@pkgr/core@0.1.1: + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - dependencies: - cross-spawn: 7.0.3 - fast-glob: 3.3.1 - is-glob: 4.0.3 - open: 9.1.0 - picocolors: 1.0.0 - tslib: 2.6.2 dev: true /@pnpm/config.env-replace@1.1.0: @@ -1327,12 +1321,12 @@ packages: config-chain: 1.1.13 dev: true - /@prettier/sync@0.3.0(prettier@3.2.1): + /@prettier/sync@0.3.0(prettier@3.2.5): resolution: {integrity: sha512-3dcmCyAxIcxy036h1I7MQU/uEEBq8oLwf1CE3xeze+MPlgkdlb/+w6rGR/1dhp6Hqi17fRS6nvwnOzkESxEkOw==} peerDependencies: prettier: ^3.0.0 dependencies: - prettier: 3.2.1 + prettier: 3.2.5 dev: true /@resolver-engine/core@0.3.3: @@ -1504,6 +1498,10 @@ packages: antlr4ts: 0.5.0-alpha.4 dev: true + /@solidity-parser/parser@0.17.0: + resolution: {integrity: sha512-Nko8R0/kUo391jsEHHxrGM07QFdnPGvlmox4rmH0kNiNAashItAilhy4Mv4pK5gQmW5f4sXAF58fwJbmlkGcVw==} + dev: true + /@szmarczak/http-timer@1.1.2: resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} engines: {node: '>=6'} @@ -1696,13 +1694,13 @@ packages: /@types/bn.js@4.11.6: resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/bn.js@5.1.1: resolution: {integrity: sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/cacheable-request@6.0.2: @@ -1710,14 +1708,14 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 16.18.68 + '@types/node': 16.18.80 '@types/responselike': 1.0.0 dev: true /@types/cbor@5.0.1: resolution: {integrity: sha512-zVqJy2KzusZPLOgyGJDnOIbu3DxIGGqxYbEwtEEe4Z+la8jwIhOyb+GMrlHafs5tvKruwf8f8qOYP6zTvse/pw==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/chai@4.3.11: @@ -1727,7 +1725,7 @@ packages: /@types/concat-stream@1.6.1: resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/debug@4.1.12: @@ -1747,7 +1745,7 @@ packages: /@types/form-data@0.0.33: resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/glob@7.1.1: @@ -1755,7 +1753,7 @@ packages: dependencies: '@types/events': 3.0.0 '@types/minimatch': 3.0.3 - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/http-cache-semantics@4.0.1: @@ -1769,7 +1767,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/lru-cache@5.1.1: @@ -1783,7 +1781,7 @@ packages: /@types/mkdirp@0.5.2: resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/mocha@10.0.6: @@ -1797,7 +1795,7 @@ packages: /@types/node-fetch@2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 form-data: 3.0.1 dev: true @@ -1809,8 +1807,8 @@ packages: resolution: {integrity: sha512-7xHmXm/QJ7cbK2laF+YYD7gb5MggHIIQwqyjin3bpEGiSuvScMQ5JZZXPvRipi1MwckTQbJZROMns/JxdnIL1Q==} dev: true - /@types/node@16.18.68: - resolution: {integrity: sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg==} + /@types/node@16.18.80: + resolution: {integrity: sha512-vFxJ1Iyl7A0+xB0uW1r1v504yItKZLdqg/VZELUZ4H02U0bXAgBisSQ8Erf0DMruNFz9ggoiEv6T8Ll9bTg8Jw==} dev: true /@types/node@8.10.66: @@ -1820,7 +1818,7 @@ packages: /@types/pbkdf2@3.1.0: resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/prettier@2.7.1: @@ -1834,26 +1832,26 @@ packages: /@types/readable-stream@2.3.15: resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 safe-buffer: 5.1.2 dev: true /@types/resolve@0.0.8: resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/secp256k1@4.0.3: resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} dependencies: - '@types/node': 16.18.68 + '@types/node': 16.18.80 dev: true /@types/semver@7.5.0: @@ -1877,8 +1875,8 @@ packages: resolution: {integrity: sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==} dev: true - /@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.55.0)(typescript@5.3.3): - resolution: {integrity: sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==} + /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -1889,13 +1887,13 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.9.1 - '@typescript-eslint/parser': 6.18.1(eslint@8.55.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 6.18.1 - '@typescript-eslint/type-utils': 6.18.1(eslint@8.55.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.18.1(eslint@8.55.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.18.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.55.0 + eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 @@ -1906,8 +1904,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.18.1(eslint@8.55.0)(typescript@5.3.3): - resolution: {integrity: sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==} + /@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1916,27 +1914,27 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.18.1 - '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.18.1 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.55.0 + eslint: 8.56.0 typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.18.1: - resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==} + /@typescript-eslint/scope-manager@6.21.0: + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/visitor-keys': 6.18.1 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 dev: true - /@typescript-eslint/type-utils@6.18.1(eslint@8.55.0)(typescript@5.3.3): - resolution: {integrity: sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==} + /@typescript-eslint/type-utils@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1945,23 +1943,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) - '@typescript-eslint/utils': 6.18.1(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.55.0 + eslint: 8.56.0 ts-api-utils: 1.0.3(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.18.1: - resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==} + /@typescript-eslint/types@6.21.0: + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3): - resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==} + /@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3): + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -1969,8 +1967,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/visitor-keys': 6.18.1 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 @@ -1982,30 +1980,30 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@6.18.1(eslint@8.55.0)(typescript@5.3.3): - resolution: {integrity: sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==} + /@typescript-eslint/utils@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.13 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 6.18.1 - '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) - eslint: 8.55.0 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + eslint: 8.56.0 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@6.18.1: - resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==} + /@typescript-eslint/visitor-keys@6.21.0: + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 dev: true @@ -2038,7 +2036,7 @@ packages: source-map-support: 0.5.21 optionalDependencies: prettier: 2.8.8 - prettier-plugin-solidity: 1.2.0(prettier@2.8.8) + prettier-plugin-solidity: 1.3.1(prettier@2.8.8) transitivePeerDependencies: - supports-color dev: true @@ -2128,6 +2126,7 @@ packages: /aes-js@3.1.2: resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} + requiresBuild: true dev: true optional: true @@ -2181,6 +2180,7 @@ packages: /amdefine@1.0.1: resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} engines: {node: '>=0.4.2'} + requiresBuild: true dev: true optional: true @@ -3080,11 +3080,6 @@ packages: engines: {node: '>=0.6'} dev: true - /big-integer@1.6.51: - resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} - engines: {node: '>=0.6'} - dev: true - /big.js@6.2.1: resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} dev: true @@ -3176,13 +3171,6 @@ packages: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true - /bplist-parser@0.2.0: - resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} - engines: {node: '>= 5.10.0'} - dependencies: - big-integer: 1.6.51 - dev: true - /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -3366,13 +3354,6 @@ packages: engines: {node: '>=8.0.0'} dev: false - /bundle-name@3.0.0: - resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} - engines: {node: '>=12'} - dependencies: - run-applescript: 5.0.0 - dev: true - /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -4267,24 +4248,6 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true - /default-browser-id@3.0.0: - resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} - engines: {node: '>=12'} - dependencies: - bplist-parser: 0.2.0 - untildify: 4.0.0 - dev: true - - /default-browser@4.0.0: - resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} - engines: {node: '>=14.16'} - dependencies: - bundle-name: 3.0.0 - default-browser-id: 3.0.0 - execa: 7.2.0 - titleize: 3.0.0 - dev: true - /defer-to-connect@1.1.1: resolution: {integrity: sha512-J7thop4u3mRTkYRQ+Vpfwy2G5Ehoy82I14+14W4YMDLKdWloI9gSzRbV30s/NckQGVJtPkWNcW4oMAUigTdqiQ==} dev: true @@ -4317,11 +4280,6 @@ packages: has-property-descriptors: 1.0.0 dev: true - /define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - dev: true - /define-properties@1.1.4: resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} engines: {node: '>= 0.4'} @@ -4781,17 +4739,17 @@ packages: source-map: 0.2.0 dev: true - /eslint-config-prettier@9.1.0(eslint@8.55.0): + /eslint-config-prettier@9.1.0(eslint@8.56.0): resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.55.0 + eslint: 8.56.0 dev: true - /eslint-plugin-prettier@5.0.1(eslint-config-prettier@9.1.0)(eslint@8.55.0)(prettier@3.2.1): - resolution: {integrity: sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==} + /eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.5): + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -4804,11 +4762,11 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.55.0 - eslint-config-prettier: 9.1.0(eslint@8.55.0) - prettier: 3.2.1 + eslint: 8.56.0 + eslint-config-prettier: 9.1.0(eslint@8.56.0) + prettier: 3.2.5 prettier-linter-helpers: 1.0.0 - synckit: 0.8.5 + synckit: 0.8.8 dev: true /eslint-scope@7.2.2: @@ -4824,15 +4782,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.55.0: - resolution: {integrity: sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==} + /eslint@8.56.0: + resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@eslint-community/regexpp': 4.9.1 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.55.0 + '@eslint/js': 8.56.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -5405,6 +5363,7 @@ packages: is-hex-prefixed: 1.0.0 strip-hex-prefix: 1.0.0 dev: true + bundledDependencies: false /eventemitter3@4.0.4: resolution: {integrity: sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==} @@ -5422,36 +5381,6 @@ packages: safe-buffer: 5.2.1 dev: true - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /execa@7.2.0: - resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.1.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - dev: true - /expand-brackets@2.1.4: resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} engines: {node: '>=0.10.0'} @@ -6432,7 +6361,7 @@ packages: solc: 0.7.3(debug@4.3.4) source-map-support: 0.5.21 stacktrace-parser: 0.1.10 - ts-node: 10.9.2(@types/node@16.18.68)(typescript@5.3.3) + ts-node: 10.9.2(@types/node@16.18.80)(typescript@5.3.3) tsort: 0.0.1 typescript: 5.3.3 undici: 5.19.1 @@ -6706,16 +6635,6 @@ packages: - supports-color dev: true - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true - - /human-signals@4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} - dev: true - /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -6961,12 +6880,6 @@ packages: hasBin: true dev: true - /is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - dev: true - /is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -7032,14 +6945,6 @@ packages: engines: {node: '>=6.5.0', npm: '>=3'} dev: true - /is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - dependencies: - is-docker: 3.0.0 - dev: true - /is-lower-case@1.1.3: resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} dependencies: @@ -7120,16 +7025,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -7955,10 +7850,6 @@ packages: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} dev: true - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -8049,16 +7940,6 @@ packages: hasBin: true dev: true - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true - - /mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - dev: true - /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -8471,20 +8352,6 @@ packages: engines: {node: '>=10'} dev: true - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - dev: true - - /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - path-key: 4.0.0 - dev: true - /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: @@ -8597,6 +8464,7 @@ packages: /oboe@2.1.4: resolution: {integrity: sha512-ymBJ4xSC6GBXLT9Y7lirj+xbqBLa+jADGJldGEYG7u8sZbS9GyG+u1Xk9c5cbriKwSpCg41qUhPjvU5xOpvIyQ==} + requiresBuild: true dependencies: http-https: 1.0.0 dev: true @@ -8621,20 +8489,6 @@ packages: wrappy: 1.0.2 dev: true - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - - /onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - dependencies: - mimic-fn: 4.0.0 - dev: true - /open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} @@ -8643,16 +8497,6 @@ packages: is-wsl: 2.2.0 dev: true - /open@9.1.0: - resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} - engines: {node: '>=14.16'} - dependencies: - default-browser: 4.0.0 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - is-wsl: 2.2.0 - dev: true - /optionator@0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} @@ -8959,11 +8803,6 @@ packages: engines: {node: '>=8'} dev: true - /path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - dev: true - /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true @@ -9009,10 +8848,6 @@ packages: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: true - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -9087,29 +8922,29 @@ packages: fast-diff: 1.2.0 dev: true - /prettier-plugin-solidity@1.2.0(prettier@2.8.8): - resolution: {integrity: sha512-fgxcUZpVAP+LlRfy5JI5oaAkXGkmsje2VJ5krv/YMm+rcTZbIUwFguSw5f+WFuttMjpDm6wB4UL7WVkArEfiVA==} + /prettier-plugin-solidity@1.3.1(prettier@2.8.8): + resolution: {integrity: sha512-MN4OP5I2gHAzHZG1wcuJl0FsLS3c4Cc5494bbg+6oQWBPuEamjwDvmGfFMZ6NFzsh3Efd9UUxeT7ImgjNH4ozA==} engines: {node: '>=16'} peerDependencies: prettier: '>=2.3.0' dependencies: - '@solidity-parser/parser': 0.16.2 + '@solidity-parser/parser': 0.17.0 prettier: 2.8.8 semver: 7.5.4 - solidity-comments-extractor: 0.0.7 + solidity-comments-extractor: 0.0.8 dev: true optional: true - /prettier-plugin-solidity@1.2.0(prettier@3.2.1): - resolution: {integrity: sha512-fgxcUZpVAP+LlRfy5JI5oaAkXGkmsje2VJ5krv/YMm+rcTZbIUwFguSw5f+WFuttMjpDm6wB4UL7WVkArEfiVA==} + /prettier-plugin-solidity@1.3.1(prettier@3.2.5): + resolution: {integrity: sha512-MN4OP5I2gHAzHZG1wcuJl0FsLS3c4Cc5494bbg+6oQWBPuEamjwDvmGfFMZ6NFzsh3Efd9UUxeT7ImgjNH4ozA==} engines: {node: '>=16'} peerDependencies: prettier: '>=2.3.0' dependencies: - '@solidity-parser/parser': 0.16.2 - prettier: 3.2.1 + '@solidity-parser/parser': 0.17.0 + prettier: 3.2.5 semver: 7.5.4 - solidity-comments-extractor: 0.0.7 + solidity-comments-extractor: 0.0.8 dev: true /prettier@2.8.8: @@ -9118,8 +8953,8 @@ packages: hasBin: true dev: true - /prettier@3.2.1: - resolution: {integrity: sha512-qSUWshj1IobVbKc226Gw2pync27t0Kf0EdufZa9j7uBSJay1CC+B3K5lAAZoqgX3ASiKuWsk6OmzKRetXNObWg==} + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true dev: true @@ -9726,13 +9561,6 @@ packages: bn.js: 5.2.1 dev: true - /run-applescript@5.0.0: - resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} - engines: {node: '>=12'} - dependencies: - execa: 5.1.1 - dev: true - /run-parallel-limit@1.1.0: resolution: {integrity: sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==} dependencies: @@ -9819,6 +9647,7 @@ packages: /scryptsy@1.2.1: resolution: {integrity: sha512-aldIRgMozSJ/Gl6K6qmJZysRP82lz83Wb42vl4PWN8SaLFHIaOzLPc9nUUW2jQN88CuGm5q5HefJ9jZ3nWSmTw==} + requiresBuild: true dependencies: pbkdf2: 3.1.2 dev: true @@ -10198,23 +10027,23 @@ packages: - debug dev: true - /solhint-plugin-prettier@0.1.0(prettier-plugin-solidity@1.2.0)(prettier@3.2.1): + /solhint-plugin-prettier@0.1.0(prettier-plugin-solidity@1.3.1)(prettier@3.2.5): resolution: {integrity: sha512-SDOTSM6tZxZ6hamrzl3GUgzF77FM6jZplgL2plFBclj/OjKP8Z3eIPojKU73gRr0MvOS8ACZILn8a5g0VTz/Gw==} peerDependencies: prettier: ^3.0.0 prettier-plugin-solidity: ^1.0.0 dependencies: - '@prettier/sync': 0.3.0(prettier@3.2.1) - prettier: 3.2.1 + '@prettier/sync': 0.3.0(prettier@3.2.5) + prettier: 3.2.5 prettier-linter-helpers: 1.0.0 - prettier-plugin-solidity: 1.2.0(prettier@3.2.1) + prettier-plugin-solidity: 1.3.1(prettier@3.2.5) dev: true - /solhint@4.0.0: - resolution: {integrity: sha512-bFViMcFvhqVd/HK3Roo7xZXX5nbujS7Bxeg5vnZc9QvH0yCWCrQ38Yrn1pbAY9tlKROc6wFr+rK1mxYgYrjZgA==} + /solhint@4.1.1: + resolution: {integrity: sha512-7G4iF8H5hKHc0tR+/uyZesSKtfppFIMvPSW+Ku6MSL25oVRuyFeqNhOsXHfkex64wYJyXs4fe+pvhB069I19Tw==} hasBin: true dependencies: - '@solidity-parser/parser': 0.16.0 + '@solidity-parser/parser': 0.16.2 ajv: 6.12.6 antlr4: 4.13.0 ast-parents: 0.0.1 @@ -10260,8 +10089,8 @@ packages: dev: true optional: true - /solidity-comments-extractor@0.0.7: - resolution: {integrity: sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==} + /solidity-comments-extractor@0.0.8: + resolution: {integrity: sha512-htM7Vn6LhHreR+EglVMd2s+sZhcXAirB1Zlyrv5zBuTxieCvjfnRpd7iZk75m/u6NOlEyQ94C6TWbBn2cY7w8g==} dev: true /solidity-comments-freebsd-x64@0.0.2: @@ -10671,16 +10500,6 @@ packages: is-utf8: 0.2.1 dev: true - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true - - /strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - dev: true - /strip-hex-prefix@1.0.0: resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} engines: {node: '>=6.5.0', npm: '>=3'} @@ -10790,11 +10609,11 @@ packages: get-port: 3.2.0 dev: true - /synckit@0.8.5: - resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} + /synckit@0.8.8: + resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} engines: {node: ^14.18.0 || >=16.0.0} dependencies: - '@pkgr/utils': 2.4.2 + '@pkgr/core': 0.1.1 tslib: 2.6.2 dev: true @@ -10910,11 +10729,6 @@ packages: upper-case: 1.1.3 dev: true - /titleize@3.0.0: - resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} - engines: {node: '>=12'} - dev: true - /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -11052,7 +10866,7 @@ packages: ts-essentials: 1.0.4 dev: true - /ts-node@10.9.2(@types/node@16.18.68)(typescript@5.3.3): + /ts-node@10.9.2(@types/node@16.18.80)(typescript@5.3.3): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: @@ -11071,7 +10885,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 - '@types/node': 16.18.68 + '@types/node': 16.18.80 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -11304,6 +11118,7 @@ packages: /underscore@1.9.1: resolution: {integrity: sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==} + requiresBuild: true dev: true optional: true @@ -11356,11 +11171,6 @@ packages: isobject: 3.0.1 dev: true - /untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: true - /upper-case-first@1.1.2: resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==} dependencies: @@ -11513,6 +11323,7 @@ packages: /web3-bzz@1.2.11: resolution: {integrity: sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/node': 12.19.16 got: 9.6.0 @@ -11556,6 +11367,7 @@ packages: /web3-core-helpers@1.2.11: resolution: {integrity: sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: underscore: 1.9.1 web3-eth-iban: 1.2.11 @@ -11582,6 +11394,7 @@ packages: /web3-core-method@1.2.11: resolution: {integrity: sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@ethersproject/transactions': 5.7.0 underscore: 1.9.1 @@ -11617,6 +11430,7 @@ packages: /web3-core-promievent@1.2.11: resolution: {integrity: sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: eventemitter3: 4.0.4 dev: true @@ -11639,6 +11453,7 @@ packages: /web3-core-requestmanager@1.2.11: resolution: {integrity: sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: underscore: 1.9.1 web3-core-helpers: 1.2.11 @@ -11680,6 +11495,7 @@ packages: /web3-core-subscriptions@1.2.11: resolution: {integrity: sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: eventemitter3: 4.0.4 underscore: 1.9.1 @@ -11706,6 +11522,7 @@ packages: /web3-core@1.2.11: resolution: {integrity: sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/bn.js': 4.11.6 '@types/node': 12.19.16 @@ -11753,6 +11570,7 @@ packages: /web3-eth-abi@1.2.11: resolution: {integrity: sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@ethersproject/abi': 5.0.0-beta.153 underscore: 1.9.1 @@ -11779,6 +11597,7 @@ packages: /web3-eth-accounts@1.2.11: resolution: {integrity: sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: crypto-browserify: 3.12.0 eth-lib: 0.2.8 @@ -11838,6 +11657,7 @@ packages: /web3-eth-contract@1.2.11: resolution: {integrity: sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/bn.js': 4.11.6 underscore: 1.9.1 @@ -11889,6 +11709,7 @@ packages: /web3-eth-ens@1.2.11: resolution: {integrity: sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: content-hash: 2.5.2 eth-ens-namehash: 2.0.8 @@ -11940,6 +11761,7 @@ packages: /web3-eth-iban@1.2.11: resolution: {integrity: sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: bn.js: 4.12.0 web3-utils: 1.2.11 @@ -11965,6 +11787,7 @@ packages: /web3-eth-personal@1.2.11: resolution: {integrity: sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/node': 12.19.16 web3-core: 1.2.11 @@ -12009,6 +11832,7 @@ packages: /web3-eth@1.2.11: resolution: {integrity: sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: underscore: 1.9.1 web3-core: 1.2.11 @@ -12072,6 +11896,7 @@ packages: /web3-net@1.2.11: resolution: {integrity: sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: web3-core: 1.2.11 web3-core-method: 1.2.11 @@ -12137,6 +11962,7 @@ packages: /web3-providers-http@1.2.11: resolution: {integrity: sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: web3-core-helpers: 1.2.11 xhr2-cookies: 1.1.0 @@ -12166,6 +11992,7 @@ packages: /web3-providers-ipc@1.2.11: resolution: {integrity: sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: oboe: 2.1.4 underscore: 1.9.1 @@ -12192,6 +12019,7 @@ packages: /web3-providers-ws@1.2.11: resolution: {integrity: sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: eventemitter3: 4.0.4 underscore: 1.9.1 @@ -12227,6 +12055,7 @@ packages: /web3-shh@1.2.11: resolution: {integrity: sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: web3-core: 1.2.11 web3-core-method: 1.2.11 @@ -12267,6 +12096,7 @@ packages: /web3-utils@1.2.11: resolution: {integrity: sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: bn.js: 4.12.0 eth-lib: 0.2.8 @@ -12759,8 +12589,8 @@ packages: ethereumjs-util: 6.2.1 dev: true - github.com/smartcontractkit/chainlink-solhint-rules/cfc50b32f95b730304a50deb2e27e88d87115874: - resolution: {tarball: https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/cfc50b32f95b730304a50deb2e27e88d87115874} + github.com/smartcontractkit/chainlink-solhint-rules/1b4c0c2663fcd983589d4f33a2e73908624ed43c: + resolution: {tarball: https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c} name: '@chainlink/solhint-plugin-chainlink-solidity' version: 1.2.0 dev: true From 28b53e52609cb3e2f92c5b40f3a6be96922225cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Tue, 13 Feb 2024 20:03:44 +0200 Subject: [PATCH 17/98] Implement NewPluginProvider (EVM) (#11995) * Implement NewPluginProvider (generic) * Implement PluginProvider Start/Stop/Name/Ready/HealthReport methods * Fix a lint error * Update common, starknet, solana, cosmos * Update common, starknet, solana, cosmos --------- Co-authored-by: Cedric Cordenier Co-authored-by: Bolek <1416262+bolekk@users.noreply.github.com> --- core/scripts/go.mod | 8 +-- core/scripts/go.sum | 16 ++--- core/services/relay/evm/evm.go | 22 ++++++ core/services/relay/evm/plugin_provider.go | 79 ++++++++++++++++++++++ core/services/relay/relay_test.go | 10 ++- go.mod | 8 +-- go.sum | 16 ++--- integration-tests/go.mod | 8 +-- integration-tests/go.sum | 16 ++--- 9 files changed, 146 insertions(+), 37 deletions(-) create mode 100644 core/services/relay/evm/plugin_provider.go diff --git a/core/scripts/go.mod b/core/scripts/go.mod index f03f0276ae6..511e02c5554 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,7 +19,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 @@ -246,11 +246,11 @@ require ( github.com/shirou/gopsutil/v3 v3.23.11 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857 // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944 // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d9c4c4aad16..e9c9c00d668 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1169,18 +1169,18 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 h1:XZ5A3s+DyRSnPisks6scNRGrW6Egb0wsFreVb/UEdP8= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 h1:DuSQLuq+Ilm3Q+2zn5agLrAi9UvFQmOUdKwZQKX0AFA= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62/go.mod h1:Ny6kBD8Houh5yZRmGiB0ovsLHdb4qOHHwBno9JZUT+Y= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 h1:Yk0RK9WV59ISOZZMsdtxZBAKaBfdgb05oXyca/qSqcw= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1/go.mod h1:GuPvyXryvbiUZIHmPeLBz4L+yJKeyGUjrDfd1KNne+o= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857 h1:HTJykZVLsHFTNIZYR/QioAPdImmb3ftOmNZ5UXJFiYo= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857/go.mod h1:NCy9FZ8xONgJ618kmJbks6wCN0nALodUmhZuvwY5hHs= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944 h1:1Cb/XqEs38SFpkBHHxdhYqS8RZR7qXGaXH9+lxtMGJo= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944/go.mod h1:pGnBsaraD3vPjnak8jbu9U+OWZrCVHzGMjA/5++E1PI= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 596f53308b6..4c5e7952508 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -125,6 +125,28 @@ func (r *Relayer) HealthReport() (report map[string]error) { return } +func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.PluginProvider, error) { + lggr := r.lggr.Named("PluginProvider").Named(rargs.ExternalJobID.String()) + + configWatcher, err := newConfigProvider(r.lggr, r.chain, types.NewRelayOpts(rargs)) + if err != nil { + return nil, err + } + + transmitter, err := newContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}) + if err != nil { + return nil, err + } + + return NewPluginProvider( + r.chainReader, + r.codec, + transmitter, + configWatcher, + lggr, + ), nil +} + func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.MercuryProvider, error) { lggr := r.lggr.Named("MercuryProvider").Named(rargs.ExternalJobID.String()) relayOpts := types.NewRelayOpts(rargs) diff --git a/core/services/relay/evm/plugin_provider.go b/core/services/relay/evm/plugin_provider.go new file mode 100644 index 00000000000..a419d069cae --- /dev/null +++ b/core/services/relay/evm/plugin_provider.go @@ -0,0 +1,79 @@ +package evm + +import ( + "context" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +type pluginProvider struct { + services.Service + chainReader types.ChainReader + codec types.Codec + contractTransmitter ocrtypes.ContractTransmitter + configWatcher *configWatcher + lggr logger.Logger + ms services.MultiStart +} + +var _ types.PluginProvider = (*pluginProvider)(nil) + +func NewPluginProvider( + chainReader types.ChainReader, + codec types.Codec, + contractTransmitter ocrtypes.ContractTransmitter, + configWatcher *configWatcher, + lggr logger.Logger, +) *pluginProvider { + return &pluginProvider{ + chainReader: chainReader, + codec: codec, + contractTransmitter: contractTransmitter, + configWatcher: configWatcher, + lggr: lggr, + ms: services.MultiStart{}, + } +} + +func (p *pluginProvider) Name() string { return p.lggr.Name() } + +func (p *pluginProvider) Ready() error { return nil } + +func (p *pluginProvider) HealthReport() map[string]error { + hp := map[string]error{p.Name(): p.Ready()} + services.CopyHealth(hp, p.configWatcher.HealthReport()) + return hp +} + +func (p *pluginProvider) ContractTransmitter() ocrtypes.ContractTransmitter { + return p.contractTransmitter +} + +func (p *pluginProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { + return p.configWatcher.OffchainConfigDigester() +} + +func (p *pluginProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { + return p.configWatcher.configPoller +} + +func (p *pluginProvider) ChainReader() types.ChainReader { + return p.chainReader +} + +func (p *pluginProvider) Codec() types.Codec { + return p.codec +} + +func (p *pluginProvider) Start(ctx context.Context) error { + return p.configWatcher.Start(ctx) +} + +func (p *pluginProvider) Close() error { + return p.configWatcher.Close() +} diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go index 40a11518edd..7b92bab37cd 100644 --- a/core/services/relay/relay_test.go +++ b/core/services/relay/relay_test.go @@ -101,6 +101,10 @@ type staticAutomationProvider struct { types.AutomationProvider } +type staticPluginProvider struct { + types.PluginProvider +} + type mockRelayer struct { types.Relayer } @@ -121,6 +125,10 @@ func (m *mockRelayer) NewAutomationProvider(rargs types.RelayArgs, pargs types.P return staticAutomationProvider{}, nil } +func (m *mockRelayer) NewPluginProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) { + return staticPluginProvider{}, nil +} + type mockRelayerExt struct { loop.RelayerExt } @@ -165,7 +173,7 @@ func TestRelayerServerAdapter(t *testing.T) { }, { ProviderType: string(types.GenericPlugin), - Error: "unexpected call to NewPluginProvider", + Test: isType[types.PluginProvider], }, } diff --git a/go.mod b/go.mod index 04078ed4c3d..ddb45496be3 100644 --- a/go.mod +++ b/go.mod @@ -66,12 +66,12 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857 - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944 + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index 1cce0e09a1a..d06090b588c 100644 --- a/go.sum +++ b/go.sum @@ -1164,18 +1164,18 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 h1:XZ5A3s+DyRSnPisks6scNRGrW6Egb0wsFreVb/UEdP8= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 h1:DuSQLuq+Ilm3Q+2zn5agLrAi9UvFQmOUdKwZQKX0AFA= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62/go.mod h1:Ny6kBD8Houh5yZRmGiB0ovsLHdb4qOHHwBno9JZUT+Y= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 h1:Yk0RK9WV59ISOZZMsdtxZBAKaBfdgb05oXyca/qSqcw= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1/go.mod h1:GuPvyXryvbiUZIHmPeLBz4L+yJKeyGUjrDfd1KNne+o= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857 h1:HTJykZVLsHFTNIZYR/QioAPdImmb3ftOmNZ5UXJFiYo= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857/go.mod h1:NCy9FZ8xONgJ618kmJbks6wCN0nALodUmhZuvwY5hHs= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944 h1:1Cb/XqEs38SFpkBHHxdhYqS8RZR7qXGaXH9+lxtMGJo= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944/go.mod h1:pGnBsaraD3vPjnak8jbu9U+OWZrCVHzGMjA/5++E1PI= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 683ceba36a7..226572aee98 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 @@ -368,11 +368,11 @@ require ( github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857 // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944 // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/soheilhy/cmux v0.1.5 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 3642c98ed7b..a012eca8fca 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1501,18 +1501,18 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699 h1:XZ5A3s+DyRSnPisks6scNRGrW6Egb0wsFreVb/UEdP8= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240212160026-5d1fecc0a699/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62 h1:DuSQLuq+Ilm3Q+2zn5agLrAi9UvFQmOUdKwZQKX0AFA= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240206150430-fbccaa95af62/go.mod h1:Ny6kBD8Houh5yZRmGiB0ovsLHdb4qOHHwBno9JZUT+Y= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 h1:Yk0RK9WV59ISOZZMsdtxZBAKaBfdgb05oXyca/qSqcw= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1/go.mod h1:GuPvyXryvbiUZIHmPeLBz4L+yJKeyGUjrDfd1KNne+o= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857 h1:HTJykZVLsHFTNIZYR/QioAPdImmb3ftOmNZ5UXJFiYo= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240207182351-414a66663857/go.mod h1:NCy9FZ8xONgJ618kmJbks6wCN0nALodUmhZuvwY5hHs= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944 h1:1Cb/XqEs38SFpkBHHxdhYqS8RZR7qXGaXH9+lxtMGJo= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240206145519-35a4346b5944/go.mod h1:pGnBsaraD3vPjnak8jbu9U+OWZrCVHzGMjA/5++E1PI= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-testing-framework v1.23.2 h1:haXPd9Pg++Zs5/QIZnhFd9RElmz/d0+4nNeletUg9ZM= github.com/smartcontractkit/chainlink-testing-framework v1.23.2/go.mod h1:StIOdxvwd8AMO6xuBtmD6FQfJXktEn/mJJEr7728BTc= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= From 7d64b5189d7b84cc470feb3fb2b5f123ad0380fe Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 13 Feb 2024 13:39:27 -0600 Subject: [PATCH 18/98] golangci-lint: revive: add early-return; fix issues (#12017) --- .golangci.yml | 2 +- .../chains/evm/gas/block_history_estimator.go | 85 +++++++++---------- core/chains/evm/types/models.go | 47 +++++----- core/cmd/shell_local.go | 53 ++++++------ core/gethwrappers/abigen.go | 5 +- core/gethwrappers/go_generate_test.go | 5 +- core/gethwrappers/utils.go | 5 +- .../handler/keeper_verifiable_load.go | 7 +- core/scripts/common/polygonedge.go | 5 +- core/services/ocr2/delegate.go | 7 +- .../evmregistry/v21/payload_builder.go | 35 ++++---- .../ocr2vrf/coordinator/coordinator.go | 19 ++--- core/services/pipeline/common.go | 5 +- core/services/pipeline/runner.go | 5 +- core/services/pipeline/task_params.go | 6 +- .../evm/functions/contract_transmitter.go | 5 +- .../relay/evm/functions/logpoller_wrapper.go | 7 +- .../relay/evm/mercury/wsrpc/client.go | 16 ++-- .../vrf/v2/listener_v2_log_processor.go | 23 +++-- core/sessions/ldapauth/ldap.go | 16 ++-- core/web/cosmos_transfer_controller.go | 6 +- 21 files changed, 171 insertions(+), 193 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 3672692f599..71468b4975f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -71,7 +71,7 @@ linters-settings: - name: identical-branches - name: get-return # - name: flag-parameter - # - name: early-return + - name: early-return - name: defer - name: constant-logical-expr # - name: confusing-naming diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index dc95240fd42..5ac8ca5faf8 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -340,11 +340,10 @@ func (b *BlockHistoryEstimator) checkConnectivity(attempts []EvmPriorAttempt) er // reverse order since we want to go highest -> lowest block number and bail out early for i := l - 1; i >= 0; i-- { block := blockHistory[i] - if block.Number >= broadcastBeforeBlockNum { - blocks = append(blocks, block) - } else { + if block.Number < broadcastBeforeBlockNum { break } + blocks = append(blocks, block) } var eip1559 bool switch attempt.TxType { @@ -364,27 +363,26 @@ func (b *BlockHistoryEstimator) checkConnectivity(attempts []EvmPriorAttempt) er b.logger.AssumptionViolationw("unexpected error while verifying transaction inclusion", "err", err, "txHash", attempt.TxHash.String()) return nil } - if eip1559 { - sufficientFeeCap := true - for _, b := range blocks { - // feecap must >= tipcap+basefee for the block, otherwise there - // is no way this could have been included, and we must bail - // out of the check - attemptFeeCap := attempt.DynamicFee.FeeCap - attemptTipCap := attempt.DynamicFee.TipCap - if attemptFeeCap.Cmp(attemptTipCap.Add(b.BaseFeePerGas)) < 0 { - sufficientFeeCap = false - break - } - } - if sufficientFeeCap && attempt.DynamicFee.TipCap.Cmp(tipCap) > 0 { - return errors.Wrapf(commonfee.ErrConnectivity, "transaction %s has tip cap of %s, which is above percentile=%d%% (percentile tip cap: %s) for blocks %d thru %d (checking %d blocks)", attempt.TxHash, attempt.DynamicFee.TipCap, percentile, tipCap, blockHistory[l-1].Number, blockHistory[0].Number, expectInclusionWithinBlocks) - } - } else { + if !eip1559 { if attempt.GasPrice.Cmp(gasPrice) > 0 { return errors.Wrapf(commonfee.ErrConnectivity, "transaction %s has gas price of %s, which is above percentile=%d%% (percentile price: %s) for blocks %d thru %d (checking %d blocks)", attempt.TxHash, attempt.GasPrice, percentile, gasPrice, blockHistory[l-1].Number, blockHistory[0].Number, expectInclusionWithinBlocks) - } + continue + } + sufficientFeeCap := true + for _, b := range blocks { + // feecap must >= tipcap+basefee for the block, otherwise there + // is no way this could have been included, and we must bail + // out of the check + attemptFeeCap := attempt.DynamicFee.FeeCap + attemptTipCap := attempt.DynamicFee.TipCap + if attemptFeeCap.Cmp(attemptTipCap.Add(b.BaseFeePerGas)) < 0 { + sufficientFeeCap = false + break + } + } + if sufficientFeeCap && attempt.DynamicFee.TipCap.Cmp(tipCap) > 0 { + return errors.Wrapf(commonfee.ErrConnectivity, "transaction %s has tip cap of %s, which is above percentile=%d%% (percentile tip cap: %s) for blocks %d thru %d (checking %d blocks)", attempt.TxHash, attempt.DynamicFee.TipCap, percentile, tipCap, blockHistory[l-1].Number, blockHistory[0].Number, expectInclusionWithinBlocks) } } return nil @@ -560,20 +558,20 @@ func (b *BlockHistoryEstimator) Recalculate(head *evmtypes.Head) { b.setPercentileGasPrice(percentileGasPrice) promBlockHistoryEstimatorSetGasPrice.WithLabelValues(fmt.Sprintf("%v%%", percentile), b.chainID.String()).Set(float64(percentileGasPrice.Int64())) - if eip1559 { - float = new(big.Float).SetInt(percentileTipCap.ToInt()) - gwei, _ = big.NewFloat(0).Quo(float, big.NewFloat(1000000000)).Float64() - tipCapGwei := fmt.Sprintf("%.2f", gwei) - lggrFields = append(lggrFields, []interface{}{ - "tipCapWei", percentileTipCap, - "tipCapGwei", tipCapGwei, - }...) - lggr.Debugw(fmt.Sprintf("Setting new default prices, GasPrice: %v Gwei, TipCap: %v Gwei", gasPriceGwei, tipCapGwei), lggrFields...) - b.setPercentileTipCap(percentileTipCap) - promBlockHistoryEstimatorSetTipCap.WithLabelValues(fmt.Sprintf("%v%%", percentile), b.chainID.String()).Set(float64(percentileTipCap.Int64())) - } else { + if !eip1559 { lggr.Debugw(fmt.Sprintf("Setting new default gas price: %v Gwei", gasPriceGwei), lggrFields...) + return } + float = new(big.Float).SetInt(percentileTipCap.ToInt()) + gwei, _ = big.NewFloat(0).Quo(float, big.NewFloat(1000000000)).Float64() + tipCapGwei := fmt.Sprintf("%.2f", gwei) + lggrFields = append(lggrFields, []interface{}{ + "tipCapWei", percentileTipCap, + "tipCapGwei", tipCapGwei, + }...) + lggr.Debugw(fmt.Sprintf("Setting new default prices, GasPrice: %v Gwei, TipCap: %v Gwei", gasPriceGwei, tipCapGwei), lggrFields...) + b.setPercentileTipCap(percentileTipCap) + promBlockHistoryEstimatorSetTipCap.WithLabelValues(fmt.Sprintf("%v%%", percentile), b.chainID.String()).Set(float64(percentileTipCap.Int64())) } // FetchBlocks fetches block history leading up to the given head. @@ -774,21 +772,20 @@ func (b *BlockHistoryEstimator) getPricesFromBlocks(blocks []evmtypes.Block, eip for _, tx := range block.Transactions { if b.IsUsable(tx, block, b.config.ChainType(), b.eConfig.PriceMin(), b.logger) { gp := b.EffectiveGasPrice(block, tx) - if gp != nil { - gasPrices = append(gasPrices, gp) - } else { + if gp == nil { b.logger.Warnw("Unable to get gas price for tx", "tx", tx, "block", block) continue } - if eip1559 { - tc := b.EffectiveTipCap(block, tx) - if tc != nil { - tipCaps = append(tipCaps, tc) - } else { - b.logger.Warnw("Unable to get tip cap for tx", "tx", tx, "block", block) - continue - } + gasPrices = append(gasPrices, gp) + if !eip1559 { + continue + } + tc := b.EffectiveTipCap(block, tx) + if tc == nil { + b.logger.Warnw("Unable to get tip cap for tx", "tx", tx, "block", block) + continue } + tipCaps = append(tipCaps, tc) } } } diff --git a/core/chains/evm/types/models.go b/core/chains/evm/types/models.go index 44e150b6541..7db38fc6821 100644 --- a/core/chains/evm/types/models.go +++ b/core/chains/evm/types/models.go @@ -105,11 +105,10 @@ func (h *Head) IsInChain(blockHash common.Hash) bool { if h.Hash == blockHash { return true } - if h.Parent != nil { - h = h.Parent - } else { + if h.Parent == nil { break } + h = h.Parent } return false } @@ -121,11 +120,10 @@ func (h *Head) HashAtHeight(blockNum int64) common.Hash { if h.Number == blockNum { return h.Hash } - if h.Parent != nil { - h = h.Parent - } else { + if h.Parent == nil { break } + h = h.Parent } return common.Hash{} } @@ -138,15 +136,14 @@ func (h *Head) ChainLength() uint32 { l := uint32(1) for { - if h.Parent != nil { - l++ - if h == h.Parent { - panic("circular reference detected") - } - h = h.Parent - } else { + if h.Parent == nil { break } + l++ + if h == h.Parent { + panic("circular reference detected") + } + h = h.Parent } return l } @@ -157,14 +154,13 @@ func (h *Head) ChainHashes() []common.Hash { for { hashes = append(hashes, h.Hash) - if h.Parent != nil { - if h == h.Parent { - panic("circular reference detected") - } - h = h.Parent - } else { + if h.Parent == nil { break } + if h == h.Parent { + panic("circular reference detected") + } + h = h.Parent } return hashes } @@ -186,15 +182,14 @@ func (h *Head) ChainString() string { for { sb.WriteString(h.String()) - if h.Parent != nil { - if h == h.Parent { - panic("circular reference detected") - } - sb.WriteString("->") - h = h.Parent - } else { + if h.Parent == nil { break } + if h == h.Parent { + panic("circular reference detected") + } + sb.WriteString("->") + h = h.Parent } sb.WriteString("->nil") return sb.String() diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index b970b516413..350e6abf77d 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -1002,37 +1002,36 @@ func (s *Shell) CleanupChainTables(c *cli.Context) error { // some tables with evm_chain_id (mostly job specs) are in public schema tablesToDeleteFromQuery := `SELECT table_name, table_schema FROM information_schema.columns WHERE "column_name"=$1;` // Delete rows from each table based on the chain_id. - if strings.EqualFold("EVM", c.String("type")) { - rows, err := db.Query(tablesToDeleteFromQuery, "evm_chain_id") - if err != nil { - return err - } - defer rows.Close() + if !strings.EqualFold("EVM", c.String("type")) { + return s.errorOut(errors.New("unknown chain type")) + } + rows, err := db.Query(tablesToDeleteFromQuery, "evm_chain_id") + if err != nil { + return err + } + defer rows.Close() - var tablesToDeleteFrom []string - for rows.Next() { - var name string - var schema string - if err = rows.Scan(&name, &schema); err != nil { - return err - } - tablesToDeleteFrom = append(tablesToDeleteFrom, schema+"."+name) - } - if rows.Err() != nil { - return rows.Err() + var tablesToDeleteFrom []string + for rows.Next() { + var name string + var schema string + if err = rows.Scan(&name, &schema); err != nil { + return err } + tablesToDeleteFrom = append(tablesToDeleteFrom, schema+"."+name) + } + if rows.Err() != nil { + return rows.Err() + } - for _, tableName := range tablesToDeleteFrom { - query := fmt.Sprintf(`DELETE FROM %s WHERE "evm_chain_id"=$1;`, tableName) - _, err = db.Exec(query, c.String("id")) - if err != nil { - fmt.Printf("Error deleting rows containing evm_chain_id from %s: %v\n", tableName, err) - } else { - fmt.Printf("Rows with evm_chain_id %s deleted from %s.\n", c.String("id"), tableName) - } + for _, tableName := range tablesToDeleteFrom { + query := fmt.Sprintf(`DELETE FROM %s WHERE "evm_chain_id"=$1;`, tableName) + _, err = db.Exec(query, c.String("id")) + if err != nil { + fmt.Printf("Error deleting rows containing evm_chain_id from %s: %v\n", tableName, err) + } else { + fmt.Printf("Rows with evm_chain_id %s deleted from %s.\n", c.String("id"), tableName) } - } else { - return s.errorOut(errors.New("unknown chain type")) } return nil } diff --git a/core/gethwrappers/abigen.go b/core/gethwrappers/abigen.go index ed2558f4173..af085f30d9b 100644 --- a/core/gethwrappers/abigen.go +++ b/core/gethwrappers/abigen.go @@ -147,11 +147,10 @@ func getContractName(fileNode *ast.File) string { if len(n.Name) < 3 { return true } - if n.Name[len(n.Name)-3:] == "ABI" { - contractName = n.Name[:len(n.Name)-3] - } else { + if n.Name[len(n.Name)-3:] != "ABI" { return true } + contractName = n.Name[:len(n.Name)-3] } } return false diff --git a/core/gethwrappers/go_generate_test.go b/core/gethwrappers/go_generate_test.go index e0779c306c4..52d0f520dd7 100644 --- a/core/gethwrappers/go_generate_test.go +++ b/core/gethwrappers/go_generate_test.go @@ -138,11 +138,10 @@ func getProjectRoot(t *testing.T) (rootPath string) { root, err := os.Getwd() require.NoError(t, err, "could not get current working directory") for root != "/" { // Walk up path to find dir containing go.mod - if _, err := os.Stat(filepath.Join(root, "go.mod")); os.IsNotExist(err) { - root = filepath.Dir(root) - } else { + if _, err := os.Stat(filepath.Join(root, "go.mod")); !os.IsNotExist(err) { return root } + root = filepath.Dir(root) } t.Fatal("could not find project root") return diff --git a/core/gethwrappers/utils.go b/core/gethwrappers/utils.go index c9b61c9441a..277ebf8aaae 100644 --- a/core/gethwrappers/utils.go +++ b/core/gethwrappers/utils.go @@ -44,11 +44,10 @@ func GetProjectRoot() (rootPath string) { err) } for root != "/" { // Walk up path to find dir containing go.mod - if _, err := os.Stat(filepath.Join(root, "go.mod")); os.IsNotExist(err) { - root = filepath.Dir(root) - } else { + if _, err := os.Stat(filepath.Join(root, "go.mod")); !os.IsNotExist(err) { return root } + root = filepath.Dir(root) } Exit("could not find project root", nil) panic("can't get here") diff --git a/core/scripts/chaincli/handler/keeper_verifiable_load.go b/core/scripts/chaincli/handler/keeper_verifiable_load.go index aa62d820101..ee763e54f79 100644 --- a/core/scripts/chaincli/handler/keeper_verifiable_load.go +++ b/core/scripts/chaincli/handler/keeper_verifiable_load.go @@ -203,12 +203,11 @@ func (k *Keeper) fetchBucketData(v verifiableLoad, opts *bind.CallOpts, id *big. var err error for i := 0; i < retryNum; i++ { bucketDelays, err = v.GetBucketedDelays(opts, id, bucketNum) - if err != nil { - log.Printf("failed to get bucketed delays for upkeep id %s bucket %d: %v, retrying...", id.String(), bucketNum, err) - time.Sleep(retryDelay) - } else { + if err == nil { break } + log.Printf("failed to get bucketed delays for upkeep id %s bucket %d: %v, retrying...", id.String(), bucketNum, err) + time.Sleep(retryDelay) } var floatBucketDelays []float64 diff --git a/core/scripts/common/polygonedge.go b/core/scripts/common/polygonedge.go index e3cc7a52ad3..c91d76cce87 100644 --- a/core/scripts/common/polygonedge.go +++ b/core/scripts/common/polygonedge.go @@ -149,11 +149,10 @@ func GetIbftExtraClean(extra []byte) (cleanedExtra []byte, err error) { hexExtra := hex.EncodeToString(extra) prefix := "" for _, s := range hexExtra { - if s == '0' { - prefix = prefix + "0" - } else { + if s != '0' { break } + prefix = prefix + "0" } hexExtra = strings.TrimLeft(hexExtra, "0") diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 870dfb6463c..c185ec6ddbe 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -491,12 +491,11 @@ func GetEVMEffectiveTransmitterID(jb *job.Job, chain legacyevm.Chain, lggr logge effectiveTransmitterID, err := chain.TxManager().GetForwarderForEOA(common.HexToAddress(spec.TransmitterID.String)) if err == nil { return effectiveTransmitterID.String(), nil - } else if spec.TransmitterID.Valid { - lggr.Warnw("Skipping forwarding for job, will fallback to default behavior", "job", jb.Name, "err", err) - // this shouldn't happen unless behaviour above was changed - } else { + } else if !spec.TransmitterID.Valid { return "", errors.New("failed to get forwarder address and transmitterID is not set") } + lggr.Warnw("Skipping forwarding for job, will fallback to default behavior", "job", jb.Name, "err", err) + // this shouldn't happen unless behaviour above was changed } return spec.TransmitterID.String, nil diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go index 4854f517c46..7f29cb3b7ac 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go @@ -33,27 +33,26 @@ func (b *payloadBuilder) BuildPayloads(ctx context.Context, proposals ...ocr2kee for i, proposal := range proposals { var payload ocr2keepers.UpkeepPayload - if b.upkeepList.IsActive(proposal.UpkeepID.BigInt()) { - b.lggr.Debugf("building payload for coordinated block proposal %+v", proposal) - var checkData []byte - var err error - switch core.GetUpkeepType(proposal.UpkeepID) { - case types.LogTrigger: - checkData, err = b.recoverer.GetProposalData(ctx, proposal) - if err != nil { - b.lggr.Warnw("failed to get log proposal data", "err", err, "upkeepID", proposal.UpkeepID, "trigger", proposal.Trigger) - continue - } - case types.ConditionTrigger: - // Empty checkData for conditionals - } - payload, err = core.NewUpkeepPayload(proposal.UpkeepID.BigInt(), proposal.Trigger, checkData) + if !b.upkeepList.IsActive(proposal.UpkeepID.BigInt()) { + b.lggr.Warnw("upkeep is not active, skipping", "upkeepID", proposal.UpkeepID) + continue + } + b.lggr.Debugf("building payload for coordinated block proposal %+v", proposal) + var checkData []byte + var err error + switch core.GetUpkeepType(proposal.UpkeepID) { + case types.LogTrigger: + checkData, err = b.recoverer.GetProposalData(ctx, proposal) if err != nil { - b.lggr.Warnw("error building upkeep payload", "err", err, "upkeepID", proposal.UpkeepID) + b.lggr.Warnw("failed to get log proposal data", "err", err, "upkeepID", proposal.UpkeepID, "trigger", proposal.Trigger) continue } - } else { - b.lggr.Warnw("upkeep is not active, skipping", "upkeepID", proposal.UpkeepID) + case types.ConditionTrigger: + // Empty checkData for conditionals + } + payload, err = core.NewUpkeepPayload(proposal.UpkeepID.BigInt(), proposal.Trigger, checkData) + if err != nil { + b.lggr.Warnw("error building upkeep payload", "err", err, "upkeepID", proposal.UpkeepID) continue } diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go index 88d6544d8c4..803ed3450be 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go @@ -440,18 +440,17 @@ func (c *coordinator) ReportBlocks( // Fill blocks slice with valid requested blocks. blocks = []ocr2vrftypes.Block{} for block := range blocksRequested { - if c.coordinatorConfig.BatchGasLimit-currentBatchGasLimit >= c.coordinatorConfig.BlockGasOverhead { - _, redeemRandomnessRequested := redeemRandomnessBlocksRequested[block] - blocks = append(blocks, ocr2vrftypes.Block{ - Hash: blockhashesMapping[block.blockNumber], - Height: block.blockNumber, - ConfirmationDelay: block.confDelay, - ShouldStore: redeemRandomnessRequested, - }) - currentBatchGasLimit += c.coordinatorConfig.BlockGasOverhead - } else { + if c.coordinatorConfig.BatchGasLimit-currentBatchGasLimit < c.coordinatorConfig.BlockGasOverhead { break } + _, redeemRandomnessRequested := redeemRandomnessBlocksRequested[block] + blocks = append(blocks, ocr2vrftypes.Block{ + Hash: blockhashesMapping[block.blockNumber], + Height: block.blockNumber, + ConfirmationDelay: block.confDelay, + ShouldStore: redeemRandomnessRequested, + }) + currentBatchGasLimit += c.coordinatorConfig.BlockGasOverhead } c.lggr.Tracew("got elligible blocks", "blocks", blocks) diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index 1c8703e2eb1..da0e0d3c00b 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -673,11 +673,10 @@ func getJsonNumberValue(value json.Number) (interface{}, error) { } } else { f, err := value.Float64() - if err == nil { - result = f - } else { + if err != nil { return nil, pkgerrors.Errorf("failed to parse json.Value: %v", err) } + result = f } return result, nil diff --git a/core/services/pipeline/runner.go b/core/services/pipeline/runner.go index a432d9fec11..30a35598c3e 100644 --- a/core/services/pipeline/runner.go +++ b/core/services/pipeline/runner.go @@ -546,11 +546,10 @@ func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccess // retain old UUID values for _, taskRun := range run.PipelineTaskRuns { task := pipeline.ByDotID(taskRun.DotID) - if task != nil && task.Base() != nil { - task.Base().uuid = taskRun.ID - } else { + if task == nil || task.Base() == nil { return false, pkgerrors.Errorf("failed to match a pipeline task for dot ID: %v", taskRun.DotID) } + task.Base().uuid = taskRun.ID } preinsert := pipeline.RequiresPreInsert() diff --git a/core/services/pipeline/task_params.go b/core/services/pipeline/task_params.go index 72d0d619429..61d3b8650ad 100644 --- a/core/services/pipeline/task_params.go +++ b/core/services/pipeline/task_params.go @@ -708,11 +708,11 @@ func (p *JSONPathParam) UnmarshalPipelineParam(val interface{}) error { ssp = v case []interface{}: for _, x := range v { - if as, is := x.(string); is { - ssp = append(ssp, as) - } else { + as, is := x.(string) + if !is { return ErrBadInput } + ssp = append(ssp, as) } case string: if len(v) == 0 { diff --git a/core/services/relay/evm/functions/contract_transmitter.go b/core/services/relay/evm/functions/contract_transmitter.go index 2a62db31a8c..78a5ff39bb7 100644 --- a/core/services/relay/evm/functions/contract_transmitter.go +++ b/core/services/relay/evm/functions/contract_transmitter.go @@ -125,7 +125,8 @@ func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes. } var destinationContract common.Address - if oc.contractVersion == 1 { + switch oc.contractVersion { + case 1: oc.lggr.Debugw("FunctionsContractTransmitter: start", "reportLenBytes", len(report)) requests, err2 := oc.reportCodec.DecodeReport(report) if err2 != nil { @@ -152,7 +153,7 @@ func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes. } } oc.lggr.Debugw("FunctionsContractTransmitter: ready", "nRequests", len(requests), "coordinatorContract", destinationContract.Hex()) - } else { + default: return fmt.Errorf("unsupported contract version: %d", oc.contractVersion) } payload, err := oc.contractABI.Pack("transmit", rawReportCtx, []byte(report), rs, ss, vs) diff --git a/core/services/relay/evm/functions/logpoller_wrapper.go b/core/services/relay/evm/functions/logpoller_wrapper.go index 7897e86310e..f11b6bee1e0 100644 --- a/core/services/relay/evm/functions/logpoller_wrapper.go +++ b/core/services/relay/evm/functions/logpoller_wrapper.go @@ -304,12 +304,11 @@ func (l *logPollerWrapper) filterPreviouslyDetectedEvents(logs []logpoller.Log, expiredRequests := 0 for _, detectedEvent := range detectedEvents.detectedEventsOrdered { expirationTime := time.Now().Add(-time.Second * time.Duration(l.logPollerCacheDurationSec)) - if detectedEvent.timeDetected.Before(expirationTime) { - delete(detectedEvents.isPreviouslyDetected, detectedEvent.requestId) - expiredRequests++ - } else { + if !detectedEvent.timeDetected.Before(expirationTime) { break } + delete(detectedEvents.isPreviouslyDetected, detectedEvent.requestId) + expiredRequests++ } detectedEvents.detectedEventsOrdered = detectedEvents.detectedEventsOrdered[expiredRequests:] l.lggr.Debugw("filterPreviouslyDetectedEvents: done", "filterType", filterType, "nLogs", len(logs), "nFilteredLogs", len(filteredLogs), "nExpiredRequests", expiredRequests, "previouslyDetectedCacheSize", len(detectedEvents.detectedEventsOrdered)) diff --git a/core/services/relay/evm/mercury/wsrpc/client.go b/core/services/relay/evm/mercury/wsrpc/client.go index c9533717757..d420a17a1a4 100644 --- a/core/services/relay/evm/mercury/wsrpc/client.go +++ b/core/services/relay/evm/mercury/wsrpc/client.go @@ -193,16 +193,16 @@ func (w *client) resetTransport() { b := utils.NewRedialBackoff() for { // Will block until successful dial, or context is canceled (i.e. on close) - if err := w.dial(ctx, wsrpc.WithBlock()); err != nil { - if ctx.Err() != nil { - w.logger.Debugw("ResetTransport exiting due to client Close", "err", err) - return - } - w.logger.Errorw("ResetTransport failed to redial", "err", err) - time.Sleep(b.Duration()) - } else { + err := w.dial(ctx, wsrpc.WithBlock()) + if err == nil { break } + if ctx.Err() != nil { + w.logger.Debugw("ResetTransport exiting due to client Close", "err", err) + return + } + w.logger.Errorw("ResetTransport failed to redial", "err", err) + time.Sleep(b.Duration()) } w.logger.Info("ResetTransport successfully redialled") } diff --git a/core/services/vrf/v2/listener_v2_log_processor.go b/core/services/vrf/v2/listener_v2_log_processor.go index eebe9038c0c..be9457d7cee 100644 --- a/core/services/vrf/v2/listener_v2_log_processor.go +++ b/core/services/vrf/v2/listener_v2_log_processor.go @@ -155,22 +155,21 @@ func (lsn *listenerV2) processPendingVRFRequests(ctx context.Context, pendingReq Context: ctx}, sID) if err != nil { - if strings.Contains(err.Error(), "execution reverted") { - // "execution reverted" indicates that the subscription no longer exists. - // We can no longer just mark these as processed and continue, - // since it could be that the subscription was canceled while there - // were still unfulfilled requests. - // The simplest approach to handle this is to enter the processRequestsPerSub - // loop rather than create a bunch of largely duplicated code - // to handle this specific situation, since we need to run the pipeline to get - // the VRF proof, abi-encode it, etc. - l.Warnw("Subscription not found - setting start balance to zero", "subID", subID, "err", err) - startLinkBalance = big.NewInt(0) - } else { + if !strings.Contains(err.Error(), "execution reverted") { // Most likely this is an RPC error, so we re-try later. l.Errorw("Unable to read subscription balance", "err", err) return } + // "execution reverted" indicates that the subscription no longer exists. + // We can no longer just mark these as processed and continue, + // since it could be that the subscription was canceled while there + // were still unfulfilled requests. + // The simplest approach to handle this is to enter the processRequestsPerSub + // loop rather than create a bunch of largely duplicated code + // to handle this specific situation, since we need to run the pipeline to get + // the VRF proof, abi-encode it, etc. + l.Warnw("Subscription not found - setting start balance to zero", "subID", subID, "err", err) + startLinkBalance = big.NewInt(0) } else { // Happy path - sub is active. startLinkBalance = sub.Balance() diff --git a/core/sessions/ldapauth/ldap.go b/core/sessions/ldapauth/ldap.go index 147f8bd2aed..fc0e76bb5c1 100644 --- a/core/sessions/ldapauth/ldap.go +++ b/core/sessions/ldapauth/ldap.go @@ -124,17 +124,15 @@ func (l *ldapAuthenticator) FindUser(email string) (sessions.User, error) { sql := "SELECT * FROM users WHERE lower(email) = lower($1)" return tx.Get(&foundLocalAdminUser, sql, email) }) - if checkErr != nil { - // If error is not nil, there was either an issue or no local users found - if !errors.Is(checkErr, sql.ErrNoRows) { - // If the error is not that no local user was found, log and exit - l.lggr.Errorf("error searching users table: %v", checkErr) - return sessions.User{}, errors.New("error Finding user") - } - } else { - // Error was nil, local user found. Return + if checkErr == nil { return foundLocalAdminUser, nil } + // If error is not nil, there was either an issue or no local users found + if !errors.Is(checkErr, sql.ErrNoRows) { + // If the error is not that no local user was found, log and exit + l.lggr.Errorf("error searching users table: %v", checkErr) + return sessions.User{}, errors.New("error Finding user") + } // First query for user "is active" property if defined usersActive, err := l.validateUsersActive([]string{email}) diff --git a/core/web/cosmos_transfer_controller.go b/core/web/cosmos_transfer_controller.go index 965f694fc1b..9b958346642 100644 --- a/core/web/cosmos_transfer_controller.go +++ b/core/web/cosmos_transfer_controller.go @@ -60,12 +60,12 @@ func (tc *CosmosTransfersController) Create(c *gin.Context) { } var gasToken string cfgs := tc.App.GetConfig().CosmosConfigs() - if i := slices.IndexFunc(cfgs, func(config *coscfg.TOMLConfig) bool { return *config.ChainID == tr.CosmosChainID }); i != -1 { - gasToken = cfgs[i].GasToken() - } else { + i := slices.IndexFunc(cfgs, func(config *coscfg.TOMLConfig) bool { return *config.ChainID == tr.CosmosChainID }) + if i == -1 { jsonAPIError(c, http.StatusInternalServerError, fmt.Errorf("no config for chain id: %s", tr.CosmosChainID)) return } + gasToken = cfgs[i].GasToken() //TODO move this inside? coin, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec(tr.Token, tr.Amount), gasToken) From 3a974b7a551723168c4a2e93c666c34196b1460a Mon Sep 17 00:00:00 2001 From: chudilka1 Date: Tue, 13 Feb 2024 20:03:00 +0000 Subject: [PATCH 19/98] Update Sonar properties (#11986) --- sonar-project.properties | 58 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index 8a215f6c0be..c5a2eb33ad2 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,15 +1,63 @@ sonar.projectKey=smartcontractkit_chainlink sonar.sources=. +sonar.sourceEncoding=UTF-8 sonar.python.version=3.8 # Full exclusions from the static analysis -sonar.exclusions=**/node_modules/**/*,**/mocks/**/*, **/testdata/**/*, **/contracts/typechain/**/*, **/contracts/artifacts/**/*, **/contracts/cache/**/*, **/contracts/scripts/**/*, **/generated/**/*, **/fixtures/**/*, **/docs/**/*, **/tools/**/*, **/*.pb.go, **/*report.xml, **/*.config.ts, **/*.txt, **/*.abi, **/*.bin, **/*_codecgen.go, core/services/relay/evm/types/*_gen.go, core/services/relay/evm/types/gen/main.go, core/services/relay/evm/testfiles/*, **/core/web/assets**, core/scripts/chaincli/handler/debug.go, **/fuzz/**/* +sonar.exclusions=\ +**/node_modules/**/*,\ +**/mocks/**/*,\ +**/testdata/**/*,\ +**/contracts/typechain/**/*,\ +**/contracts/artifacts/**/*,\ +**/contracts/cache/**/*,\ +**/contracts/scripts/**/*,\ +**/generated/**/*,\ +**/fixtures/**/*,\ +**/testutils/**/*,\ +**/gen/**/*,\ +**/testfiles/**/*,\ +**/testconfig/**/*,\ +**/core/web/assets/**/*,\ +**/core/scripts/**/*,\ +**/docs/**/*,\ +**/tools/**/*,\ +**/fuzz/**/*,\ +**/*.pb.go,\ +**/*report.xml,\ +**/*.config.ts,\ +**/*.txt,\ +**/*.abi,\ +**/*.bin,\ +**/*_codecgen.go,\ +**/*_gen.go,\ +**/debug.go + # Coverage exclusions -sonar.coverage.exclusions=**/*.test.ts, **/*_test.go, **/contracts/test/**/*, **/contracts/**/tests/**/*, **/core/**/testutils/**/*, **/core/**/mocks/**/*, **/core/**/cltest/**/*, **/integration-tests/**/*, **/generated/**/*, **/core/scripts**/* , **/*.pb.go, ./plugins/**/*, **/main.go, **/0195_add_not_null_to_evm_chain_id_in_job_specs.go, **/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go +sonar.coverage.exclusions=\ +**/*.test.ts,\ +**/*_test.go,\ +**/contracts/test/**/*,\ +**/contracts/**/tests/**/*,\ +**/core/**/cltest/**/*,\ +**/integration-tests/**/*,\ +**/plugins/**/*,\ +**/main.go,\ +**/0195_add_not_null_to_evm_chain_id_in_job_specs.go,\ +**/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go + # Duplication exclusions: mercury excluded because current MercuryProvider and Factory APIs are inherently duplicated due to embedded versioning -sonar.cpd.exclusions=**/contracts/**/*.sol, **/config.go, /core/services/ocr2/plugins/ocr2keeper/evm*/*, **/integration-tests/testconfig/**/*, /core/services/ocr2/plugins/mercury/plugin.go +sonar.cpd.exclusions=\ +**/contracts/**/*.sol,\ +**/config.go,\ +**/core/services/ocr2/plugins/ocr2keeper/evm/**/*,\ +**/core/services/ocr2/plugins/mercury/plugin.go # Tests' root folder, inclusions (tests to check and count) and exclusions sonar.tests=. -sonar.test.inclusions=**/*_test.go, **/*.test.ts -sonar.test.exclusions=**/integration-tests/**/*, **/charts/chainlink-cluster/dashboard/cmd/* +sonar.test.inclusions=\ +**/*_test.go,\ +**/*.test.ts +sonar.test.exclusions=\ +**/integration-tests/**/*,\ +**/charts/chainlink-cluster/dashboard/cmd/**/* \ No newline at end of file From 238022085de0fe655248f6a49dfe744102b7adf3 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 13 Feb 2024 16:09:20 -0500 Subject: [PATCH 20/98] Allow for custom config poller onchain codec (LLO support) (#11957) * Allow for custom config poller onchain codec (LLO support) * Fix linter * Remove useless pkgerrors * remove another pkg errors * PR comments * Lint * Resolve conflicts with develop --- core/services/relay/evm/config_poller.go | 87 ++++---------- core/services/relay/evm/config_poller_test.go | 14 ++- core/services/relay/evm/evm.go | 112 +++++++----------- core/services/relay/evm/functions.go | 12 +- .../services/relay/evm/mercury/transmitter.go | 4 +- .../relay/evm/mercury/transmitter_test.go | 32 +++-- .../relay/evm/mercury_config_provider.go | 44 +++++++ .../relay/evm/ocr2aggregator_decoder.go | 65 ++++++++++ core/services/relay/evm/ocr2keeper.go | 44 +++---- core/services/relay/evm/ocr2vrf.go | 26 ++-- .../relay/evm/standard_config_provider.go | 52 ++++++++ 11 files changed, 289 insertions(+), 203 deletions(-) create mode 100644 core/services/relay/evm/mercury_config_provider.go create mode 100644 core/services/relay/evm/ocr2aggregator_decoder.go create mode 100644 core/services/relay/evm/standard_config_provider.go diff --git a/core/services/relay/evm/config_poller.go b/core/services/relay/evm/config_poller.go index dc75fe037fe..bb962fc6ed5 100644 --- a/core/services/relay/evm/config_poller.go +++ b/core/services/relay/evm/config_poller.go @@ -5,7 +5,6 @@ import ( "database/sql" "fmt" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" @@ -34,60 +33,9 @@ var ( ) ) -var ( - // ConfigSet Common to all OCR2 evm based contracts: https://github.com/smartcontractkit/libocr/blob/master/contract2/dev/OCR2Abstract.sol - ConfigSet common.Hash - - defaultABI abi.ABI -) - -const configSetEventName = "ConfigSet" - -func init() { - var err error - abiPointer, err := ocr2aggregator.OCR2AggregatorMetaData.GetAbi() - if err != nil { - panic(err) - } - defaultABI = *abiPointer - ConfigSet = defaultABI.Events[configSetEventName].ID -} - -func unpackLogData(d []byte) (*ocr2aggregator.OCR2AggregatorConfigSet, error) { - unpacked := new(ocr2aggregator.OCR2AggregatorConfigSet) - err := defaultABI.UnpackIntoInterface(unpacked, configSetEventName, d) - if err != nil { - return nil, errors.Wrap(err, "failed to unpack log data") - } - return unpacked, nil -} - -func configFromLog(logData []byte) (ocrtypes.ContractConfig, error) { - unpacked, err := unpackLogData(logData) - if err != nil { - return ocrtypes.ContractConfig{}, err - } - - var transmitAccounts []ocrtypes.Account - for _, addr := range unpacked.Transmitters { - transmitAccounts = append(transmitAccounts, ocrtypes.Account(addr.Hex())) - } - var signers []ocrtypes.OnchainPublicKey - for _, addr := range unpacked.Signers { - addr := addr - signers = append(signers, addr[:]) - } - - return ocrtypes.ContractConfig{ - ConfigDigest: unpacked.ConfigDigest, - ConfigCount: unpacked.ConfigCount, - Signers: signers, - Transmitters: transmitAccounts, - F: unpacked.F, - OnchainConfig: unpacked.OnchainConfig, - OffchainConfigVersion: unpacked.OffchainConfigVersion, - OffchainConfig: unpacked.OffchainConfig, - }, nil +type LogDecoder interface { + EventSig() common.Hash + Decode(rawLog []byte) (ocrtypes.ContractConfig, error) } type configPoller struct { @@ -105,18 +53,30 @@ type configPoller struct { // contract allows us work around such restrictions. configStoreContractAddr *common.Address configStoreContract *ocrconfigurationstoreevmsimple.OCRConfigurationStoreEVMSimple + + // Depending on the exact contract used, the raw config log may be shaped + // in different ways + ld LogDecoder } func configPollerFilterName(addr common.Address) string { return logpoller.FilterName("OCR2ConfigPoller", addr.String()) } -func NewConfigPoller(lggr logger.Logger, client client.Client, destChainPoller logpoller.LogPoller, aggregatorContractAddr common.Address, configStoreAddr *common.Address) (evmRelayTypes.ConfigPoller, error) { - return newConfigPoller(lggr, client, destChainPoller, aggregatorContractAddr, configStoreAddr) +type CPConfig struct { + Client client.Client + DestinationChainPoller logpoller.LogPoller + AggregatorContractAddress common.Address + ConfigStoreAddress *common.Address + LogDecoder LogDecoder +} + +func NewConfigPoller(lggr logger.Logger, cfg CPConfig) (evmRelayTypes.ConfigPoller, error) { + return newConfigPoller(lggr, cfg.Client, cfg.DestinationChainPoller, cfg.AggregatorContractAddress, cfg.ConfigStoreAddress, cfg.LogDecoder) } -func newConfigPoller(lggr logger.Logger, client client.Client, destChainPoller logpoller.LogPoller, aggregatorContractAddr common.Address, configStoreAddr *common.Address) (*configPoller, error) { - err := destChainPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(aggregatorContractAddr), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{aggregatorContractAddr}}) +func newConfigPoller(lggr logger.Logger, client client.Client, destChainPoller logpoller.LogPoller, aggregatorContractAddr common.Address, configStoreAddr *common.Address, ld LogDecoder) (*configPoller, error) { + err := destChainPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(aggregatorContractAddr), EventSigs: []common.Hash{ld.EventSig()}, Addresses: []common.Address{aggregatorContractAddr}}) if err != nil { return nil, err } @@ -133,6 +93,7 @@ func newConfigPoller(lggr logger.Logger, client client.Client, destChainPoller l aggregatorContractAddr: aggregatorContractAddr, client: client, aggregatorContract: aggregatorContract, + ld: ld, } if configStoreAddr != nil { @@ -164,7 +125,7 @@ func (cp *configPoller) Replay(ctx context.Context, fromBlock int64) error { // LatestConfigDetails returns the latest config details from the logs func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { - latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(ConfigSet, cp.aggregatorContractAddr, 1, pg.WithParentCtx(ctx)) + latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(cp.ld.EventSig(), cp.aggregatorContractAddr, 1, pg.WithParentCtx(ctx)) if err != nil { if errors.Is(err, sql.ErrNoRows) { if cp.isConfigStoreAvailable() { @@ -176,7 +137,7 @@ func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock } return 0, ocrtypes.ConfigDigest{}, err } - latestConfigSet, err := configFromLog(latest.Data) + latestConfigSet, err := cp.ld.Decode(latest.Data) if err != nil { return 0, ocrtypes.ConfigDigest{}, err } @@ -185,7 +146,7 @@ func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock // LatestConfig returns the latest config from the logs on a certain block func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) (ocrtypes.ContractConfig, error) { - lgs, err := cp.destChainLogPoller.Logs(int64(changedInBlock), int64(changedInBlock), ConfigSet, cp.aggregatorContractAddr, pg.WithParentCtx(ctx)) + lgs, err := cp.destChainLogPoller.Logs(int64(changedInBlock), int64(changedInBlock), cp.ld.EventSig(), cp.aggregatorContractAddr, pg.WithParentCtx(ctx)) if err != nil { return ocrtypes.ContractConfig{}, err } @@ -196,7 +157,7 @@ func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) } return ocrtypes.ContractConfig{}, fmt.Errorf("no logs found for config on contract %s (chain %s) at block %d", cp.aggregatorContractAddr.Hex(), cp.client.ConfiguredChainID().String(), changedInBlock) } - latestConfigSet, err := configFromLog(lgs[len(lgs)-1].Data) + latestConfigSet, err := cp.ld.Decode(lgs[len(lgs)-1].Data) if err != nil { return ocrtypes.ContractConfig{}, err } diff --git a/core/services/relay/evm/config_poller_test.go b/core/services/relay/evm/config_poller_test.go index 79533a06f01..cd66e5479bf 100644 --- a/core/services/relay/evm/config_poller_test.go +++ b/core/services/relay/evm/config_poller_test.go @@ -55,6 +55,8 @@ func TestConfigPoller(t *testing.T) { var linkTokenAddress common.Address var accessAddress common.Address + ld := OCR2AggregatorLogDecoder + { key, err := crypto.GenerateKey() require.NoError(t, err) @@ -92,7 +94,7 @@ func TestConfigPoller(t *testing.T) { } t.Run("LatestConfig errors if there is no config in logs and config store is unconfigured", func(t *testing.T) { - cp, err := NewConfigPoller(lggr, ethClient, lp, ocrAddress, nil) + cp, err := NewConfigPoller(lggr, CPConfig{ethClient, lp, ocrAddress, nil, ld}) require.NoError(t, err) _, err = cp.LatestConfig(testutils.Context(t), 0) @@ -101,7 +103,7 @@ func TestConfigPoller(t *testing.T) { }) t.Run("happy path (with config store)", func(t *testing.T) { - cp, err := NewConfigPoller(lggr, ethClient, lp, ocrAddress, &configStoreContractAddr) + cp, err := NewConfigPoller(lggr, CPConfig{ethClient, lp, ocrAddress, &configStoreContractAddr, ld}) require.NoError(t, err) // Should have no config to begin with. _, configDigest, err := cp.LatestConfigDetails(testutils.Context(t)) @@ -172,7 +174,7 @@ func TestConfigPoller(t *testing.T) { mp.On("LatestLogByEventSigWithConfs", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, sql.ErrNoRows) t.Run("if callLatestConfigDetails succeeds", func(t *testing.T) { - cp, err := newConfigPoller(lggr, ethClient, mp, ocrAddress, &configStoreContractAddr) + cp, err := newConfigPoller(lggr, ethClient, mp, ocrAddress, &configStoreContractAddr, ld) require.NoError(t, err) t.Run("when config has not been set, returns zero values", func(t *testing.T) { @@ -209,7 +211,7 @@ func TestConfigPoller(t *testing.T) { failingClient := new(evmClientMocks.Client) failingClient.On("ConfiguredChainID").Return(big.NewInt(42)) failingClient.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("something exploded")) - cp, err := newConfigPoller(lggr, failingClient, mp, ocrAddress, &configStoreContractAddr) + cp, err := newConfigPoller(lggr, failingClient, mp, ocrAddress, &configStoreContractAddr, ld) require.NoError(t, err) cp.configStoreContractAddr = &configStoreContractAddr @@ -248,7 +250,7 @@ func TestConfigPoller(t *testing.T) { mp.On("LatestLogByEventSigWithConfs", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, sql.ErrNoRows) t.Run("if callReadConfig succeeds", func(t *testing.T) { - cp, err := newConfigPoller(lggr, ethClient, mp, ocrAddress, &configStoreContractAddr) + cp, err := newConfigPoller(lggr, ethClient, mp, ocrAddress, &configStoreContractAddr, ld) require.NoError(t, err) t.Run("when config has not been set, returns error", func(t *testing.T) { @@ -310,7 +312,7 @@ func TestConfigPoller(t *testing.T) { // initial call to retrieve config store address from aggregator return *callArgs.To == ocrAddress }), mock.Anything).Return(nil, errors.New("something exploded")).Once() - cp, err := newConfigPoller(lggr, failingClient, mp, ocrAddress, &configStoreContractAddr) + cp, err := newConfigPoller(lggr, failingClient, mp, ocrAddress, &configStoreContractAddr, ld) require.NoError(t, err) _, err = cp.LatestConfig(testutils.Context(t), 0) diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 4c5e7952508..4de4e48bd90 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -17,7 +17,6 @@ import ( "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median/evmreportcodec" - "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -42,6 +41,23 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) +var ( + OCR2AggregatorTransmissionContractABI abi.ABI + OCR2AggregatorLogDecoder LogDecoder +) + +func init() { + var err error + OCR2AggregatorTransmissionContractABI, err = abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorMetaData.ABI)) + if err != nil { + panic(err) + } + OCR2AggregatorLogDecoder, err = newOCR2AggregatorLogDecoder() + if err != nil { + panic(err) + } +} + var _ commontypes.Relayer = &Relayer{} //nolint:staticcheck type Relayer struct { @@ -128,12 +144,12 @@ func (r *Relayer) HealthReport() (report map[string]error) { func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.PluginProvider, error) { lggr := r.lggr.Named("PluginProvider").Named(rargs.ExternalJobID.String()) - configWatcher, err := newConfigProvider(r.lggr, r.chain, types.NewRelayOpts(rargs)) + configWatcher, err := newStandardConfigProvider(r.lggr, r.chain, types.NewRelayOpts(rargs)) if err != nil { return nil, err } - transmitter, err := newContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}) + transmitter, err := newOnChainContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) if err != nil { return nil, err } @@ -168,7 +184,7 @@ func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commonty if relayConfig.ChainID.String() != r.chain.ID().String() { return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), r.chain.ID().String()) } - cw, err := newConfigProvider(lggr, r.chain, relayOpts) + cp, err := newMercuryConfigProvider(lggr, r.chain, relayOpts) if err != nil { return nil, pkgerrors.WithStack(err) } @@ -204,9 +220,9 @@ func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commonty default: return nil, fmt.Errorf("invalid feed version %d", feedID.Version()) } - transmitter := mercury.NewTransmitter(lggr, cw.ContractConfigTracker(), client, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.db, r.pgCfg, transmitterCodec) + transmitter := mercury.NewTransmitter(lggr, client, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.db, r.pgCfg, transmitterCodec) - return NewMercuryProvider(cw, r.chainReader, r.codec, NewMercuryChainReader(r.chain.HeadTracker()), transmitter, reportCodecV1, reportCodecV2, reportCodecV3, lggr), nil + return NewMercuryProvider(cp, r.chainReader, r.codec, NewMercuryChainReader(r.chain.HeadTracker()), transmitter, reportCodecV1, reportCodecV2, reportCodecV3, lggr), nil } func (r *Relayer) NewLLOProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.LLOProvider, error) { @@ -219,7 +235,8 @@ func (r *Relayer) NewFunctionsProvider(rargs commontypes.RelayArgs, pargs common return NewFunctionsProvider(r.chain, rargs, pargs, lggr, r.ks.Eth(), functions.FunctionsPlugin) } -func (r *Relayer) NewConfigProvider(args commontypes.RelayArgs) (commontypes.ConfigProvider, error) { +// NewConfigProvider is called by bootstrap jobs +func (r *Relayer) NewConfigProvider(args commontypes.RelayArgs) (configProvider commontypes.ConfigProvider, err error) { lggr := r.lggr.Named("ConfigProvider").Named(args.ExternalJobID.String()) relayOpts := types.NewRelayOpts(args) relayConfig, err := relayOpts.RelayConfig() @@ -231,7 +248,24 @@ func (r *Relayer) NewConfigProvider(args commontypes.RelayArgs) (commontypes.Con return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), r.chain.ID().String()) } - configProvider, err := newConfigProvider(lggr, r.chain, relayOpts) + // Handle legacy jobs which did not yet specify provider type and + // switched between median/mercury based on presence of feed ID + if args.ProviderType == "" { + if relayConfig.FeedID == nil { + args.ProviderType = "median" + } else { + args.ProviderType = "mercury" + } + } + + switch args.ProviderType { + case "median": + configProvider, err = newStandardConfigProvider(lggr, r.chain, relayOpts) + case "mercury": + configProvider, err = newMercuryConfigProvider(lggr, r.chain, relayOpts) + default: + return nil, fmt.Errorf("unrecognized provider type: %q", args.ProviderType) + } if err != nil { // Never return (*configProvider)(nil) return nil, err @@ -261,7 +295,6 @@ type configWatcher struct { services.StateMachine lggr logger.Logger contractAddress common.Address - contractABI abi.ABI offchainDigester ocrtypes.OffchainConfigDigester configPoller types.ConfigPoller chain legacyevm.Chain @@ -274,7 +307,6 @@ type configWatcher struct { func newConfigWatcher(lggr logger.Logger, contractAddress common.Address, - contractABI abi.ABI, offchainDigester ocrtypes.OffchainConfigDigester, configPoller types.ConfigPoller, chain legacyevm.Chain, @@ -285,7 +317,6 @@ func newConfigWatcher(lggr logger.Logger, return &configWatcher{ lggr: lggr.Named("ConfigWatcher").Named(contractAddress.String()), contractAddress: contractAddress, - contractABI: contractABI, offchainDigester: offchainDigester, configPoller: configPoller, chain: chain, @@ -341,63 +372,12 @@ func (c *configWatcher) ContractConfigTracker() ocrtypes.ContractConfigTracker { return c.configPoller } -func newConfigProvider(lggr logger.Logger, chain legacyevm.Chain, opts *types.RelayOpts) (*configWatcher, error) { - if !common.IsHexAddress(opts.ContractID) { - return nil, pkgerrors.Errorf("invalid contractID, expected hex address") - } - - aggregatorAddress := common.HexToAddress(opts.ContractID) - contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorMetaData.ABI)) - if err != nil { - return nil, pkgerrors.Wrap(err, "could not get contract ABI JSON") - } - var cp types.ConfigPoller - - relayConfig, err := opts.RelayConfig() - if err != nil { - return nil, fmt.Errorf("failed to get relay config: %w", err) - } - if relayConfig.FeedID != nil { - cp, err = mercury.NewConfigPoller( - lggr.Named(relayConfig.FeedID.String()), - chain.LogPoller(), - aggregatorAddress, - *relayConfig.FeedID, - // TODO: Does mercury need to support config contract? DF-19182 - ) - } else { - cp, err = NewConfigPoller( - lggr, - chain.Client(), - chain.LogPoller(), - aggregatorAddress, - relayConfig.ConfigContractAddress, - ) - } - if err != nil { - return nil, err - } - - var offchainConfigDigester ocrtypes.OffchainConfigDigester - if relayConfig.FeedID != nil { - // Mercury - offchainConfigDigester = mercury.NewOffchainConfigDigester(*relayConfig.FeedID, chain.Config().EVM().ChainID(), aggregatorAddress) - } else { - // Non-mercury - offchainConfigDigester = evmutil.EVMOffchainConfigDigester{ - ChainID: chain.Config().EVM().ChainID().Uint64(), - ContractAddress: aggregatorAddress, - } - } - return newConfigWatcher(lggr, aggregatorAddress, contractABI, offchainConfigDigester, cp, chain, relayConfig.FromBlock, opts.New), nil -} - type configTransmitterOpts struct { // override the gas limit default provided in the config watcher pluginGasLimit *uint32 } -func newContractTransmitter(lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts) (*contractTransmitter, error) { +func newOnChainContractTransmitter(lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts, transmissionContractABI abi.ABI) (*contractTransmitter, error) { var relayConfig types.RelayConfig if err := json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { return nil, err @@ -461,7 +441,7 @@ func newContractTransmitter(lggr logger.Logger, rargs commontypes.RelayArgs, tra return NewOCRContractTransmitter( configWatcher.contractAddress, configWatcher.chain.Client(), - configWatcher.contractABI, + transmissionContractABI, transmitter, configWatcher.chain.LogPoller(), lggr, @@ -485,13 +465,13 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp } contractID := common.HexToAddress(relayOpts.ContractID) - configWatcher, err := newConfigProvider(lggr, r.chain, relayOpts) + configWatcher, err := newStandardConfigProvider(lggr, r.chain, relayOpts) if err != nil { return nil, err } reportCodec := evmreportcodec.ReportCodec{} - contractTransmitter, err := newContractTransmitter(lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}) + contractTransmitter, err := newOnChainContractTransmitter(lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) if err != nil { return nil, err } diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go index b957ab56f3b..d4e91034496 100644 --- a/core/services/relay/evm/functions.go +++ b/core/services/relay/evm/functions.go @@ -4,14 +4,10 @@ import ( "context" "encoding/json" "fmt" - "strings" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - "go.uber.org/multierr" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -145,10 +141,6 @@ func newFunctionsConfigProvider(pluginType functionsRelay.FunctionsPluginType, c } routerContractAddress := common.HexToAddress(args.ContractID) - contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorMetaData.ABI)) - if err != nil { - return nil, errors.Wrap(err, "could not get contract ABI JSON") - } cp, err := functionsRelay.NewFunctionsConfigPoller(pluginType, chain.LogPoller(), lggr) if err != nil { @@ -159,7 +151,7 @@ func newFunctionsConfigProvider(pluginType functionsRelay.FunctionsPluginType, c offchainConfigDigester := functionsRelay.NewFunctionsOffchainConfigDigester(pluginType, chain.ID().Uint64()) logPollerWrapper.SubscribeToUpdates("FunctionsOffchainConfigDigester", offchainConfigDigester) - return newConfigWatcher(lggr, routerContractAddress, contractABI, offchainConfigDigester, cp, chain, fromBlock, args.New), nil + return newConfigWatcher(lggr, routerContractAddress, offchainConfigDigester, cp, chain, fromBlock, args.New), nil } func newFunctionsContractTransmitter(contractVersion uint32, rargs commontypes.RelayArgs, transmitterID string, configWatcher *configWatcher, ethKeystore keystore.Eth, logPollerWrapper evmRelayTypes.LogPollerWrapper, lggr logger.Logger) (ContractTransmitter, error) { @@ -222,7 +214,7 @@ func newFunctionsContractTransmitter(contractVersion uint32, rargs commontypes.R functionsTransmitter, err := functionsRelay.NewFunctionsContractTransmitter( configWatcher.chain.Client(), - configWatcher.contractABI, + OCR2AggregatorTransmissionContractABI, transmitter, configWatcher.chain.LogPoller(), lggr, diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go index 6a4bfeb6dd0..9444b904b89 100644 --- a/core/services/relay/evm/mercury/transmitter.go +++ b/core/services/relay/evm/mercury/transmitter.go @@ -108,7 +108,6 @@ type mercuryTransmitter struct { services.StateMachine lggr logger.Logger rpcClient wsrpc.Client - cfgTracker ConfigTracker persistenceManager *PersistenceManager codec TransmitterReportDecoder @@ -149,14 +148,13 @@ func getPayloadTypes() abi.Arguments { }) } -func NewTransmitter(lggr logger.Logger, cfgTracker ConfigTracker, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey, jobID int32, feedID [32]byte, db *sqlx.DB, cfg pg.QConfig, codec TransmitterReportDecoder) *mercuryTransmitter { +func NewTransmitter(lggr logger.Logger, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey, jobID int32, feedID [32]byte, db *sqlx.DB, cfg pg.QConfig, codec TransmitterReportDecoder) *mercuryTransmitter { feedIDHex := fmt.Sprintf("0x%x", feedID[:]) persistenceManager := NewPersistenceManager(lggr, NewORM(db, lggr, cfg), jobID, maxTransmitQueueSize, flushDeletesFrequency, pruneFrequency) return &mercuryTransmitter{ services.StateMachine{}, lggr.Named("MercuryTransmitter").With("feedID", feedIDHex), rpcClient, - cfgTracker, persistenceManager, codec, feedID, diff --git a/core/services/relay/evm/mercury/transmitter_test.go b/core/services/relay/evm/mercury/transmitter_test.go index c8a68d41a16..188beff5113 100644 --- a/core/services/relay/evm/mercury/transmitter_test.go +++ b/core/services/relay/evm/mercury/transmitter_test.go @@ -27,6 +27,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`) pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`) q := NewTransmitQueue(lggr, "", 0, nil, nil) + codec := new(mockCodec) t.Run("v1 report transmission successfully enqueued", func(t *testing.T) { report := sampleV1Report @@ -40,7 +41,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) mt.queue = q err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) @@ -58,7 +59,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) mt.queue = q err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) @@ -76,7 +77,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) mt.queue = q err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) @@ -88,6 +89,8 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) db := pgtest.NewSqlxDB(t) + var jobID int32 + codec := new(mockCodec) t.Run("successful query", func(t *testing.T) { c := mocks.MockWSRPCClient{ @@ -101,7 +104,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) ts, err := mt.LatestTimestamp(testutils.Context(t)) require.NoError(t, err) @@ -116,7 +119,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) ts, err := mt.LatestTimestamp(testutils.Context(t)) require.NoError(t, err) @@ -129,7 +132,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { return nil, errors.New("something exploded") }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) _, err := mt.LatestTimestamp(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -151,6 +154,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) db := pgtest.NewSqlxDB(t) + var jobID int32 codec := new(mockCodec) @@ -167,7 +171,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), codec) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) t.Run("BenchmarkPriceFromReport succeeds", func(t *testing.T) { codec.val = originalPrice @@ -197,7 +201,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) require.NoError(t, err) @@ -210,7 +214,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { return nil, errors.New("something exploded") }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) _, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -222,6 +226,8 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { lggr := logger.TestLogger(t) db := pgtest.NewSqlxDB(t) + var jobID int32 + codec := new(mockCodec) t.Run("successful query", func(t *testing.T) { c := mocks.MockWSRPCClient{ @@ -235,7 +241,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) @@ -250,7 +256,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), codec) bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) @@ -262,7 +268,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return nil, errors.New("something exploded") }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), codec) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -279,7 +285,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) + mt := NewTransmitter(lggr, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), codec) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "latestReport failed; mismatched feed IDs, expected: 0x1c916b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472, got: 0x") diff --git a/core/services/relay/evm/mercury_config_provider.go b/core/services/relay/evm/mercury_config_provider.go new file mode 100644 index 00000000000..027a3cfb27c --- /dev/null +++ b/core/services/relay/evm/mercury_config_provider.go @@ -0,0 +1,44 @@ +package evm + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +func newMercuryConfigProvider(lggr logger.Logger, chain legacyevm.Chain, opts *types.RelayOpts) (commontypes.ConfigProvider, error) { + if !common.IsHexAddress(opts.ContractID) { + return nil, errors.New("invalid contractID, expected hex address") + } + + aggregatorAddress := common.HexToAddress(opts.ContractID) + + relayConfig, err := opts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + if relayConfig.FeedID == nil { + return nil, errors.New("feed ID is required for tracking config on mercury contracts") + } + cp, err := mercury.NewConfigPoller( + lggr.Named(relayConfig.FeedID.String()), + chain.LogPoller(), + aggregatorAddress, + *relayConfig.FeedID, + // TODO: Does mercury need to support config contract? DF-19182 + ) + if err != nil { + return nil, err + } + + offchainConfigDigester := mercury.NewOffchainConfigDigester(*relayConfig.FeedID, chain.Config().EVM().ChainID(), aggregatorAddress) + return newConfigWatcher(lggr, aggregatorAddress, offchainConfigDigester, cp, chain, relayConfig.FromBlock, opts.New), nil +} diff --git a/core/services/relay/evm/ocr2aggregator_decoder.go b/core/services/relay/evm/ocr2aggregator_decoder.go new file mode 100644 index 00000000000..92abfad1896 --- /dev/null +++ b/core/services/relay/evm/ocr2aggregator_decoder.go @@ -0,0 +1,65 @@ +package evm + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +var _ LogDecoder = &ocr2AggregatorLogDecoder{} + +type ocr2AggregatorLogDecoder struct { + eventName string + eventSig common.Hash + abi *abi.ABI +} + +func newOCR2AggregatorLogDecoder() (*ocr2AggregatorLogDecoder, error) { + const eventName = "ConfigSet" + abi, err := ocr2aggregator.OCR2AggregatorMetaData.GetAbi() + if err != nil { + return nil, err + } + return &ocr2AggregatorLogDecoder{ + eventName: eventName, + eventSig: abi.Events[eventName].ID, + abi: abi, + }, nil +} + +func (d *ocr2AggregatorLogDecoder) Decode(rawLog []byte) (ocrtypes.ContractConfig, error) { + unpacked := new(ocr2aggregator.OCR2AggregatorConfigSet) + err := d.abi.UnpackIntoInterface(unpacked, d.eventName, rawLog) + if err != nil { + return ocrtypes.ContractConfig{}, fmt.Errorf("failed to unpack log data: %w", err) + } + + var transmitAccounts []ocrtypes.Account + for _, addr := range unpacked.Transmitters { + transmitAccounts = append(transmitAccounts, ocrtypes.Account(addr.Hex())) + } + var signers []ocrtypes.OnchainPublicKey + for _, addr := range unpacked.Signers { + addr := addr + signers = append(signers, addr[:]) + } + + return ocrtypes.ContractConfig{ + ConfigDigest: unpacked.ConfigDigest, + ConfigCount: unpacked.ConfigCount, + Signers: signers, + Transmitters: transmitAccounts, + F: unpacked.F, + OnchainConfig: unpacked.OnchainConfig, + OffchainConfigVersion: unpacked.OffchainConfigVersion, + OffchainConfig: unpacked.OffchainConfig, + }, nil +} + +func (d *ocr2AggregatorLogDecoder) EventSig() common.Hash { + return d.eventSig +} diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index fd1fdb70480..6bde444d80b 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -4,36 +4,30 @@ import ( "context" "encoding/json" "fmt" - "strings" - iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" - evm "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" - - "github.com/smartcontractkit/chainlink-common/pkg/types/automation" - - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/jmoiron/sqlx" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/automation" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + evm "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -96,7 +90,7 @@ func (r *ocr2keeperRelayer) NewOCR2KeeperProvider(rargs commontypes.RelayArgs, p } gasLimit := cfgWatcher.chain.Config().EVM().OCR2().Automation().GasLimit() - contractTransmitter, err := newContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, cfgWatcher, configTransmitterOpts{pluginGasLimit: &gasLimit}) + contractTransmitter, err := newOnChainContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, cfgWatcher, configTransmitterOpts{pluginGasLimit: &gasLimit}, OCR2AggregatorTransmissionContractABI) if err != nil { return nil, err } @@ -221,18 +215,17 @@ func newOCR2KeeperConfigProvider(lggr logger.Logger, chain legacyevm.Chain, rarg } contractAddress := common.HexToAddress(rargs.ContractID) - contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorMetaData.ABI)) - if err != nil { - return nil, errors.Wrap(err, "could not get OCR2Aggregator ABI JSON") - } configPoller, err := NewConfigPoller( lggr.With("contractID", rargs.ContractID), - chain.Client(), - chain.LogPoller(), - contractAddress, - // TODO: Does ocr2keeper need to support config contract? DF-19182 - nil, + CPConfig{ + chain.Client(), + chain.LogPoller(), + contractAddress, + // TODO: Does ocr2keeper need to support config contract? DF-19182 + nil, + OCR2AggregatorLogDecoder, + }, ) if err != nil { return nil, errors.Wrap(err, "failed to create config poller") @@ -246,7 +239,6 @@ func newOCR2KeeperConfigProvider(lggr logger.Logger, chain legacyevm.Chain, rarg return newConfigWatcher( lggr, contractAddress, - contractABI, offchainConfigDigester, configPoller, chain, diff --git a/core/services/relay/evm/ocr2vrf.go b/core/services/relay/evm/ocr2vrf.go index d300c71fbef..d421b38ea77 100644 --- a/core/services/relay/evm/ocr2vrf.go +++ b/core/services/relay/evm/ocr2vrf.go @@ -3,14 +3,10 @@ package evm import ( "encoding/json" "fmt" - "strings" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/jmoiron/sqlx" - "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -67,7 +63,7 @@ func (r *ocr2vrfRelayer) NewDKGProvider(rargs commontypes.RelayArgs, pargs commo if err != nil { return nil, err } - contractTransmitter, err := newContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}) + contractTransmitter, err := newOnChainContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) if err != nil { return nil, err } @@ -90,7 +86,7 @@ func (r *ocr2vrfRelayer) NewOCR2VRFProvider(rargs commontypes.RelayArgs, pargs c if err != nil { return nil, err } - contractTransmitter, err := newContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}) + contractTransmitter, err := newOnChainContractTransmitter(r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) if err != nil { return nil, err } @@ -146,17 +142,16 @@ func newOCR2VRFConfigProvider(lggr logger.Logger, chain legacyevm.Chain, rargs c } contractAddress := common.HexToAddress(rargs.ContractID) - contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorABI)) - if err != nil { - return nil, errors.Wrap(err, "could not get OCR2Aggregator ABI JSON") - } configPoller, err := NewConfigPoller( lggr.With("contractID", rargs.ContractID), - chain.Client(), - chain.LogPoller(), - contractAddress, - // TODO: Does ocr2vrf need to support config contract? DF-19182 - nil, + CPConfig{ + chain.Client(), + chain.LogPoller(), + contractAddress, + // TODO: Does ocr2vrf need to support config contract? DF-19182 + nil, + OCR2AggregatorLogDecoder, + }, ) if err != nil { return nil, err @@ -170,7 +165,6 @@ func newOCR2VRFConfigProvider(lggr logger.Logger, chain legacyevm.Chain, rargs c return newConfigWatcher( lggr, contractAddress, - contractABI, offchainConfigDigester, configPoller, chain, diff --git a/core/services/relay/evm/standard_config_provider.go b/core/services/relay/evm/standard_config_provider.go new file mode 100644 index 00000000000..0de48240b7d --- /dev/null +++ b/core/services/relay/evm/standard_config_provider.go @@ -0,0 +1,52 @@ +package evm + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +func newStandardConfigProvider(lggr logger.Logger, chain legacyevm.Chain, opts *types.RelayOpts) (*configWatcher, error) { + if !common.IsHexAddress(opts.ContractID) { + return nil, errors.New("invalid contractID, expected hex address") + } + + aggregatorAddress := common.HexToAddress(opts.ContractID) + offchainConfigDigester := evmutil.EVMOffchainConfigDigester{ + ChainID: chain.Config().EVM().ChainID().Uint64(), + ContractAddress: aggregatorAddress, + } + return newContractConfigProvider(lggr, chain, opts, aggregatorAddress, OCR2AggregatorLogDecoder, offchainConfigDigester) +} + +func newContractConfigProvider(lggr logger.Logger, chain legacyevm.Chain, opts *types.RelayOpts, aggregatorAddress common.Address, ld LogDecoder, digester ocrtypes.OffchainConfigDigester) (*configWatcher, error) { + var cp types.ConfigPoller + + relayConfig, err := opts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + cp, err = NewConfigPoller( + lggr, + CPConfig{ + chain.Client(), + chain.LogPoller(), + aggregatorAddress, + relayConfig.ConfigContractAddress, + ld, + }, + ) + if err != nil { + return nil, err + } + + return newConfigWatcher(lggr, aggregatorAddress, digester, cp, chain, relayConfig.FromBlock, opts.New), nil +} From 85e8858a085598fe2e0ae1dd7f0f3cda0696b08f Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:48:39 -0800 Subject: [PATCH 21/98] Add a simple Codec test (#12006) Hopefully a clear minimal example. --- core/services/relay/evm/codec_test.go | 25 ++++++++++++++++++++ core/services/relay/evm/types/codec_entry.go | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/services/relay/evm/codec_test.go b/core/services/relay/evm/codec_test.go index b13051cb010..2f9a4639d41 100644 --- a/core/services/relay/evm/codec_test.go +++ b/core/services/relay/evm/codec_test.go @@ -50,6 +50,31 @@ func TestCodec(t *testing.T) { }) } +func TestCodec_SimpleEncode(t *testing.T) { + codecName := "my_codec" + input := map[string]any{ + "Report": int32(6), + "Meta": "abcdefg", + } + evmEncoderConfig := `[{"Name":"Report","Type":"int32"},{"Name":"Meta","Type":"string"}]` + + codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ + codecName: {TypeABI: evmEncoderConfig}, + }} + c, err := evm.NewCodec(codecConfig) + require.NoError(t, err) + + result, err := c.Encode(testutils.Context(t), input, codecName) + require.NoError(t, err) + expected := + "0000000000000000000000000000000000000000000000000000000000000006" + // int32(6) + "0000000000000000000000000000000000000000000000000000000000000040" + // total bytes occupied by the string (64) + "0000000000000000000000000000000000000000000000000000000000000007" + // length of the string (7 chars) + "6162636465666700000000000000000000000000000000000000000000000000" // actual string + + require.Equal(t, expected, hexutil.Encode(result)[2:]) +} + type codecInterfaceTester struct{} func (it *codecInterfaceTester) Setup(_ *testing.T) {} diff --git a/core/services/relay/evm/types/codec_entry.go b/core/services/relay/evm/types/codec_entry.go index b87f7ced721..21e5ac59847 100644 --- a/core/services/relay/evm/types/codec_entry.go +++ b/core/services/relay/evm/types/codec_entry.go @@ -222,7 +222,7 @@ func getNativeAndCheckedTypes(curType *abi.Type) (reflect.Type, reflect.Type, er func createTupleType(curType *abi.Type, converter func(reflect.Type) reflect.Type) (reflect.Type, reflect.Type, error) { if len(curType.TupleElems) == 0 { if curType.TupleType == nil { - return nil, nil, fmt.Errorf("%w: unsupported solitidy type: %v", commontypes.ErrInvalidType, curType.String()) + return nil, nil, fmt.Errorf("%w: unsupported solidity type: %v", commontypes.ErrInvalidType, curType.String()) } return curType.TupleType, curType.TupleType, nil } From 1d0f9ec63433bb6c48688f7002621451736bb4dc Mon Sep 17 00:00:00 2001 From: Tate Date: Tue, 13 Feb 2024 15:18:08 -0700 Subject: [PATCH 22/98] Handle a 0 exit code from the remote runner instead of always failing (#12015) --- integration-tests/scripts/entrypoint | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/integration-tests/scripts/entrypoint b/integration-tests/scripts/entrypoint index 8797765ab2c..d4ebe722a1d 100755 --- a/integration-tests/scripts/entrypoint +++ b/integration-tests/scripts/entrypoint @@ -21,14 +21,17 @@ exit_code=$? echo "Test exit code: ${exit_code}" -# 3 is the code for an interrupted test, we only want to restart the test when the test is interrupted and in a state -# that it can recover from. Otherwise we mark the test as "passed" as far as K8s is concerned so it doesn't restart it. -if [ $exit_code -eq 3 ]; then -echo "Test was interrupted, exiting with 1 exit code to trigger K8s to restart" - exit 1 # Exiting with non-zero status to trigger pod restart -else - echo "Test either panicked or had some sort of failure. We're exiting with a non-zero exit code so that K8s doesn't restart the pod." - echo "TEST_FAILED" +# Check if the test did not pass (non-zero exit code) +if [ $exit_code -ne 0 ]; then + # 3 is the code for an interrupted test, we only want to restart the test when the test is interrupted and in a state + # that it can recover from. Otherwise we mark the test as "passed" as far as K8s is concerned so it doesn't restart it. + if [ $exit_code -eq 3 ]; then + echo "Test was interrupted, exiting with 1 exit code to trigger K8s to restart" + exit 1 # Exiting with non-zero status to trigger pod restart + else + echo "Test either panicked or had some sort of failure. We're exiting with a non-zero exit code so that K8s doesn't restart the pod." + echo "TEST_FAILED" + fi fi # Sleep for the amount of time provided by the POST_RUN_SLEEP env var @@ -44,4 +47,4 @@ if [ -n "${UPLOAD_MEM_PROFILE}" ]; then fi echo "Exiting with 0 exit code as test is either completed, or failed and cannot be restarted" -exit 0 \ No newline at end of file +exit 0 From ea53e42de9071fe0ce944d65c776b1ec032fdcc8 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 13 Feb 2024 18:55:32 -0600 Subject: [PATCH 23/98] core/web: improve health CLI readabilty (#12021) --- core/web/health_controller.go | 6 +-- core/web/testdata/body/health.txt | 38 +++++++++---------- core/web/testdata/health.txt | 18 ++++----- testdata/scripts/health/default.txtar | 16 ++++---- testdata/scripts/health/multi-chain.txtar | 46 +++++++++++------------ 5 files changed, 62 insertions(+), 62 deletions(-) diff --git a/core/web/health_controller.go b/core/web/health_controller.go index 7ab07291b58..bd775671d73 100644 --- a/core/web/health_controller.go +++ b/core/web/health_controller.go @@ -125,12 +125,12 @@ func (hc *HealthController) Health(c *gin.Context) { func writeTextTo(w io.Writer, checks []presenters.Check) error { slices.SortFunc(checks, presenters.CmpCheckName) for _, ch := range checks { - status := "?" + status := "? " switch ch.Status { case HealthStatusPassing: - status = "-" + status = "ok " case HealthStatusFailing: - status = "!" + status = "! " } if _, err := fmt.Fprintf(w, "%s%s\n", status, ch.Name); err != nil { return err diff --git a/core/web/testdata/body/health.txt b/core/web/testdata/body/health.txt index 59f63c26413..03a78c22c28 100644 --- a/core/web/testdata/body/health.txt +++ b/core/web/testdata/body/health.txt @@ -1,20 +1,20 @@ --EVM.0 --EVM.0.BalanceMonitor --EVM.0.HeadBroadcaster --EVM.0.HeadTracker -!EVM.0.HeadTracker.HeadListener +ok EVM.0 +ok EVM.0.BalanceMonitor +ok EVM.0.HeadBroadcaster +ok EVM.0.HeadTracker +! EVM.0.HeadTracker.HeadListener Listener is not connected --EVM.0.LogBroadcaster --EVM.0.Txm --EVM.0.Txm.BlockHistoryEstimator --EVM.0.Txm.Broadcaster --EVM.0.Txm.Confirmer --EVM.0.Txm.WrappedEvmEstimator --JobSpawner --Mailbox.Monitor --Mercury.WSRPCPool --Mercury.WSRPCPool.CacheSet --PipelineORM --PipelineRunner --PromReporter --TelemetryManager +ok EVM.0.LogBroadcaster +ok EVM.0.Txm +ok EVM.0.Txm.BlockHistoryEstimator +ok EVM.0.Txm.Broadcaster +ok EVM.0.Txm.Confirmer +ok EVM.0.Txm.WrappedEvmEstimator +ok JobSpawner +ok Mailbox.Monitor +ok Mercury.WSRPCPool +ok Mercury.WSRPCPool.CacheSet +ok PipelineORM +ok PipelineRunner +ok PromReporter +ok TelemetryManager diff --git a/core/web/testdata/health.txt b/core/web/testdata/health.txt index f155d6c0212..89882cc1159 100644 --- a/core/web/testdata/health.txt +++ b/core/web/testdata/health.txt @@ -1,15 +1,15 @@ --foo -!foo.bar +ok foo +! foo.bar example error message --foo.bar.1 --foo.bar.1.A --foo.bar.1.B -!foo.bar.2 +ok foo.bar.1 +ok foo.bar.1.A +ok foo.bar.1.B +! foo.bar.2 error: this is a multi-line error: new line: original error -!foo.bar.2.A +! foo.bar.2.A failure! --foo.bar.2.B --foo.baz +ok foo.bar.2.B +ok foo.baz diff --git a/testdata/scripts/health/default.txtar b/testdata/scripts/health/default.txtar index 15be9da1fe6..4ca7fba9254 100644 --- a/testdata/scripts/health/default.txtar +++ b/testdata/scripts/health/default.txtar @@ -31,14 +31,14 @@ fj293fbBnlQ!f9vNs HTTPPort = $PORT -- out.txt -- --JobSpawner --Mailbox.Monitor --Mercury.WSRPCPool --Mercury.WSRPCPool.CacheSet --PipelineORM --PipelineRunner --PromReporter --TelemetryManager +ok JobSpawner +ok Mailbox.Monitor +ok Mercury.WSRPCPool +ok Mercury.WSRPCPool.CacheSet +ok PipelineORM +ok PipelineRunner +ok PromReporter +ok TelemetryManager -- out.json -- { diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar index 6a6adb895cb..112d9e3cdb1 100644 --- a/testdata/scripts/health/multi-chain.txtar +++ b/testdata/scripts/health/multi-chain.txtar @@ -60,30 +60,30 @@ Name = 'primary' URL = 'http://stark.node' -- out.txt -- --Cosmos.Foo.Chain --Cosmos.Foo.Txm --EVM.1 --EVM.1.BalanceMonitor --EVM.1.HeadBroadcaster --EVM.1.HeadTracker -!EVM.1.HeadTracker.HeadListener +ok Cosmos.Foo.Chain +ok Cosmos.Foo.Txm +ok EVM.1 +ok EVM.1.BalanceMonitor +ok EVM.1.HeadBroadcaster +ok EVM.1.HeadTracker +! EVM.1.HeadTracker.HeadListener Listener is not connected --EVM.1.LogBroadcaster --EVM.1.Txm --EVM.1.Txm.BlockHistoryEstimator --EVM.1.Txm.Broadcaster --EVM.1.Txm.Confirmer --EVM.1.Txm.WrappedEvmEstimator --JobSpawner --Mailbox.Monitor --Mercury.WSRPCPool --Mercury.WSRPCPool.CacheSet --PipelineORM --PipelineRunner --PromReporter --Solana.Bar --StarkNet.Baz --TelemetryManager +ok EVM.1.LogBroadcaster +ok EVM.1.Txm +ok EVM.1.Txm.BlockHistoryEstimator +ok EVM.1.Txm.Broadcaster +ok EVM.1.Txm.Confirmer +ok EVM.1.Txm.WrappedEvmEstimator +ok JobSpawner +ok Mailbox.Monitor +ok Mercury.WSRPCPool +ok Mercury.WSRPCPool.CacheSet +ok PipelineORM +ok PipelineRunner +ok PromReporter +ok Solana.Bar +ok StarkNet.Baz +ok TelemetryManager -- out.json -- { From a3bd1f7650103e859f0f1fff7e2a305e16f2d597 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Wed, 14 Feb 2024 09:30:34 +0100 Subject: [PATCH 24/98] Improving deletes performance by limiting number of records to scan (#12007) * Improving deletes performance by limiting number of records to scan * Post review fixes - replacing direct latestBlock call with nested query --- core/chains/evm/logpoller/orm.go | 18 ++++++++++++++---- core/chains/evm/logpoller/orm_test.go | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 663c56d10ed..1db8271ccb6 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/logger" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) @@ -196,8 +197,6 @@ func (o *DbORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { } func (o *DbORM) DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) error { - // These deletes are bounded by reorg depth, so they are - // fast and should not slow down the log readers. return o.q.WithOpts(qopts...).Transaction(func(tx pg.Queryer) error { args, err := newQueryArgs(o.chainID). withStartBlock(start). @@ -207,13 +206,24 @@ func (o *DbORM) DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) error { return err } - _, err = tx.NamedExec(`DELETE FROM evm.log_poller_blocks WHERE block_number >= :start_block AND evm_chain_id = :evm_chain_id`, args) + // Applying upper bound filter is critical for Postgres performance (especially for evm.logs table) + // because it allows the planner to properly estimate the number of rows to be scanned. + // If not applied, these queries can become very slow. After some critical number + // of logs, Postgres will try to scan all the logs in the index by block_number. + // Latency without upper bound filter can be orders of magnitude higher for large number of logs. + _, err = tx.NamedExec(`DELETE FROM evm.log_poller_blocks + WHERE evm_chain_id = :evm_chain_id + AND block_number >= :start_block + AND block_number <= (SELECT MAX(block_number) FROM evm.log_poller_blocks WHERE evm_chain_id = :evm_chain_id)`, args) if err != nil { o.lggr.Warnw("Unable to clear reorged blocks, retrying", "err", err) return err } - _, err = tx.NamedExec(`DELETE FROM evm.logs WHERE block_number >= :start_block AND evm_chain_id = :evm_chain_id`, args) + _, err = tx.NamedExec(`DELETE FROM evm.logs + WHERE evm_chain_id = :evm_chain_id + AND block_number >= :start_block + AND block_number <= (SELECT MAX(block_number) FROM evm.logs WHERE evm_chain_id = :evm_chain_id)`, args) if err != nil { o.lggr.Warnw("Unable to clear reorged logs, retrying", "err", err) return err diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 0af62ebd547..bcaa6f72fa0 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -1435,7 +1435,7 @@ func TestInsertLogsInTx(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // clean all logs and blocks between test cases - defer func() { _ = o.DeleteLogsAndBlocksAfter(0) }() + defer func() { _, _ = db.Exec("truncate evm.logs") }() insertErr := o.InsertLogs(tt.logs) logsFromDb, err := o.SelectLogs(0, math.MaxInt, address, event) From efdb8afb4cdcdade3ced48dad7967a2daeb13ae4 Mon Sep 17 00:00:00 2001 From: Lee Yik Jiun Date: Wed, 14 Feb 2024 17:28:41 +0800 Subject: [PATCH 25/98] VRF-878 Gas Optimization V2 Plus (#11982) * Optimize deregisterProvingKey * Optimize fulfillRandomWords * Optimize deregisterMigratableCoordinator * Optimize _isTargetRegistered * Optimize pendingRequestExists * Optimize _deleteSubscription * Optimize getActiveSubscriptionIds * Optimize requestRandomWords * Replace post-increment with pre-increment * Optimize _getFeedData * Optimize ownerCancelSubscription * Optimize getSubscription * Optimize createSubscription * Optimize requestSubscriptionOwnerTransfer * Optimize acceptSubscriptionOwnerTransfer * Optimize addConsumer * Update geth wrappers * Remove proving keys length check in pendingRequestExists --- .../src/v0.8/vrf/dev/SubscriptionAPI.sol | 65 ++++++---- .../src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol | 118 ++++++++++-------- .../vrf_coordinator_v2_5.go | 4 +- .../vrf_v2plus_upgraded_version.go | 4 +- ...rapper-dependency-versions-do-not-edit.txt | 4 +- 5 files changed, 109 insertions(+), 86 deletions(-) diff --git a/contracts/src/v0.8/vrf/dev/SubscriptionAPI.sol b/contracts/src/v0.8/vrf/dev/SubscriptionAPI.sol index a29e526b77d..8a634f904a8 100644 --- a/contracts/src/v0.8/vrf/dev/SubscriptionAPI.sol +++ b/contracts/src/v0.8/vrf/dev/SubscriptionAPI.sol @@ -165,10 +165,11 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr * @dev notably can be called even if there are pending requests, outstanding ones may fail onchain */ function ownerCancelSubscription(uint256 subId) external onlyOwner { - if (s_subscriptionConfigs[subId].owner == address(0)) { + address owner = s_subscriptionConfigs[subId].owner; + if (owner == address(0)) { revert InvalidSubscription(); } - _cancelSubscriptionHelper(subId, s_subscriptionConfigs[subId].owner); + _cancelSubscriptionHelper(subId, owner); } /** @@ -306,14 +307,15 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr override returns (uint96 balance, uint96 nativeBalance, uint64 reqCount, address owner, address[] memory consumers) { - if (s_subscriptionConfigs[subId].owner == address(0)) { + owner = s_subscriptionConfigs[subId].owner; + if (owner == address(0)) { revert InvalidSubscription(); } return ( s_subscriptions[subId].balance, s_subscriptions[subId].nativeBalance, s_subscriptions[subId].reqCount, - s_subscriptionConfigs[subId].owner, + owner, s_subscriptionConfigs[subId].consumers ); } @@ -324,13 +326,14 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr function getActiveSubscriptionIds( uint256 startIndex, uint256 maxCount - ) external view override returns (uint256[] memory) { + ) external view override returns (uint256[] memory ids) { uint256 numSubs = s_subIds.length(); if (startIndex >= numSubs) revert IndexOutOfRange(); uint256 endIndex = startIndex + maxCount; endIndex = endIndex > numSubs || maxCount == 0 ? numSubs : endIndex; - uint256[] memory ids = new uint256[](endIndex - startIndex); - for (uint256 idx = 0; idx < ids.length; idx++) { + uint256 idsLength = endIndex - startIndex; + ids = new uint256[](idsLength); + for (uint256 idx = 0; idx < idsLength; ++idx) { ids[idx] = s_subIds.at(idx + startIndex); } return ids; @@ -339,13 +342,14 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr /** * @inheritdoc IVRFSubscriptionV2Plus */ - function createSubscription() external override nonReentrant returns (uint256) { + function createSubscription() external override nonReentrant returns (uint256 subId) { // Generate a subscription id that is globally unique. - uint256 subId = uint256( - keccak256(abi.encodePacked(msg.sender, blockhash(block.number - 1), address(this), s_currentSubNonce)) + uint64 currentSubNonce = s_currentSubNonce; + subId = uint256( + keccak256(abi.encodePacked(msg.sender, blockhash(block.number - 1), address(this), currentSubNonce)) ); // Increment the subscription nonce counter. - s_currentSubNonce++; + s_currentSubNonce = currentSubNonce + 1; // Initialize storage variables. address[] memory consumers = new address[](0); s_subscriptions[subId] = Subscription({balance: 0, nativeBalance: 0, reqCount: 0}); @@ -369,8 +373,9 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr address newOwner ) external override onlySubOwner(subId) nonReentrant { // Proposing to address(0) would never be claimable so don't need to check. - if (s_subscriptionConfigs[subId].requestedOwner != newOwner) { - s_subscriptionConfigs[subId].requestedOwner = newOwner; + SubscriptionConfig storage subscriptionConfig = s_subscriptionConfigs[subId]; + if (subscriptionConfig.requestedOwner != newOwner) { + subscriptionConfig.requestedOwner = newOwner; emit SubscriptionOwnerTransferRequested(subId, msg.sender, newOwner); } } @@ -379,13 +384,13 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr * @inheritdoc IVRFSubscriptionV2Plus */ function acceptSubscriptionOwnerTransfer(uint256 subId) external override nonReentrant { - if (s_subscriptionConfigs[subId].owner == address(0)) { + address oldOwner = s_subscriptionConfigs[subId].owner; + if (oldOwner == address(0)) { revert InvalidSubscription(); } if (s_subscriptionConfigs[subId].requestedOwner != msg.sender) { revert MustBeRequestedOwner(s_subscriptionConfigs[subId].requestedOwner); } - address oldOwner = s_subscriptionConfigs[subId].owner; s_subscriptionConfigs[subId].owner = msg.sender; s_subscriptionConfigs[subId].requestedOwner = address(0); emit SubscriptionOwnerTransferred(subId, oldOwner, msg.sender); @@ -396,36 +401,42 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr */ function addConsumer(uint256 subId, address consumer) external override onlySubOwner(subId) nonReentrant { // Already maxed, cannot add any more consumers. - if (s_subscriptionConfigs[subId].consumers.length == MAX_CONSUMERS) { + address[] storage consumers = s_subscriptionConfigs[subId].consumers; + if (consumers.length == MAX_CONSUMERS) { revert TooManyConsumers(); } - if (s_consumers[consumer][subId] != 0) { + mapping(uint256 => uint64) storage nonces = s_consumers[consumer]; + if (nonces[subId] != 0) { // Idempotence - do nothing if already added. // Ensures uniqueness in s_subscriptions[subId].consumers. return; } // Initialize the nonce to 1, indicating the consumer is allocated. - s_consumers[consumer][subId] = 1; - s_subscriptionConfigs[subId].consumers.push(consumer); + nonces[subId] = 1; + consumers.push(consumer); emit SubscriptionConsumerAdded(subId, consumer); } function _deleteSubscription(uint256 subId) internal returns (uint96 balance, uint96 nativeBalance) { - SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; - Subscription memory sub = s_subscriptions[subId]; - balance = sub.balance; - nativeBalance = sub.nativeBalance; + address[] storage consumers = s_subscriptionConfigs[subId].consumers; + balance = s_subscriptions[subId].balance; + nativeBalance = s_subscriptions[subId].nativeBalance; // Note bounded by MAX_CONSUMERS; // If no consumers, does nothing. - for (uint256 i = 0; i < subConfig.consumers.length; i++) { - delete s_consumers[subConfig.consumers[i]][subId]; + uint256 consumersLength = consumers.length; + for (uint256 i = 0; i < consumersLength; ++i) { + delete s_consumers[consumers[i]][subId]; } delete s_subscriptionConfigs[subId]; delete s_subscriptions[subId]; s_subIds.remove(subId); - s_totalBalance -= balance; - s_totalNativeBalance -= nativeBalance; + if (balance != 0) { + s_totalBalance -= balance; + } + if (nativeBalance != 0) { + s_totalNativeBalance -= nativeBalance; + } return (balance, nativeBalance); } diff --git a/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol b/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol index c21634bc61d..4bd7c1bd20c 100644 --- a/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol +++ b/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol @@ -122,12 +122,13 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { revert NoSuchProvingKey(kh); } delete s_provingKeys[kh]; - for (uint256 i = 0; i < s_provingKeyHashes.length; i++) { + uint256 s_provingKeyHashesLength = s_provingKeyHashes.length; + for (uint256 i = 0; i < s_provingKeyHashesLength; ++i) { if (s_provingKeyHashes[i] == kh) { - bytes32 last = s_provingKeyHashes[s_provingKeyHashes.length - 1]; // Copy last element and overwrite kh to be deleted with it - s_provingKeyHashes[i] = last; + s_provingKeyHashes[i] = s_provingKeyHashes[s_provingKeyHashesLength - 1]; s_provingKeyHashes.pop(); + break; } } emit ProvingKeyDeregistered(kh, key.maxGas); @@ -241,17 +242,19 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { */ function requestRandomWords( VRFV2PlusClient.RandomWordsRequest calldata req - ) external override nonReentrant returns (uint256) { + ) external override nonReentrant returns (uint256 requestId) { // Input validation using the subscription storage. - if (s_subscriptionConfigs[req.subId].owner == address(0)) { + uint256 subId = req.subId; + if (s_subscriptionConfigs[subId].owner == address(0)) { revert InvalidSubscription(); } // Its important to ensure that the consumer is in fact who they say they // are, otherwise they could use someone else's subscription balance. // A nonce of 0 indicates consumer is not allocated to the sub. - uint64 currentNonce = s_consumers[msg.sender][req.subId]; - if (currentNonce == 0) { - revert InvalidConsumer(req.subId, msg.sender); + mapping(uint256 => uint64) storage nonces = s_consumers[msg.sender]; + uint64 nonce = nonces[subId]; + if (nonce == 0) { + revert InvalidConsumer(subId, msg.sender); } // Input validation using the config storage word. if ( @@ -273,19 +276,20 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { if (req.numWords > MAX_NUM_WORDS) { revert NumWordsTooBig(req.numWords, MAX_NUM_WORDS); } + // Note we do not check whether the keyHash is valid to save gas. // The consequence for users is that they can send requests // for invalid keyHashes which will simply not be fulfilled. - uint64 nonce = currentNonce + 1; - (uint256 requestId, uint256 preSeed) = _computeRequestId(req.keyHash, msg.sender, req.subId, nonce); + ++nonce; + uint256 preSeed; + (requestId, preSeed) = _computeRequestId(req.keyHash, msg.sender, subId, nonce); - VRFV2PlusClient.ExtraArgsV1 memory extraArgs = _fromBytes(req.extraArgs); - bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(extraArgs); + bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(_fromBytes(req.extraArgs)); s_requestCommitments[requestId] = keccak256( abi.encode( requestId, ChainSpecificUtil._getBlockNumber(), - req.subId, + subId, req.callbackGasLimit, req.numWords, msg.sender, @@ -296,14 +300,14 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { req.keyHash, requestId, preSeed, - req.subId, + subId, req.requestConfirmations, req.callbackGasLimit, req.numWords, extraArgsBytes, msg.sender ); - s_consumers[msg.sender][req.subId] = nonce; + nonces[subId] = nonce; return requestId; } @@ -437,54 +441,63 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { Proof memory proof, RequestCommitment memory rc, bool onlyPremium - ) external nonReentrant returns (uint96) { + ) external nonReentrant returns (uint96 payment) { uint256 startGas = gasleft(); Output memory output = _getRandomnessFromProof(proof, rc); uint256 gasPrice = _getValidatedGasPrice(onlyPremium, output.provingKey.maxGas); - uint256[] memory randomWords = new uint256[](rc.numWords); - for (uint256 i = 0; i < rc.numWords; i++) { - randomWords[i] = uint256(keccak256(abi.encode(output.randomness, i))); + uint256[] memory randomWords; + uint256 randomness = output.randomness; + // stack too deep error + { + uint256 numWords = rc.numWords; + randomWords = new uint256[](numWords); + for (uint256 i = 0; i < numWords; ++i) { + randomWords[i] = uint256(keccak256(abi.encode(randomness, i))); + } } - delete s_requestCommitments[output.requestId]; - bool success = _deliverRandomness(output.requestId, rc, randomWords); + uint256 requestId = output.requestId; + delete s_requestCommitments[requestId]; + bool success = _deliverRandomness(requestId, rc, randomWords); // Increment the req count for the subscription. + uint256 subId = rc.subId; + ++s_subscriptions[subId].reqCount; + // stack too deep error { - s_subscriptions[rc.subId].reqCount = s_subscriptions[rc.subId].reqCount + 1; - } - - bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; + bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; - // We want to charge users exactly for how much gas they use in their callback. - // The gasAfterPaymentCalculation is meant to cover these additional operations where we - // decrement the subscription balance and increment the oracles withdrawable balance. - uint96 payment = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium); + // We want to charge users exactly for how much gas they use in their callback. + // The gasAfterPaymentCalculation is meant to cover these additional operations where we + // decrement the subscription balance and increment the oracles withdrawable balance. + payment = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium); - _chargePayment(payment, nativePayment, rc.subId); + _chargePayment(payment, nativePayment, subId); + } // Include payment in the event for tracking costs. - emit RandomWordsFulfilled(output.requestId, output.randomness, rc.subId, payment, success, onlyPremium); + emit RandomWordsFulfilled(requestId, randomness, subId, payment, success, onlyPremium); return payment; } function _chargePayment(uint96 payment, bool nativePayment, uint256 subId) internal { + Subscription storage subcription = s_subscriptions[subId]; if (nativePayment) { - uint96 prevBal = s_subscriptions[subId].nativeBalance; + uint96 prevBal = subcription.nativeBalance; if (prevBal < payment) { revert InsufficientBalance(); } - s_subscriptions[subId].nativeBalance = prevBal - payment; + subcription.nativeBalance = prevBal - payment; s_withdrawableNative += payment; } else { - uint96 prevBal = s_subscriptions[subId].balance; + uint96 prevBal = subcription.balance; if (prevBal < payment) { revert InsufficientBalance(); } - s_subscriptions[subId].balance = prevBal - payment; + subcription.balance = prevBal - payment; s_withdrawableTokens += payment; } } @@ -552,14 +565,12 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { return uint96(payment); } - function _getFeedData() private view returns (int256) { + function _getFeedData() private view returns (int256 weiPerUnitLink) { uint32 stalenessSeconds = s_config.stalenessSeconds; - bool staleFallback = stalenessSeconds > 0; uint256 timestamp; - int256 weiPerUnitLink; (, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData(); // solhint-disable-next-line not-rely-on-time - if (staleFallback && stalenessSeconds < block.timestamp - timestamp) { + if (stalenessSeconds > 0 && stalenessSeconds < block.timestamp - timestamp) { weiPerUnitLink = s_fallbackWeiPerUnitLink; } return weiPerUnitLink; @@ -569,15 +580,16 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { * @inheritdoc IVRFSubscriptionV2Plus */ function pendingRequestExists(uint256 subId) public view override returns (bool) { - SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; - for (uint256 i = 0; i < subConfig.consumers.length; i++) { - for (uint256 j = 0; j < s_provingKeyHashes.length; j++) { - (uint256 reqId, ) = _computeRequestId( - s_provingKeyHashes[j], - subConfig.consumers[i], - subId, - s_consumers[subConfig.consumers[i]][subId] - ); + address[] storage consumers = s_subscriptionConfigs[subId].consumers; + uint256 consumersLength = consumers.length; + if (consumersLength == 0) { + return false; + } + uint256 provingKeyHashesLength = s_provingKeyHashes.length; + for (uint256 i = 0; i < consumersLength; ++i) { + address consumer = consumers[i]; + for (uint256 j = 0; j < provingKeyHashesLength; ++j) { + (uint256 reqId, ) = _computeRequestId(s_provingKeyHashes[j], consumer, subId, s_consumers[consumer][subId]); if (s_requestCommitments[reqId] != 0) { return true; } @@ -599,7 +611,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { // Note bounded by MAX_CONSUMERS address[] memory consumers = s_subscriptionConfigs[subId].consumers; uint256 lastConsumerIndex = consumers.length - 1; - for (uint256 i = 0; i < consumers.length; i++) { + for (uint256 i = 0; i < consumers.length; ++i) { if (consumers[i] == consumer) { address last = consumers[lastConsumerIndex]; // Storage write to preserve last element @@ -657,7 +669,8 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { } function _isTargetRegistered(address target) internal view returns (bool) { - for (uint256 i = 0; i < s_migrationTargets.length; i++) { + uint256 migrationTargetsLength = s_migrationTargets.length; + for (uint256 i = 0; i < migrationTargetsLength; ++i) { if (s_migrationTargets[i] == target) { return true; } @@ -675,10 +688,9 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { function deregisterMigratableCoordinator(address target) external onlyOwner { uint256 nTargets = s_migrationTargets.length; - for (uint256 i = 0; i < nTargets; i++) { + for (uint256 i = 0; i < nTargets; ++i) { if (s_migrationTargets[i] == target) { s_migrationTargets[i] = s_migrationTargets[nTargets - 1]; - s_migrationTargets[nTargets - 1] = target; s_migrationTargets.pop(); emit CoordinatorDeregistered(target); return; @@ -718,7 +730,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { // despite the fact that we follow best practices this is still probably safest // to prevent any re-entrancy possibilities. s_config.reentrancyLock = true; - for (uint256 i = 0; i < consumers.length; i++) { + for (uint256 i = 0; i < consumers.length; ++i) { IVRFMigratableConsumerV2Plus(consumers[i]).setCoordinator(newCoordinator); } s_config.reentrancyLock = false; diff --git a/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go b/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go index 275233808d4..6a53141253b 100644 --- a/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go +++ b/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go @@ -61,8 +61,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } var VRFCoordinatorV25MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"want\",\"type\":\"uint256\"}],\"name\":\"InsufficientGasForConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2_5.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200602138038062006021833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615e46620001db6000396000818161055001526133cc0152615e466000f3fe60806040526004361061021c5760003560e01c80638402595e11610124578063b2a7cac5116100a6578063b2a7cac514610732578063bec4c08c14610752578063caf70c4a14610772578063cb63179714610792578063d98e620e146107b2578063da2f2610146107d2578063dac83d2914610831578063dc311dd314610851578063e72f6e3014610882578063ee9d2d38146108a2578063f2fde38b146108cf57600080fd5b80638402595e146105c757806386fe91c7146105e75780638da5cb5b1461060757806395b55cfc146106255780639b1c385e146106385780639d40a6fd14610658578063a21a23e414610690578063a4c0ed36146106a5578063a63e0bfb146106c5578063aa433aff146106e5578063aefb212f1461070557600080fd5b8063405b84fa116101ad578063405b84fa1461044e57806340d6bb821461046e57806341af6c871461049957806351cff8d9146104c95780635d06b4ab146104e957806364d51a2a14610509578063659827441461051e578063689c45171461053e57806372e9d5651461057257806379ba5097146105925780637a5a2aef146105a757600080fd5b806304104edb14610221578063043bd6ae14610243578063088070f51461026c57806308821d581461033a5780630ae095401461035a57806315c48b841461037a57806318e3dd27146103a25780631b6b6d23146103e15780632f622e6b1461040e578063301f42e91461042e575b600080fd5b34801561022d57600080fd5b5061024161023c36600461520c565b6108ef565b005b34801561024f57600080fd5b5061025960105481565b6040519081526020015b60405180910390f35b34801561027857600080fd5b50600c546102dd9061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610263565b34801561034657600080fd5b506102416103553660046152ea565b610aa5565b34801561036657600080fd5b506102416103753660046155d4565b610c48565b34801561038657600080fd5b5061038f60c881565b60405161ffff9091168152602001610263565b3480156103ae57600080fd5b50600a546103c990600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610263565b3480156103ed57600080fd5b50600254610401906001600160a01b031681565b604051610263919061580b565b34801561041a57600080fd5b5061024161042936600461520c565b610c90565b34801561043a57600080fd5b506103c96104493660046153f0565b610ddc565b34801561045a57600080fd5b506102416104693660046155d4565b611032565b34801561047a57600080fd5b506104846101f481565b60405163ffffffff9091168152602001610263565b3480156104a557600080fd5b506104b96104b4366004615373565b6113e6565b6040519015158152602001610263565b3480156104d557600080fd5b506102416104e436600461520c565b611587565b3480156104f557600080fd5b5061024161050436600461520c565b611715565b34801561051557600080fd5b5061038f606481565b34801561052a57600080fd5b50610241610539366004615229565b6117cc565b34801561054a57600080fd5b506104017f000000000000000000000000000000000000000000000000000000000000000081565b34801561057e57600080fd5b50600354610401906001600160a01b031681565b34801561059e57600080fd5b5061024161182c565b3480156105b357600080fd5b506102416105c2366004615306565b6118d6565b3480156105d357600080fd5b506102416105e236600461520c565b611a06565b3480156105f357600080fd5b50600a546103c9906001600160601b031681565b34801561061357600080fd5b506000546001600160a01b0316610401565b610241610633366004615373565b611b18565b34801561064457600080fd5b506102596106533660046154de565b611c3c565b34801561066457600080fd5b50600754610678906001600160401b031681565b6040516001600160401b039091168152602001610263565b34801561069c57600080fd5b50610259611faa565b3480156106b157600080fd5b506102416106c0366004615262565b6121d4565b3480156106d157600080fd5b506102416106e0366004615533565b612350565b3480156106f157600080fd5b50610241610700366004615373565b6125cd565b34801561071157600080fd5b506107256107203660046155f9565b61262d565b6040516102639190615882565b34801561073e57600080fd5b5061024161074d366004615373565b612730565b34801561075e57600080fd5b5061024161076d3660046155d4565b612831565b34801561077e57600080fd5b5061025961078d36600461533a565b61294b565b34801561079e57600080fd5b506102416107ad3660046155d4565b61297b565b3480156107be57600080fd5b506102596107cd366004615373565b612bfb565b3480156107de57600080fd5b506108126107ed366004615373565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b03909116602083015201610263565b34801561083d57600080fd5b5061024161084c3660046155d4565b612c1c565b34801561085d57600080fd5b5061087161086c366004615373565b612cb0565b604051610263959493929190615a57565b34801561088e57600080fd5b5061024161089d36600461520c565b612dab565b3480156108ae57600080fd5b506102596108bd366004615373565b600f6020526000908152604090205481565b3480156108db57600080fd5b506102416108ea36600461520c565b612f8c565b6108f7612f9d565b60115460005b81811015610a7d57826001600160a01b03166011828154811061092257610922615da2565b6000918252602090912001546001600160a01b03161415610a6b57601161094a600184615c52565b8154811061095a5761095a615da2565b600091825260209091200154601180546001600160a01b03909216918390811061098657610986615da2565b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790558260116109bd600185615c52565b815481106109cd576109cd615da2565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506011805480610a0c57610a0c615d8c565b600082815260209020810160001990810180546001600160a01b03191690550190556040517ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3790610a5e90859061580b565b60405180910390a1505050565b80610a7581615d0a565b9150506108fd565b5081604051635428d44960e01b8152600401610a99919061580b565b60405180910390fd5b50565b610aad612f9d565b604080518082018252600091610adc91908490600290839083908082843760009201919091525061294b915050565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b03169183019190915291925090610b3a57604051631dfd6e1360e21b815260048101839052602401610a99565b6000828152600d6020526040812080546001600160481b03191690555b600e54811015610c125782600e8281548110610b7557610b75615da2565b90600052602060002001541415610c0057600e805460009190610b9a90600190615c52565b81548110610baa57610baa615da2565b9060005260206000200154905080600e8381548110610bcb57610bcb615da2565b600091825260209091200155600e805480610be857610be8615d8c565b60019003818190600052602060002001600090559055505b80610c0a81615d0a565b915050610b57565b507f9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5828260200151604051610a5e929190615895565b81610c5281612ff2565b610c5a613053565b610c63836113e6565b15610c8157604051631685ecdd60e31b815260040160405180910390fd5b610c8b838361307e565b505050565b610c98613053565b610ca0612f9d565b600b54600160601b90046001600160601b0316610cd057604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c610cf38380615c8e565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610d3b9190615c8e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610db5576040519150601f19603f3d011682016040523d82523d6000602084013e610dba565b606091505b5050905080610c8b5760405163950b247960e01b815260040160405180910390fd5b6000610de6613053565b60005a90506000610df78686613232565b90506000610e0d858360000151602001516134ee565b90506000866060015163ffffffff166001600160401b03811115610e3357610e33615db8565b604051908082528060200260200182016040528015610e5c578160200160208202803683370190505b50905060005b876060015163ffffffff16811015610edc57836040015181604051602001610e94929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c828281518110610ebf57610ebf615da2565b602090810291909101015280610ed481615d0a565b915050610e62565b50602080840180516000908152600f9092526040822082905551610f0190898461353c565b602089810151600090815260069091526040902054909150610f3490600160c01b90046001600160401b03166001615bb6565b6020808a0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08901518051610f8190600190615c52565b81518110610f9157610f91615da2565b60209101015160f81c60011490506000610fad8786848c6135d7565b9050610fbe81838c60200151613607565b6020808b0151878201516040808a015181519081526001600160601b03861694810194909452861515908401528b1515606084015290917f6c6b5394380e16e41988d8383648010de6f5c2e4814803be5de1c6b1c852db559060800160405180910390a396505050505050505b9392505050565b61103a613053565b61104381613758565b6110625780604051635428d44960e01b8152600401610a99919061580b565b60008060008061107186612cb0565b945094505093509350336001600160a01b0316826001600160a01b0316146110d45760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610a99565b6110dd866113e6565b156111235760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610a99565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a083015291519091600091611178918491016158bf565b6040516020818303038152906040529050611192886137c2565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906111cb9085906004016158ac565b6000604051808303818588803b1580156111e457600080fd5b505af11580156111f8573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611221905057506001600160601b03861615155b156112eb5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611258908a908a90600401615852565b602060405180830381600087803b15801561127257600080fd5b505af1158015611286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112aa9190615356565b6112eb5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a99565b600c805460ff60301b1916600160301b17905560005b83518110156113945783818151811061131c5761131c615da2565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b815260040161134f919061580b565b600060405180830381600087803b15801561136957600080fd5b505af115801561137d573d6000803e3d6000fd5b50505050808061138c90615d0a565b915050611301565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906113d49089908b9061581f565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561147057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611452575b505050505081525050905060005b81604001515181101561157d5760005b600e5481101561156a576000611533600e83815481106114b0576114b0615da2565b9060005260206000200154856040015185815181106114d1576114d1615da2565b60200260200101518860046000896040015189815181106114f4576114f4615da2565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d82529092529020546001600160401b0316613a10565b506000818152600f6020526040902054909150156115575750600195945050505050565b508061156281615d0a565b91505061148e565b508061157581615d0a565b91505061147e565b5060009392505050565b61158f613053565b611597612f9d565b6002546001600160a01b03166115c05760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166115e957604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006116058380615c8e565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b031661164d9190615c8e565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906116a29085908590600401615852565b602060405180830381600087803b1580156116bc57600080fd5b505af11580156116d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f49190615356565b61171157604051631e9acf1760e31b815260040160405180910390fd5b5050565b61171d612f9d565b61172681613758565b15611746578060405163ac8a27ef60e01b8152600401610a99919061580b565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625906117c190839061580b565b60405180910390a150565b6117d4612f9d565b6002546001600160a01b0316156117fe57604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b0316331461187f5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610a99565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6118de612f9d565b60408051808201825260009161190d91908590600290839083908082843760009201919091525061294b915050565b6000818152600d602052604090205490915060ff161561194357604051634a0b8fa760e01b815260048101829052602401610a99565b60408051808201825260018082526001600160401b0385811660208085019182526000878152600d9091528581209451855492516001600160481b031990931690151568ffffffffffffffff00191617610100929093169190910291909117909255600e805491820181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01829055517f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd390610a5e9083908590615895565b611a0e612f9d565b600a544790600160601b90046001600160601b031681811115611a4e576040516354ced18160e11b81526004810182905260248101839052604401610a99565b81811015610c8b576000611a628284615c52565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114611ab1576040519150601f19603f3d011682016040523d82523d6000602084013e611ab6565b606091505b5050905080611ad85760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611b0992919061581f565b60405180910390a15050505050565b611b20613053565b6000818152600560205260409020546001600160a01b0316611b5557604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611b848385615bfd565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611bcc9190615bfd565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611c1f9190615b9e565b604080519283526020830191909152015b60405180910390a25050565b6000611c46613053565b6020808301356000908152600590915260409020546001600160a01b0316611c8157604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611cce578260200135336040516379bfd40160e01b8152600401610a99929190615934565b600c5461ffff16611ce56060850160408601615518565b61ffff161080611d08575060c8611d026060850160408601615518565b61ffff16115b15611d4e57611d1d6060840160408501615518565b600c5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610a99565b600c5462010000900463ffffffff16611d6d608085016060860161561b565b63ffffffff161115611dbd57611d89608084016060850161561b565b600c54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610a99565b6101f4611dd060a085016080860161561b565b63ffffffff161115611e1657611dec60a084016080850161561b565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610a99565b6000611e23826001615bb6565b9050600080611e39863533602089013586613a10565b90925090506000611e55611e5060a0890189615aac565b613a89565b90506000611e6282613b06565b905083611e6d613b77565b60208a0135611e8260808c0160608d0161561b565b611e9260a08d0160808e0161561b565b3386604051602001611eaa97969594939291906159b7565b60405160208183030381529060405280519060200120600f600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611f219190615518565b8e6060016020810190611f34919061561b565b8f6080016020810190611f47919061561b565b89604051611f5a96959493929190615978565b60405180910390a45050336000908152600460209081526040808320898301358452909152902080546001600160401b0319166001600160401b039490941693909317909255925050505b919050565b6000611fb4613053565b600033611fc2600143615c52565b600754604051606093841b6001600160601b03199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b0390911690600061203c83615d25565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b0381111561207b5761207b615db8565b6040519080825280602002602001820160405280156120a4578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b0392831617835592516001830180549094169116179091559251805194955090936121859260028501920190614f26565b5061219591506008905083613c07565b50817f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d336040516121c6919061580b565b60405180910390a250905090565b6121dc613053565b6002546001600160a01b03163314612207576040516344b0e3c360e01b815260040160405180910390fd5b6020811461222857604051638129bbcd60e01b815260040160405180910390fd5b600061223682840184615373565b6000818152600560205260409020549091506001600160a01b031661226e57604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906122958385615bfd565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166122dd9190615bfd565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846123309190615b9e565b6040805192835260208301919091520160405180910390a2505050505050565b612358612f9d565b60c861ffff8a1611156123925760405163539c34bb60e11b815261ffff8a1660048201819052602482015260c86044820152606401610a99565b600085136123b6576040516321ea67b360e11b815260048101869052602401610a99565b60008463ffffffff161180156123d857508363ffffffff168363ffffffff1610155b15612406576040516313c06e5960e11b815263ffffffff808516600483015285166024820152604401610a99565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b9099029890981667ffffffffffffffff60781b19600160581b90960263ffffffff60581b19600160381b9098029790971668ffffffffffffffffff60301b196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b6906125ba908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b6125d5612f9d565b6000818152600560205260409020546001600160a01b031661260a57604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610aa29082906001600160a01b031661307e565b6060600061263b6008613c13565b905080841061265d57604051631390f2a160e01b815260040160405180910390fd5b60006126698486615b9e565b905081811180612677575083155b6126815780612683565b815b905060006126918683615c52565b6001600160401b038111156126a8576126a8615db8565b6040519080825280602002602001820160405280156126d1578160200160208202803683370190505b50905060005b8151811015612724576126f56126ed8883615b9e565b600890613c1d565b82828151811061270757612707615da2565b60209081029190910101528061271c81615d0a565b9150506126d7565b50925050505b92915050565b612738613053565b6000818152600560205260409020546001600160a01b031661276d57604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b031633146127c4576000818152600560205260409081902060010154905163d084e97560e01b8152610a99916001600160a01b03169060040161580b565b6000818152600560205260409081902080546001600160a01b031980821633908117845560019093018054909116905591516001600160a01b039092169183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611c30918591615838565b8161283b81612ff2565b612843613053565b60008381526005602052604090206002015460641415612876576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b0316156128ad57505050565b6001600160a01b0382166000818152600460209081526040808320878452825280832080546001600160401b031916600190811790915560058352818420600201805491820181558452919092200180546001600160a01b0319169092179091555183907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061293e90859061580b565b60405180910390a2505050565b60008160405160200161295e9190615874565b604051602081830303815290604052805190602001209050919050565b8161298581612ff2565b61298d613053565b612996836113e6565b156129b457604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b0316612a025782826040516379bfd40160e01b8152600401610a99929190615934565b600083815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612a6557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a47575b50505050509050600060018251612a7c9190615c52565b905060005b8251811015612b8857846001600160a01b0316838281518110612aa657612aa6615da2565b60200260200101516001600160a01b03161415612b76576000838381518110612ad157612ad1615da2565b6020026020010151905080600560008981526020019081526020016000206002018381548110612b0357612b03615da2565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255888152600590915260409020600201805480612b4e57612b4e615d8c565b600082815260209020810160001990810180546001600160a01b031916905501905550612b88565b80612b8081615d0a565b915050612a81565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160401b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a790612bec90879061580b565b60405180910390a25050505050565b600e8181548110612c0b57600080fd5b600091825260209091200154905081565b81612c2681612ff2565b612c2e613053565b6000838152600560205260409020600101546001600160a01b03838116911614610c8b576000838152600560205260409081902060010180546001600160a01b0319166001600160a01b0385161790555183907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19061293e9033908690615838565b6000818152600560205260408120548190819081906060906001600160a01b0316612cee57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b0390941693918391830182828015612d9157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d73575b505050505090509450945094509450945091939590929450565b612db3612f9d565b6002546001600160a01b0316612ddc5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612e0d90309060040161580b565b60206040518083038186803b158015612e2557600080fd5b505afa158015612e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e5d919061538c565b600a549091506001600160601b031681811115612e97576040516354ced18160e11b81526004810182905260248101839052604401610a99565b81811015610c8b576000612eab8284615c52565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612ede908790859060040161581f565b602060405180830381600087803b158015612ef857600080fd5b505af1158015612f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f309190615356565b612f4d57604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366008482604051612f7e92919061581f565b60405180910390a150505050565b612f94612f9d565b610aa281613c29565b6000546001600160a01b03163314612ff05760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610a99565b565b6000818152600560205260409020546001600160a01b03168061302857604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146117115780604051636c51fda960e11b8152600401610a99919061580b565b600c54600160301b900460ff1615612ff05760405163769dd35360e11b815260040160405180910390fd5b60008061308a846137c2565b60025491935091506001600160a01b0316158015906130b157506001600160601b03821615155b156131605760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906130f19086906001600160601b0387169060040161581f565b602060405180830381600087803b15801561310b57600080fd5b505af115801561311f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131439190615356565b61316057604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d80600081146131b6576040519150601f19603f3d011682016040523d82523d6000602084013e6131bb565b606091505b50509050806131dd5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c490606001612bec565b6040805160a0810182526000606082018181526080830182905282526020820181905291810191909152600061326b846000015161294b565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b031691830191909152919250906132c957604051631dfd6e1360e21b815260048101839052602401610a99565b60008286608001516040516020016132eb929190918252602082015260400190565b60408051601f1981840301815291815281516020928301206000818152600f9093529120549091508061333157604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613360978a979096959101615a03565b6040516020818303038152906040528051906020012081146133955760405163354a450b60e21b815260040160405180910390fd5b60006133a48760000151613ccd565b90508061347c578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561341657600080fd5b505afa15801561342a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344e919061538c565b90508061347c57865160405163175dadad60e01b81526001600160401b039091166004820152602401610a99565b600088608001518260405160200161349e929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006134c58a83613daf565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a111561353457821561351757506001600160401b03811661272a565b3a8260405163435e532d60e11b8152600401610a99929190615895565b503a92915050565b6000806000631fe543e360e01b868560405160240161355c92919061595f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559086015160808701519192506135c09163ffffffff9091169083613e1a565b600c805460ff60301b191690559695505050505050565b600082156135f1576135ea858584613e66565b90506135ff565b6135fc858584613f77565b90505b949350505050565b81156136d4576000818152600660205260409020546001600160601b03600160601b909104811690841681101561365157604051631e9acf1760e31b815260040160405180910390fd5b61365b8482615c8e565b60008381526006602052604090208054600160601b600160c01b031916600160601b6001600160601b03938416810291909117909155600b805487939192600c926136aa928692900416615bfd565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050505050565b6000818152600660205260409020546001600160601b0390811690841681101561371157604051631e9acf1760e31b815260040160405180910390fd5b61371b8482615c8e565b600083815260066020526040812080546001600160601b0319166001600160601b03938416179055600b805487939192916136aa91859116615bfd565b6000805b6011548110156137b957826001600160a01b03166011828154811061378357613783615da2565b6000918252602090912001546001600160a01b031614156137a75750600192915050565b806137b181615d0a565b91505061375c565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796879694959486019391929083018282801561384e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613830575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b82604001515181101561392a5760046000846040015183815181106138da576138da615da2565b6020908102919091018101516001600160a01b031682528181019290925260409081016000908120898252909252902080546001600160401b03191690558061392281615d0a565b9150506138b3565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906139626002830182614f8b565b505060008581526006602052604081205561397e600886614160565b50600a805485919060009061399d9084906001600160601b0316615c8e565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b03166139e59190615c8e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b6040805160208082018790526001600160a01b03959095168183015260608101939093526001600160401b03919091166080808401919091528151808403909101815260a08301825280519084012060c083019490945260e0808301859052815180840390910181526101009092019052805191012091565b60408051602081019091526000815281613ab2575060408051602081019091526000815261272a565b63125fa26760e31b613ac48385615cae565b6001600160e01b03191614613aec57604051632923fee760e11b815260040160405180910390fd5b613af98260048186615b74565b81019061102b91906153a5565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613b3f91511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613b838161416c565b15613c005760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613bc257600080fd5b505afa158015613bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bfa919061538c565b91505090565b4391505090565b600061102b838361418f565b600061272a825490565b600061102b83836141de565b6001600160a01b038116331415613c7c5760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610a99565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613cd98161416c565b15613da057610100836001600160401b0316613cf3613b77565b613cfd9190615c52565b1180613d195750613d0c613b77565b836001600160401b031610155b15613d275750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a82906024015b60206040518083038186803b158015613d6857600080fd5b505afa158015613d7c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102b919061538c565b50506001600160401b03164090565b6000613de38360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614208565b60038360200151604051602001613dfb92919061594b565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613e2c57600080fd5b611388810390508460408204820311613e4457600080fd5b50823b613e5057600080fd5b60008083516020850160008789f1949350505050565b600080613ea96000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061442492505050565b905060005a600c54613ec9908890600160581b900463ffffffff16615b9e565b613ed39190615c52565b613edd9086615c33565b600c54909150600090613f0290600160781b900463ffffffff1664e8d4a51000615c33565b90508415613f4e57600c548190606490600160b81b900460ff16613f268587615b9e565b613f309190615c33565b613f3a9190615c1f565b613f449190615b9e565b935050505061102b565b600c548190606490613f6a90600160b81b900460ff1682615bd8565b60ff16613f268587615b9e565b600080613f826144e9565b905060008113613fa8576040516321ea67b360e11b815260048101829052602401610a99565b6000613fea6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061442492505050565b9050600082825a600c5461400c908b90600160581b900463ffffffff16615b9e565b6140169190615c52565b6140209089615c33565b61402a9190615b9e565b61403c90670de0b6b3a7640000615c33565b6140469190615c1f565b600c5490915060009061406f9063ffffffff600160981b8204811691600160781b900416615c69565b6140849063ffffffff1664e8d4a51000615c33565b905060008461409b83670de0b6b3a7640000615c33565b6140a59190615c1f565b9050600087156140e657600c5482906064906140cb90600160c01b900460ff1687615c33565b6140d59190615c1f565b6140df9190615b9e565b9050614126565b600c54829060649061410290600160c01b900460ff1682615bd8565b61410f9060ff1687615c33565b6141199190615c1f565b6141239190615b9e565b90505b6b033b2e3c9fd0803ce80000008111156141535760405163e80fa38160e01b815260040160405180910390fd5b9998505050505050505050565b600061102b83836145b4565b600061a4b1821480614180575062066eed82145b8061272a57505062066eee1490565b60008181526001830160205260408120546141d65750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561272a565b50600061272a565b60008260000182815481106141f5576141f5615da2565b9060005260206000200154905092915050565b614211896146a7565b61425a5760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610a99565b614263886146a7565b6142a75760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610a99565b6142b0836146a7565b6142fc5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610a99565b614305826146a7565b6143515760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610a99565b61435d878a888761476a565b6143a55760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610a99565b60006143b18a8761488d565b905060006143c4898b878b8689896148f1565b905060006143d5838d8d8a86614a10565b9050808a146144165760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610a99565b505050505050505050505050565b6000466144308161416c565b1561446f57606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d6857600080fd5b61447881614a50565b156137b957600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615df2604891396040516020016144be929190615761565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613d5091906158ac565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561454757600080fd5b505afa15801561455b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061457f9190615636565b5094509092508491505080156145a3575061459a8242615c52565b8463ffffffff16105b156135ff5750601054949350505050565b6000818152600183016020526040812054801561469d5760006145d8600183615c52565b85549091506000906145ec90600190615c52565b905081811461465157600086600001828154811061460c5761460c615da2565b906000526020600020015490508087600001848154811061462f5761462f615da2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061466257614662615d8c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061272a565b600091505061272a565b80516000906401000003d019116146f55760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610a99565b60208201516401000003d019116147435760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610a99565b60208201516401000003d0199080096147638360005b6020020151614a8a565b1492915050565b60006001600160a01b0382166147b05760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610a99565b6020840151600090600116156147c757601c6147ca565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614865573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614895614fa9565b6148c2600184846040516020016148ae939291906157ea565b604051602081830303815290604052614aae565b90505b6148ce816146a7565b61272a5780516040805160208101929092526148ea91016148ae565b90506148c5565b6148f9614fa9565b825186516401000003d01990819006910614156149585760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610a99565b614963878988614afc565b6149a85760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610a99565b6149b3848685614afc565b6149f95760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610a99565b614a04868484614c24565b98975050505050505050565b600060028686868587604051602001614a2e96959493929190615790565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a821480614a6257506101a482145b80614a6f575062aa37dc82145b80614a7b575061210582145b8061272a57505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614ab6614fa9565b614abf82614ce7565b8152614ad4614acf826000614759565b614d22565b602082018190526002900660011415611fa5576020810180516401000003d019039052919050565b600082614b395760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610a99565b83516020850151600090614b4f90600290615d4c565b15614b5b57601c614b5e565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614bd0573d6000803e3d6000fd5b505050602060405103519050600086604051602001614bef919061574f565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614c2c614fa9565b835160208086015185519186015160009384938493614c4d93909190614d42565b919450925090506401000003d019858209600114614ca95760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610a99565b60405180604001604052806401000003d01980614cc857614cc8615d76565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611fa557604080516020808201939093528151808203840181529082019091528051910120614cef565b600061272a826002614d3b6401000003d0196001615b9e565b901c614e22565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614d8283838585614eb9565b9098509050614d9388828e88614edd565b9098509050614da488828c87614edd565b90985090506000614db78d878b85614edd565b9098509050614dc888828686614eb9565b9098509050614dd988828e89614edd565b9098509050818114614e0e576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614e12565b8196505b5050505050509450945094915050565b600080614e2d614fc7565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614e5f614fe5565b60208160c0846005600019fa925082614eaf5760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610a99565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614f7b579160200282015b82811115614f7b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614f46565b50614f87929150615003565b5090565b5080546000825590600052602060002090810190610aa29190615003565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614f875760008155600101615004565b8035611fa581615dce565b806040810183101561272a57600080fd5b600082601f83011261504557600080fd5b604051604081018181106001600160401b038211171561506757615067615db8565b806040525080838560408601111561507e57600080fd5b60005b60028110156150a0578135835260209283019290910190600101615081565b509195945050505050565b8035611fa581615de3565b600060c082840312156150c857600080fd5b6150d0615af9565b90506150db826151ca565b8152602080830135818301526150f3604084016151b6565b6040830152615104606084016151b6565b6060830152608083013561511781615dce565b608083015260a08301356001600160401b038082111561513657600080fd5b818501915085601f83011261514a57600080fd5b81358181111561515c5761515c615db8565b61516e601f8201601f19168501615b44565b9150808252868482850101111561518457600080fd5b80848401858401376000848284010152508060a085015250505092915050565b803561ffff81168114611fa557600080fd5b803563ffffffff81168114611fa557600080fd5b80356001600160401b0381168114611fa557600080fd5b803560ff81168114611fa557600080fd5b805169ffffffffffffffffffff81168114611fa557600080fd5b60006020828403121561521e57600080fd5b813561102b81615dce565b6000806040838503121561523c57600080fd5b823561524781615dce565b9150602083013561525781615dce565b809150509250929050565b6000806000806060858703121561527857600080fd5b843561528381615dce565b93506020850135925060408501356001600160401b03808211156152a657600080fd5b818701915087601f8301126152ba57600080fd5b8135818111156152c957600080fd5b8860208285010111156152db57600080fd5b95989497505060200194505050565b6000604082840312156152fc57600080fd5b61102b8383615023565b6000806060838503121561531957600080fd5b6153238484615023565b9150615331604084016151ca565b90509250929050565b60006040828403121561534c57600080fd5b61102b8383615034565b60006020828403121561536857600080fd5b815161102b81615de3565b60006020828403121561538557600080fd5b5035919050565b60006020828403121561539e57600080fd5b5051919050565b6000602082840312156153b757600080fd5b604051602081018181106001600160401b03821117156153d9576153d9615db8565b60405282356153e781615de3565b81529392505050565b60008060008385036101e081121561540757600080fd5b6101a08082121561541757600080fd5b61541f615b21565b915061542b8787615034565b825261543a8760408801615034565b60208301526080860135604083015260a0860135606083015260c0860135608083015261546960e08701615018565b60a083015261010061547d88828901615034565b60c0840152615490886101408901615034565b60e0840152610180870135908301529093508401356001600160401b038111156154b957600080fd5b6154c5868287016150b6565b9250506154d56101c085016150ab565b90509250925092565b6000602082840312156154f057600080fd5b81356001600160401b0381111561550657600080fd5b820160c0818503121561102b57600080fd5b60006020828403121561552a57600080fd5b61102b826151a4565b60008060008060008060008060006101208a8c03121561555257600080fd5b61555b8a6151a4565b985061556960208b016151b6565b975061557760408b016151b6565b965061558560608b016151b6565b955060808a0135945061559a60a08b016151b6565b93506155a860c08b016151b6565b92506155b660e08b016151e1565b91506155c56101008b016151e1565b90509295985092959850929598565b600080604083850312156155e757600080fd5b82359150602083013561525781615dce565b6000806040838503121561560c57600080fd5b50508035926020909101359150565b60006020828403121561562d57600080fd5b61102b826151b6565b600080600080600060a0868803121561564e57600080fd5b615657866151f2565b945060208601519350604086015192506060860151915061567a608087016151f2565b90509295509295909350565b600081518084526020808501945080840160005b838110156156bf5781516001600160a01b03168752958201959082019060010161569a565b509495945050505050565b8060005b60028110156156ed5781518452602093840193909101906001016156ce565b50505050565b600081518084526020808501945080840160005b838110156156bf57815187529582019590820190600101615707565b6000815180845261573b816020860160208601615cde565b601f01601f19169290920160200192915050565b61575981836156ca565b604001919050565b60008351615773818460208801615cde565b835190830190615787818360208801615cde565b01949350505050565b8681526157a060208201876156ca565b6157ad60608201866156ca565b6157ba60a08201856156ca565b6157c760e08201846156ca565b60609190911b6001600160601b0319166101208201526101340195945050505050565b8381526157fa60208201846156ca565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6040810161272a82846156ca565b60208152600061102b60208301846156f3565b9182526001600160401b0316602082015260400190565b60208152600061102b6020830184615723565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261590460e0840182615686565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b9182526001600160a01b0316602082015260400190565b8281526060810161102b60208301846156ca565b8281526040602082015260006135ff60408301846156f3565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a0830152614a0460c0830184615723565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c0820181905260009061415390830184615723565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c0820181905260009061415390830184615723565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a060808201819052600090615aa190830184615686565b979650505050505050565b6000808335601e19843603018112615ac357600080fd5b8301803591506001600160401b03821115615add57600080fd5b602001915036819003821315615af257600080fd5b9250929050565b60405160c081016001600160401b0381118282101715615b1b57615b1b615db8565b60405290565b60405161012081016001600160401b0381118282101715615b1b57615b1b615db8565b604051601f8201601f191681016001600160401b0381118282101715615b6c57615b6c615db8565b604052919050565b60008085851115615b8457600080fd5b83861115615b9157600080fd5b5050820193919092039150565b60008219821115615bb157615bb1615d60565b500190565b60006001600160401b0380831681851680830382111561578757615787615d60565b600060ff821660ff84168060ff03821115615bf557615bf5615d60565b019392505050565b60006001600160601b0382811684821680830382111561578757615787615d60565b600082615c2e57615c2e615d76565b500490565b6000816000190483118215151615615c4d57615c4d615d60565b500290565b600082821015615c6457615c64615d60565b500390565b600063ffffffff83811690831681811015615c8657615c86615d60565b039392505050565b60006001600160601b0383811690831681811015615c8657615c86615d60565b6001600160e01b03198135818116916004851015615cd65780818660040360031b1b83161692505b505092915050565b60005b83811015615cf9578181015183820152602001615ce1565b838111156156ed5750506000910152565b6000600019821415615d1e57615d1e615d60565b5060010190565b60006001600160401b0380831681811415615d4257615d42615d60565b6001019392505050565b600082615d5b57615d5b615d76565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610aa257600080fd5b8015158114610aa257600080fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"want\",\"type\":\"uint256\"}],\"name\":\"InsufficientGasForConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2_5.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162005da138038062005da1833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615bc6620001db6000396000818161055001526131e70152615bc66000f3fe60806040526004361061021c5760003560e01c80638402595e11610124578063b2a7cac5116100a6578063b2a7cac514610732578063bec4c08c14610752578063caf70c4a14610772578063cb63179714610792578063d98e620e146107b2578063da2f2610146107d2578063dac83d2914610831578063dc311dd314610851578063e72f6e3014610882578063ee9d2d38146108a2578063f2fde38b146108cf57600080fd5b80638402595e146105c757806386fe91c7146105e75780638da5cb5b1461060757806395b55cfc146106255780639b1c385e146106385780639d40a6fd14610658578063a21a23e414610690578063a4c0ed36146106a5578063a63e0bfb146106c5578063aa433aff146106e5578063aefb212f1461070557600080fd5b8063405b84fa116101ad578063405b84fa1461044e57806340d6bb821461046e57806341af6c871461049957806351cff8d9146104c95780635d06b4ab146104e957806364d51a2a14610509578063659827441461051e578063689c45171461053e57806372e9d5651461057257806379ba5097146105925780637a5a2aef146105a757600080fd5b806304104edb14610221578063043bd6ae14610243578063088070f51461026c57806308821d581461033a5780630ae095401461035a57806315c48b841461037a57806318e3dd27146103a25780631b6b6d23146103e15780632f622e6b1461040e578063301f42e91461042e575b600080fd5b34801561022d57600080fd5b5061024161023c366004614f92565b6108ef565b005b34801561024f57600080fd5b5061025960105481565b6040519081526020015b60405180910390f35b34801561027857600080fd5b50600c546102dd9061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610263565b34801561034657600080fd5b50610241610355366004615070565b610a5c565b34801561036657600080fd5b5061024161037536600461535a565b610c06565b34801561038657600080fd5b5061038f60c881565b60405161ffff9091168152602001610263565b3480156103ae57600080fd5b50600a546103c990600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610263565b3480156103ed57600080fd5b50600254610401906001600160a01b031681565b604051610263919061558b565b34801561041a57600080fd5b50610241610429366004614f92565b610c4e565b34801561043a57600080fd5b506103c9610449366004615176565b610d9a565b34801561045a57600080fd5b5061024161046936600461535a565b610fc0565b34801561047a57600080fd5b506104846101f481565b60405163ffffffff9091168152602001610263565b3480156104a557600080fd5b506104b96104b43660046150f9565b611372565b6040519015158152602001610263565b3480156104d557600080fd5b506102416104e4366004614f92565b611482565b3480156104f557600080fd5b50610241610504366004614f92565b611610565b34801561051557600080fd5b5061038f606481565b34801561052a57600080fd5b50610241610539366004614faf565b6116c7565b34801561054a57600080fd5b506104017f000000000000000000000000000000000000000000000000000000000000000081565b34801561057e57600080fd5b50600354610401906001600160a01b031681565b34801561059e57600080fd5b50610241611727565b3480156105b357600080fd5b506102416105c236600461508c565b6117d1565b3480156105d357600080fd5b506102416105e2366004614f92565b611901565b3480156105f357600080fd5b50600a546103c9906001600160601b031681565b34801561061357600080fd5b506000546001600160a01b0316610401565b6102416106333660046150f9565b611a13565b34801561064457600080fd5b50610259610653366004615264565b611b37565b34801561066457600080fd5b50600754610678906001600160401b031681565b6040516001600160401b039091168152602001610263565b34801561069c57600080fd5b50610259611e78565b3480156106b157600080fd5b506102416106c0366004614fe8565b61204b565b3480156106d157600080fd5b506102416106e03660046152b9565b6121c7565b3480156106f157600080fd5b506102416107003660046150f9565b612444565b34801561071157600080fd5b5061072561072036600461537f565b61248c565b6040516102639190615602565b34801561073e57600080fd5b5061024161074d3660046150f9565b61258e565b34801561075e57600080fd5b5061024161076d36600461535a565b612683565b34801561077e57600080fd5b5061025961078d3660046150c0565b61278f565b34801561079e57600080fd5b506102416107ad36600461535a565b6127bf565b3480156107be57600080fd5b506102596107cd3660046150f9565b612a2e565b3480156107de57600080fd5b506108126107ed3660046150f9565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b03909116602083015201610263565b34801561083d57600080fd5b5061024161084c36600461535a565b612a4f565b34801561085d57600080fd5b5061087161086c3660046150f9565b612ae6565b6040516102639594939291906157d7565b34801561088e57600080fd5b5061024161089d366004614f92565b612bd4565b3480156108ae57600080fd5b506102596108bd3660046150f9565b600f6020526000908152604090205481565b3480156108db57600080fd5b506102416108ea366004614f92565b612da7565b6108f7612db8565b60115460005b81811015610a3457826001600160a01b03166011828154811061092257610922615b22565b6000918252602090912001546001600160a01b03161415610a2457601161094a6001846159d2565b8154811061095a5761095a615b22565b600091825260209091200154601180546001600160a01b03909216918390811061098657610986615b22565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060118054806109c5576109c5615b0c565b600082815260209020810160001990810180546001600160a01b03191690550190556040517ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3790610a1790859061558b565b60405180910390a1505050565b610a2d81615a8a565b90506108fd565b5081604051635428d44960e01b8152600401610a50919061558b565b60405180910390fd5b50565b610a64612db8565b604080518082018252600091610a9391908490600290839083908082843760009201919091525061278f915050565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b03169183019190915291925090610af157604051631dfd6e1360e21b815260048101839052602401610a50565b6000828152600d6020526040812080546001600160481b0319169055600e54905b81811015610bc25783600e8281548110610b2e57610b2e615b22565b90600052602060002001541415610bb257600e610b4c6001846159d2565b81548110610b5c57610b5c615b22565b9060005260206000200154600e8281548110610b7a57610b7a615b22565b600091825260209091200155600e805480610b9757610b97615b0c565b60019003818190600052602060002001600090559055610bc2565b610bbb81615a8a565b9050610b12565b507f9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5838360200151604051610bf8929190615615565b60405180910390a150505050565b81610c1081612e0d565b610c18612e6e565b610c2183611372565b15610c3f57604051631685ecdd60e31b815260040160405180910390fd5b610c498383612e99565b505050565b610c56612e6e565b610c5e612db8565b600b54600160601b90046001600160601b0316610c8e57604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c610cb18380615a0e565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610cf99190615a0e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610d73576040519150601f19603f3d011682016040523d82523d6000602084013e610d78565b606091505b5050905080610c495760405163950b247960e01b815260040160405180910390fd5b6000610da4612e6e565b60005a90506000610db5868661304d565b90506000610dcb85836000015160200151613309565b60408301516060888101519293509163ffffffff16806001600160401b03811115610df857610df8615b38565b604051908082528060200260200182016040528015610e21578160200160208202803683370190505b50925060005b81811015610e895760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c848281518110610e6e57610e6e615b22565b6020908102919091010152610e8281615a8a565b9050610e27565b50506020808501516000818152600f9092526040822082905590610eae828b86613357565b60208b81015160008181526006909252604090912080549293509091601890610ee690600160c01b90046001600160401b0316615aa5565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555060008b60a0015160018d60a0015151610f2391906159d2565b81518110610f3357610f33615b22565b60209101015160f81c6001149050610f4d8988838e6133f2565b9950610f5a8a8284613422565b50604080518581526001600160601b038b166020820152831515818301528b151560608201529051829185917f6c6b5394380e16e41988d8383648010de6f5c2e4814803be5de1c6b1c852db559181900360800190a350505050505050505b9392505050565b610fc8612e6e565b610fd181613575565b610ff05780604051635428d44960e01b8152600401610a50919061558b565b600080600080610fff86612ae6565b945094505093509350336001600160a01b0316826001600160a01b0316146110625760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610a50565b61106b86611372565b156110b15760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610a50565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a0830152915190916000916111069184910161563f565b6040516020818303038152906040529050611120886135e1565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b0388169061115990859060040161562c565b6000604051808303818588803b15801561117257600080fd5b505af1158015611186573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506111af905057506001600160601b03861615155b156112795760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906111e6908a908a906004016155d2565b602060405180830381600087803b15801561120057600080fd5b505af1158015611214573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123891906150dc565b6112795760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a50565b600c805460ff60301b1916600160301b17905560005b8351811015611320578381815181106112aa576112aa615b22565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016112dd919061558b565b600060405180830381600087803b1580156112f757600080fd5b505af115801561130b573d6000803e3d6000fd5b505050508061131990615a8a565b905061128f565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906113609089908b9061559f565b60405180910390a15050505050505050565b6000818152600560205260408120600201805480611394575060009392505050565b600e5460005b828110156114765760008482815481106113b6576113b6615b22565b60009182526020822001546001600160a01b031691505b8381101561146357600061142b600e83815481106113ed576113ed615b22565b60009182526020808320909101546001600160a01b03871683526004825260408084208e855290925291205485908c906001600160401b0316613789565b506000818152600f6020526040902054909150156114525750600198975050505050505050565b5061145c81615a8a565b90506113cd565b50508061146f90615a8a565b905061139a565b50600095945050505050565b61148a612e6e565b611492612db8565b6002546001600160a01b03166114bb5760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166114e457604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006115008380615a0e565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166115489190615a0e565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061159d90859085906004016155d2565b602060405180830381600087803b1580156115b757600080fd5b505af11580156115cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ef91906150dc565b61160c57604051631e9acf1760e31b815260040160405180910390fd5b5050565b611618612db8565b61162181613575565b15611641578060405163ac8a27ef60e01b8152600401610a50919061558b565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625906116bc90839061558b565b60405180910390a150565b6116cf612db8565b6002546001600160a01b0316156116f957604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b0316331461177a5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610a50565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6117d9612db8565b60408051808201825260009161180891908590600290839083908082843760009201919091525061278f915050565b6000818152600d602052604090205490915060ff161561183e57604051634a0b8fa760e01b815260048101829052602401610a50565b60408051808201825260018082526001600160401b0385811660208085019182526000878152600d9091528581209451855492516001600160481b031990931690151568ffffffffffffffff00191617610100929093169190910291909117909255600e805491820181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01829055517f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd390610a179083908590615615565b611909612db8565b600a544790600160601b90046001600160601b031681811115611949576040516354ced18160e11b81526004810182905260248101839052604401610a50565b81811015610c4957600061195d82846159d2565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d80600081146119ac576040519150601f19603f3d011682016040523d82523d6000602084013e6119b1565b606091505b50509050806119d35760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611a0492919061559f565b60405180910390a15050505050565b611a1b612e6e565b6000818152600560205260409020546001600160a01b0316611a5057604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611a7f838561597d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611ac7919061597d565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611b1a919061591e565b604080519283526020830191909152015b60405180910390a25050565b6000611b41612e6e565b602080830135600081815260059092526040909120546001600160a01b0316611b7d57604051630fb532db60e11b815260040160405180910390fd5b33600090815260046020908152604080832084845291829052909120546001600160401b031680611bc55782336040516379bfd40160e01b8152600401610a509291906156b4565b600c5461ffff16611bdc606087016040880161529e565b61ffff161080611bff575060c8611bf9606087016040880161529e565b61ffff16115b15611c4557611c14606086016040870161529e565b600c5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610a50565b600c5462010000900463ffffffff16611c6460808701606088016153a1565b63ffffffff161115611cb457611c8060808601606087016153a1565b600c54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610a50565b6101f4611cc760a08701608088016153a1565b63ffffffff161115611d0d57611ce360a08601608087016153a1565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610a50565b611d1681615aa5565b90506000611d278635338685613789565b90955090506000611d4b611d46611d4160a08a018a61582c565b613802565b61387f565b905085611d566138f0565b86611d6760808b0160608c016153a1565b611d7760a08c0160808d016153a1565b3386604051602001611d8f9796959493929190615737565b60405160208183030381529060405280519060200120600f600088815260200190815260200160002081905550336001600160a01b03168588600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e89868c6040016020810190611e02919061529e565b8d6060016020810190611e1591906153a1565b8e6080016020810190611e2891906153a1565b89604051611e3b969594939291906156f8565b60405180910390a450506000928352602091909152604090912080546001600160401b0319166001600160401b039092169190911790555b919050565b6000611e82612e6e565b6007546001600160401b031633611e9a6001436159d2565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611eff816001615936565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b039283161783559351600183018054909516911617909255925180519294939192611ffd9260028501920190614cac565b5061200d91506008905084613980565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161203e919061558b565b60405180910390a2505090565b612053612e6e565b6002546001600160a01b0316331461207e576040516344b0e3c360e01b815260040160405180910390fd5b6020811461209f57604051638129bbcd60e01b815260040160405180910390fd5b60006120ad828401846150f9565b6000818152600560205260409020549091506001600160a01b03166120e557604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061210c838561597d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b0316612154919061597d565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846121a7919061591e565b6040805192835260208301919091520160405180910390a2505050505050565b6121cf612db8565b60c861ffff8a1611156122095760405163539c34bb60e11b815261ffff8a1660048201819052602482015260c86044820152606401610a50565b6000851361222d576040516321ea67b360e11b815260048101869052602401610a50565b60008463ffffffff1611801561224f57508363ffffffff168363ffffffff1610155b1561227d576040516313c06e5960e11b815263ffffffff808516600483015285166024820152604401610a50565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b9099029890981667ffffffffffffffff60781b19600160581b90960263ffffffff60581b19600160381b9098029790971668ffffffffffffffffff60301b196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b690612431908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b61244c612db8565b6000818152600560205260409020546001600160a01b03168061248257604051630fb532db60e11b815260040160405180910390fd5b61160c8282612e99565b6060600061249a600861398c565b90508084106124bc57604051631390f2a160e01b815260040160405180910390fd5b60006124c8848661591e565b9050818111806124d6575083155b6124e057806124e2565b815b905060006124f086836159d2565b9050806001600160401b0381111561250a5761250a615b38565b604051908082528060200260200182016040528015612533578160200160208202803683370190505b50935060005b818110156125835761255661254e888361591e565b600890613996565b85828151811061256857612568615b22565b602090810291909101015261257c81615a8a565b9050612539565b505050505b92915050565b612596612e6e565b6000818152600560205260409020546001600160a01b0316806125cc57604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b03163314612623576000828152600560205260409081902060010154905163d084e97560e01b8152610a50916001600160a01b03169060040161558b565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611b2b9185916155b8565b8161268d81612e0d565b612695612e6e565b60008381526005602052604090206002018054606414156126c9576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b038316600090815260046020908152604080832087845291829052909120546001600160401b031615612704575050505050565b600085815260208281526040808320805460016001600160401b0319909116811790915585549081018655858452919092200180546001600160a01b0319166001600160a01b0387161790555185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061278090879061558b565b60405180910390a25050505050565b6000816040516020016127a291906155f4565b604051602081830303815290604052805190602001209050919050565b816127c981612e0d565b6127d1612e6e565b6127da83611372565b156127f857604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b03166128465782826040516379bfd40160e01b8152600401610a509291906156b4565b6000838152600560209081526040808320600201805482518185028101850190935280835291929091908301828280156128a957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161288b575b505050505090506000600182516128c091906159d2565b905060005b82518110156129ca57846001600160a01b03168382815181106128ea576128ea615b22565b60200260200101516001600160a01b031614156129ba57600083838151811061291557612915615b22565b602002602001015190508060056000898152602001908152602001600020600201838154811061294757612947615b22565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925588815260059091526040902060020180548061299257612992615b0c565b600082815260209020810160001990810180546001600160a01b0319169055019055506129ca565b6129c381615a8a565b90506128c5565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160401b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79061278090879061558b565b600e8181548110612a3e57600080fd5b600091825260209091200154905081565b81612a5981612e0d565b612a61612e6e565b600083815260056020526040902060018101546001600160a01b03848116911614612ae0576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612ad790339087906155b8565b60405180910390a25b50505050565b600081815260056020526040812054819081906001600160a01b0316606081612b2257604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612bba57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612b9c575b505050505090509450945094509450945091939590929450565b612bdc612db8565b6002546001600160a01b0316612c055760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612c3690309060040161558b565b60206040518083038186803b158015612c4e57600080fd5b505afa158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c869190615112565b600a549091506001600160601b031681811115612cc0576040516354ced18160e11b81526004810182905260248101839052604401610a50565b81811015610c49576000612cd482846159d2565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612d07908790859060040161559f565b602060405180830381600087803b158015612d2157600080fd5b505af1158015612d35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5991906150dc565b612d7657604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366008482604051610bf892919061559f565b612daf612db8565b610a59816139a2565b6000546001600160a01b03163314612e0b5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610a50565b565b6000818152600560205260409020546001600160a01b031680612e4357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461160c5780604051636c51fda960e11b8152600401610a50919061558b565b600c54600160301b900460ff1615612e0b5760405163769dd35360e11b815260040160405180910390fd5b600080612ea5846135e1565b60025491935091506001600160a01b031615801590612ecc57506001600160601b03821615155b15612f7b5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90612f0c9086906001600160601b0387169060040161559f565b602060405180830381600087803b158015612f2657600080fd5b505af1158015612f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5e91906150dc565b612f7b57604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114612fd1576040519150601f19603f3d011682016040523d82523d6000602084013e612fd6565b606091505b5050905080612ff85760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c490606001612780565b6040805160a08101825260006060820181815260808301829052825260208201819052918101919091526000613086846000015161278f565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b031691830191909152919250906130e457604051631dfd6e1360e21b815260048101839052602401610a50565b6000828660800151604051602001613106929190918252602082015260400190565b60408051601f1981840301815291815281516020928301206000818152600f9093529120549091508061314c57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d0151935161317b978a979096959101615783565b6040516020818303038152906040528051906020012081146131b05760405163354a450b60e21b815260040160405180910390fd5b60006131bf8760000151613a46565b905080613297578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561323157600080fd5b505afa158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615112565b90508061329757865160405163175dadad60e01b81526001600160401b039091166004820152602401610a50565b60008860800151826040516020016132b9929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006132e08a83613b28565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a111561334f57821561333257506001600160401b038116612588565b3a8260405163435e532d60e11b8152600401610a50929190615615565b503a92915050565b6000806000631fe543e360e01b86856040516024016133779291906156df565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559086015160808701519192506133db9163ffffffff9091169083613b93565b600c805460ff60301b191690559695505050505050565b6000821561340c57613405858584613bdf565b905061341a565b613417858584613cf0565b90505b949350505050565b600081815260066020526040902082156134e15780546001600160601b03600160601b909104811690851681101561346d57604051631e9acf1760e31b815260040160405180910390fd5b6134778582615a0e565b8254600160601b600160c01b031916600160601b6001600160601b039283168102919091178455600b805488939192600c926134b792869290041661597d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050612ae0565b80546001600160601b0390811690851681101561351157604051631e9acf1760e31b815260040160405180910390fd5b61351b8582615a0e565b82546001600160601b0319166001600160601b03918216178355600b8054879260009161354a9185911661597d565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050505050565b601154600090815b818110156135d757836001600160a01b0316601182815481106135a2576135a2615b22565b6000918252602090912001546001600160a01b031614156135c7575060019392505050565b6135d081615a8a565b905061357d565b5060009392505050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b81811015613683576004600084838154811061363657613636615b22565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160401b031916905561367c81615a8a565b9050613618565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906136bb6002830182614d11565b50506000858152600660205260408120556136d7600886613ed9565b506001600160601b0384161561372a57600a80548591906000906137059084906001600160601b0316615a0e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156137825782600a600c8282829054906101000a90046001600160601b031661375d9190615a0e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b6040805160208082018790526001600160a01b03959095168183015260608101939093526001600160401b03919091166080808401919091528151808403909101815260a08301825280519084012060c083019490945260e0808301859052815180840390910181526101009092019052805191012091565b6040805160208101909152600081528161382b5750604080516020810190915260008152612588565b63125fa26760e31b61383d8385615a2e565b6001600160e01b0319161461386557604051632923fee760e11b815260040160405180910390fd5b61387282600481866158f4565b810190610fb9919061512b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016138b891511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b6000466138fc81613ee5565b156139795760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561393b57600080fd5b505afa15801561394f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139739190615112565b91505090565b4391505090565b6000610fb98383613f08565b6000612588825490565b6000610fb98383613f57565b6001600160a01b0381163314156139f55760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610a50565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613a5281613ee5565b15613b1957610100836001600160401b0316613a6c6138f0565b613a7691906159d2565b1180613a925750613a856138f0565b836001600160401b031610155b15613aa05750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a82906024015b60206040518083038186803b158015613ae157600080fd5b505afa158015613af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb99190615112565b50506001600160401b03164090565b6000613b5c8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f81565b60038360200151604051602001613b749291906156cb565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613ba557600080fd5b611388810390508460408204820311613bbd57600080fd5b50823b613bc957600080fd5b60008083516020850160008789f1949350505050565b600080613c226000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061419d92505050565b905060005a600c54613c42908890600160581b900463ffffffff1661591e565b613c4c91906159d2565b613c5690866159b3565b600c54909150600090613c7b90600160781b900463ffffffff1664e8d4a510006159b3565b90508415613cc757600c548190606490600160b81b900460ff16613c9f858761591e565b613ca991906159b3565b613cb3919061599f565b613cbd919061591e565b9350505050610fb9565b600c548190606490613ce390600160b81b900460ff1682615958565b60ff16613c9f858761591e565b600080613cfb61426b565b905060008113613d21576040516321ea67b360e11b815260048101829052602401610a50565b6000613d636000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061419d92505050565b9050600082825a600c54613d85908b90600160581b900463ffffffff1661591e565b613d8f91906159d2565b613d9990896159b3565b613da3919061591e565b613db590670de0b6b3a76400006159b3565b613dbf919061599f565b600c54909150600090613de89063ffffffff600160981b8204811691600160781b9004166159e9565b613dfd9063ffffffff1664e8d4a510006159b3565b9050600084613e1483670de0b6b3a76400006159b3565b613e1e919061599f565b905060008715613e5f57600c548290606490613e4490600160c01b900460ff16876159b3565b613e4e919061599f565b613e58919061591e565b9050613e9f565b600c548290606490613e7b90600160c01b900460ff1682615958565b613e889060ff16876159b3565b613e92919061599f565b613e9c919061591e565b90505b6b033b2e3c9fd0803ce8000000811115613ecc5760405163e80fa38160e01b815260040160405180910390fd5b9998505050505050505050565b6000610fb9838361433a565b600061a4b1821480613ef9575062066eed82145b8061258857505062066eee1490565b6000818152600183016020526040812054613f4f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612588565b506000612588565b6000826000018281548110613f6e57613f6e615b22565b9060005260206000200154905092915050565b613f8a8961442d565b613fd35760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610a50565b613fdc8861442d565b6140205760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610a50565b6140298361442d565b6140755760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610a50565b61407e8261442d565b6140ca5760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610a50565b6140d6878a88876144f0565b61411e5760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610a50565b600061412a8a87614613565b9050600061413d898b878b868989614677565b9050600061414e838d8d8a86614796565b9050808a1461418f5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610a50565b505050505050505050505050565b6000466141a981613ee5565b156141e857606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613ae157600080fd5b6141f1816147d6565b1561426257600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615b72604891396040516020016142379291906154e1565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613ac9919061562c565b50600092915050565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169284926001600160a01b039091169163feaf968c9160048082019260a092909190829003018186803b1580156142c657600080fd5b505afa1580156142da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142fe91906153bc565b50919550909250505063ffffffff82161580159061432a575061432181426159d2565b8263ffffffff16105b156143355760105492505b505090565b6000818152600183016020526040812054801561442357600061435e6001836159d2565b8554909150600090614372906001906159d2565b90508181146143d757600086600001828154811061439257614392615b22565b90600052602060002001549050808760000184815481106143b5576143b5615b22565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806143e8576143e8615b0c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612588565b6000915050612588565b80516000906401000003d0191161447b5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610a50565b60208201516401000003d019116144c95760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610a50565b60208201516401000003d0199080096144e98360005b6020020151614810565b1492915050565b60006001600160a01b0382166145365760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610a50565b60208401516000906001161561454d57601c614550565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa1580156145eb573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b61461b614d2f565b614648600184846040516020016146349392919061556a565b604051602081830303815290604052614834565b90505b6146548161442d565b6125885780516040805160208101929092526146709101614634565b905061464b565b61467f614d2f565b825186516401000003d01990819006910614156146de5760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610a50565b6146e9878988614882565b61472e5760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610a50565b614739848685614882565b61477f5760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610a50565b61478a8684846149aa565b98975050505050505050565b6000600286868685876040516020016147b496959493929190615510565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a8214806147e857506101a482145b806147f5575062aa37dc82145b80614801575061210582145b8061258857505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b61483c614d2f565b61484582614a6d565b815261485a6148558260006144df565b614aa8565b602082018190526002900660011415611e73576020810180516401000003d019039052919050565b6000826148bf5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610a50565b835160208501516000906148d590600290615acc565b156148e157601c6148e4565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614956573d6000803e3d6000fd5b50505060206040510351905060008660405160200161497591906154cf565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b6149b2614d2f565b8351602080860151855191860151600093849384936149d393909190614ac8565b919450925090506401000003d019858209600114614a2f5760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610a50565b60405180604001604052806401000003d01980614a4e57614a4e615af6565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611e7357604080516020808201939093528151808203840181529082019091528051910120614a75565b6000612588826002614ac16401000003d019600161591e565b901c614ba8565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614b0883838585614c3f565b9098509050614b1988828e88614c63565b9098509050614b2a88828c87614c63565b90985090506000614b3d8d878b85614c63565b9098509050614b4e88828686614c3f565b9098509050614b5f88828e89614c63565b9098509050818114614b94576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614b98565b8196505b5050505050509450945094915050565b600080614bb3614d4d565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614be5614d6b565b60208160c0846005600019fa925082614c355760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610a50565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614d01579160200282015b82811115614d0157825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614ccc565b50614d0d929150614d89565b5090565b5080546000825590600052602060002090810190610a599190614d89565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614d0d5760008155600101614d8a565b8035611e7381615b4e565b806040810183101561258857600080fd5b600082601f830112614dcb57600080fd5b604051604081018181106001600160401b0382111715614ded57614ded615b38565b8060405250808385604086011115614e0457600080fd5b60005b6002811015614e26578135835260209283019290910190600101614e07565b509195945050505050565b8035611e7381615b63565b600060c08284031215614e4e57600080fd5b614e56615879565b9050614e6182614f50565b815260208083013581830152614e7960408401614f3c565b6040830152614e8a60608401614f3c565b60608301526080830135614e9d81615b4e565b608083015260a08301356001600160401b0380821115614ebc57600080fd5b818501915085601f830112614ed057600080fd5b813581811115614ee257614ee2615b38565b614ef4601f8201601f191685016158c4565b91508082528684828501011115614f0a57600080fd5b80848401858401376000848284010152508060a085015250505092915050565b803561ffff81168114611e7357600080fd5b803563ffffffff81168114611e7357600080fd5b80356001600160401b0381168114611e7357600080fd5b803560ff81168114611e7357600080fd5b805169ffffffffffffffffffff81168114611e7357600080fd5b600060208284031215614fa457600080fd5b8135610fb981615b4e565b60008060408385031215614fc257600080fd5b8235614fcd81615b4e565b91506020830135614fdd81615b4e565b809150509250929050565b60008060008060608587031215614ffe57600080fd5b843561500981615b4e565b93506020850135925060408501356001600160401b038082111561502c57600080fd5b818701915087601f83011261504057600080fd5b81358181111561504f57600080fd5b88602082850101111561506157600080fd5b95989497505060200194505050565b60006040828403121561508257600080fd5b610fb98383614da9565b6000806060838503121561509f57600080fd5b6150a98484614da9565b91506150b760408401614f50565b90509250929050565b6000604082840312156150d257600080fd5b610fb98383614dba565b6000602082840312156150ee57600080fd5b8151610fb981615b63565b60006020828403121561510b57600080fd5b5035919050565b60006020828403121561512457600080fd5b5051919050565b60006020828403121561513d57600080fd5b604051602081018181106001600160401b038211171561515f5761515f615b38565b604052823561516d81615b63565b81529392505050565b60008060008385036101e081121561518d57600080fd5b6101a08082121561519d57600080fd5b6151a56158a1565b91506151b18787614dba565b82526151c08760408801614dba565b60208301526080860135604083015260a0860135606083015260c086013560808301526151ef60e08701614d9e565b60a083015261010061520388828901614dba565b60c0840152615216886101408901614dba565b60e0840152610180870135908301529093508401356001600160401b0381111561523f57600080fd5b61524b86828701614e3c565b92505061525b6101c08501614e31565b90509250925092565b60006020828403121561527657600080fd5b81356001600160401b0381111561528c57600080fd5b820160c08185031215610fb957600080fd5b6000602082840312156152b057600080fd5b610fb982614f2a565b60008060008060008060008060006101208a8c0312156152d857600080fd5b6152e18a614f2a565b98506152ef60208b01614f3c565b97506152fd60408b01614f3c565b965061530b60608b01614f3c565b955060808a0135945061532060a08b01614f3c565b935061532e60c08b01614f3c565b925061533c60e08b01614f67565b915061534b6101008b01614f67565b90509295985092959850929598565b6000806040838503121561536d57600080fd5b823591506020830135614fdd81615b4e565b6000806040838503121561539257600080fd5b50508035926020909101359150565b6000602082840312156153b357600080fd5b610fb982614f3c565b600080600080600060a086880312156153d457600080fd5b6153dd86614f78565b945060208601519350604086015192506060860151915061540060808701614f78565b90509295509295909350565b600081518084526020808501945080840160005b838110156154455781516001600160a01b031687529582019590820190600101615420565b509495945050505050565b8060005b6002811015612ae0578151845260209384019390910190600101615454565b600081518084526020808501945080840160005b8381101561544557815187529582019590820190600101615487565b600081518084526154bb816020860160208601615a5e565b601f01601f19169290920160200192915050565b6154d98183615450565b604001919050565b600083516154f3818460208801615a5e565b835190830190615507818360208801615a5e565b01949350505050565b8681526155206020820187615450565b61552d6060820186615450565b61553a60a0820185615450565b61554760e0820184615450565b60609190911b6001600160601b0319166101208201526101340195945050505050565b83815261557a6020820184615450565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b604081016125888284615450565b602081526000610fb96020830184615473565b9182526001600160401b0316602082015260400190565b602081526000610fb960208301846154a3565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261568460e084018261540c565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b9182526001600160a01b0316602082015260400190565b82815260608101610fb96020830184615450565b82815260406020820152600061341a6040830184615473565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261478a60c08301846154a3565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ecc908301846154a3565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ecc908301846154a3565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a0608082018190526000906158219083018461540c565b979650505050505050565b6000808335601e1984360301811261584357600080fd5b8301803591506001600160401b0382111561585d57600080fd5b60200191503681900382131561587257600080fd5b9250929050565b60405160c081016001600160401b038111828210171561589b5761589b615b38565b60405290565b60405161012081016001600160401b038111828210171561589b5761589b615b38565b604051601f8201601f191681016001600160401b03811182821017156158ec576158ec615b38565b604052919050565b6000808585111561590457600080fd5b8386111561591157600080fd5b5050820193919092039150565b6000821982111561593157615931615ae0565b500190565b60006001600160401b0380831681851680830382111561550757615507615ae0565b600060ff821660ff84168060ff0382111561597557615975615ae0565b019392505050565b60006001600160601b0382811684821680830382111561550757615507615ae0565b6000826159ae576159ae615af6565b500490565b60008160001904831182151516156159cd576159cd615ae0565b500290565b6000828210156159e4576159e4615ae0565b500390565b600063ffffffff83811690831681811015615a0657615a06615ae0565b039392505050565b60006001600160601b0383811690831681811015615a0657615a06615ae0565b6001600160e01b03198135818116916004851015615a565780818660040360031b1b83161692505b505092915050565b60005b83811015615a79578181015183820152602001615a61565b83811115612ae05750506000910152565b6000600019821415615a9e57615a9e615ae0565b5060010190565b60006001600160401b0380831681811415615ac257615ac2615ae0565b6001019392505050565b600082615adb57615adb615af6565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a5957600080fd5b8015158114610a5957600080fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000806000a", } var VRFCoordinatorV25ABI = VRFCoordinatorV25MetaData.ABI diff --git a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go index 88230b75fee..f81693ce06b 100644 --- a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go +++ b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go @@ -61,8 +61,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } var VRFCoordinatorV2PlusUpgradedVersionMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162005f5d38038062005f5d833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615d82620001db600039600081816104f4015261349c0152615d826000f3fe6080604052600436106101e05760003560e01c8062012291146101e5578063088070f5146102125780630ae09540146102e057806315c48b841461030257806318e3dd271461032a5780631b6b6d2314610369578063294daa49146103965780632f622e6b146103b2578063301f42e9146103d2578063405b84fa146103f257806340d6bb821461041257806341af6c871461043d57806351cff8d91461046d5780635d06b4ab1461048d57806364d51a2a146104ad57806365982744146104c2578063689c4517146104e257806372e9d5651461051657806379ba5097146105365780637bce14d11461054b5780638402595e1461056b57806386fe91c71461058b5780638da5cb5b146105ab57806395b55cfc146105c95780639b1c385e146105dc5780639d40a6fd1461060a578063a21a23e414610637578063a4c0ed361461064c578063a63e0bfb1461066c578063aa433aff1461068c578063aefb212f146106ac578063b2a7cac5146106d9578063bec4c08c146106f9578063caf70c4a14610719578063cb63179714610739578063ce3f471914610759578063d98e620e1461076c578063dac83d291461078c578063dc311dd3146107ac578063e72f6e30146107dd578063ee9d2d38146107fd578063f2fde38b1461082a575b600080fd5b3480156101f157600080fd5b506101fa61084a565b6040516102099392919061582f565b60405180910390f35b34801561021e57600080fd5b50600c546102839061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610209565b3480156102ec57600080fd5b506103006102fb3660046154a2565b6108c6565b005b34801561030e57600080fd5b5061031760c881565b60405161ffff9091168152602001610209565b34801561033657600080fd5b50600a5461035190600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610209565b34801561037557600080fd5b50600254610389906001600160a01b031681565b60405161020991906156d3565b3480156103a257600080fd5b5060405160028152602001610209565b3480156103be57600080fd5b506103006103cd366004614fbc565b61090e565b3480156103de57600080fd5b506103516103ed366004615173565b610a5a565b3480156103fe57600080fd5b5061030061040d3660046154a2565b610ef0565b34801561041e57600080fd5b506104286101f481565b60405163ffffffff9091168152602001610209565b34801561044957600080fd5b5061045d610458366004615489565b6112c1565b6040519015158152602001610209565b34801561047957600080fd5b50610300610488366004614fbc565b611462565b34801561049957600080fd5b506103006104a8366004614fbc565b6115f0565b3480156104b957600080fd5b50610317606481565b3480156104ce57600080fd5b506103006104dd366004614fd9565b6116a7565b3480156104ee57600080fd5b506103897f000000000000000000000000000000000000000000000000000000000000000081565b34801561052257600080fd5b50600354610389906001600160a01b031681565b34801561054257600080fd5b50610300611707565b34801561055757600080fd5b5061030061056636600461506d565b6117b1565b34801561057757600080fd5b50610300610586366004614fbc565b6118aa565b34801561059757600080fd5b50600a54610351906001600160601b031681565b3480156105b757600080fd5b506000546001600160a01b0316610389565b6103006105d7366004615489565b6119b6565b3480156105e857600080fd5b506105fc6105f7366004615261565b611ad7565b604051908152602001610209565b34801561061657600080fd5b5060075461062a906001600160401b031681565b60405161020991906159c8565b34801561064357600080fd5b506105fc611e23565b34801561065857600080fd5b50610300610667366004615012565b61204d565b34801561067857600080fd5b506103006106873660046153e8565b6121c7565b34801561069857600080fd5b506103006106a7366004615489565b6123d0565b3480156106b857600080fd5b506106cc6106c73660046154c7565b612433565b604051610209919061574a565b3480156106e557600080fd5b506103006106f4366004615489565b612536565b34801561070557600080fd5b506103006107143660046154a2565b612637565b34801561072557600080fd5b506105fc610734366004615095565b612751565b34801561074557600080fd5b506103006107543660046154a2565b612781565b6103006107673660046150e7565b612a01565b34801561077857600080fd5b506105fc610787366004615489565b612d18565b34801561079857600080fd5b506103006107a73660046154a2565b612d39565b3480156107b857600080fd5b506107cc6107c7366004615489565b612dcd565b6040516102099594939291906159dc565b3480156107e957600080fd5b506103006107f8366004614fbc565b612ec8565b34801561080957600080fd5b506105fc610818366004615489565b600f6020526000908152604090205481565b34801561083657600080fd5b50610300610845366004614fbc565b6130a3565b600c54600e805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff169391928391908301828280156108b457602002820191906000526020600020905b8154815260200190600101908083116108a0575b50505050509050925092509250909192565b816108d0816130b4565b6108d8613115565b6108e1836112c1565b156108ff57604051631685ecdd60e31b815260040160405180910390fd5b6109098383613142565b505050565b610916613115565b61091e6132f6565b600b54600160601b90046001600160601b031661094e57604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c6109718380615bc2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b03166109b99190615bc2565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610a33576040519150601f19603f3d011682016040523d82523d6000602084013e610a38565b606091505b50509050806109095760405163950b247960e01b815260040160405180910390fd5b6000610a64613115565b60005a90506000610a758686613349565b90506000856060015163ffffffff166001600160401b03811115610a9b57610a9b615cf4565b604051908082528060200260200182016040528015610ac4578160200160208202803683370190505b50905060005b866060015163ffffffff16811015610b3b57826040015181604051602001610af392919061575d565b6040516020818303038152906040528051906020012060001c828281518110610b1e57610b1e615cde565b602090810291909101015280610b3381615c46565b915050610aca565b50602080830180516000908152600f9092526040808320839055905190518291631fe543e360e01b91610b73919086906024016158b9565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559089015160808a0151919250600091610bd89163ffffffff1690846135b4565b600c805460ff60301b1916905560208a810151600090815260069091526040902054909150600160c01b90046001600160401b0316610c18816001615b34565b6020808c0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08b01518051610c6590600190615bab565b81518110610c7557610c75615cde565b602091010151600c5460f89190911c6001149150600090610ca6908a90600160581b900463ffffffff163a85613600565b90508115610d9e576020808d01516000908152600690915260409020546001600160601b03808316600160601b909204161015610cf657604051631e9acf1760e31b815260040160405180910390fd5b60208c81015160009081526006909152604090208054829190600c90610d2d908490600160601b90046001600160601b0316615bc2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b600c8282829054906101000a90046001600160601b0316610d759190615b56565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610e79565b6020808d01516000908152600690915260409020546001600160601b0380831691161015610ddf57604051631e9acf1760e31b815260040160405180910390fd5b6020808d015160009081526006909152604081208054839290610e0c9084906001600160601b0316615bc2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b60008282829054906101000a90046001600160601b0316610e549190615b56565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8b6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051610ed6939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b9392505050565b610ef8613115565b610f018161364f565b610f295780604051635428d44960e01b8152600401610f2091906156d3565b60405180910390fd5b600080600080610f3886612dcd565b945094505093509350336001600160a01b0316826001600160a01b031614610f9b5760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610f20565b610fa4866112c1565b15610fea5760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610f20565b60006040518060c00160405280610fff600290565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b03168152509050600081604051602001611053919061579c565b604051602081830303815290604052905061106d886136b9565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906110a6908590600401615789565b6000604051808303818588803b1580156110bf57600080fd5b505af11580156110d3573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506110fc905057506001600160601b03861615155b156111c65760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611133908a908a9060040161571a565b602060405180830381600087803b15801561114d57600080fd5b505af1158015611161573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118591906150b1565b6111c65760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610f20565b600c805460ff60301b1916600160301b17905560005b835181101561126f578381815181106111f7576111f7615cde565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b815260040161122a91906156d3565b600060405180830381600087803b15801561124457600080fd5b505af1158015611258573d6000803e3d6000fd5b50505050808061126790615c46565b9150506111dc565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906112af9089908b906156e7565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561134b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161132d575b505050505081525050905060005b8160400151518110156114585760005b600e5481101561144557600061140e600e838154811061138b5761138b615cde565b9060005260206000200154856040015185815181106113ac576113ac615cde565b60200260200101518860046000896040015189815181106113cf576113cf615cde565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d82529092529020546001600160401b0316613907565b506000818152600f6020526040902054909150156114325750600195945050505050565b508061143d81615c46565b915050611369565b508061145081615c46565b915050611359565b5060009392505050565b61146a613115565b6114726132f6565b6002546001600160a01b031661149b5760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166114c457604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006114e08380615bc2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166115289190615bc2565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061157d908590859060040161571a565b602060405180830381600087803b15801561159757600080fd5b505af11580156115ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cf91906150b1565b6115ec57604051631e9acf1760e31b815260040160405180910390fd5b5050565b6115f86132f6565b6116018161364f565b15611621578060405163ac8a27ef60e01b8152600401610f2091906156d3565b601280546001810182556000919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259061169c9083906156d3565b60405180910390a150565b6116af6132f6565b6002546001600160a01b0316156116d957604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b0316331461175a5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610f20565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6117b96132f6565b6040805180820182526000916117e8919084906002908390839080828437600092019190915250612751915050565b6000818152600d602052604090205490915060ff161561181e57604051634a0b8fa760e01b815260048101829052602401610f20565b6000818152600d6020526040808220805460ff19166001908117909155600e805491820181559092527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd909101829055517fc9583fd3afa3d7f16eb0b88d0268e7d05c09bafa4b21e092cbd1320e1bc8089d9061189e9083815260200190565b60405180910390a15050565b6118b26132f6565b600a544790600160601b90046001600160601b0316818111156118ec5780826040516354ced18160e11b8152600401610f2092919061575d565b818110156109095760006119008284615bab565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461194f576040519150601f19603f3d011682016040523d82523d6000602084013e611954565b606091505b50509050806119765760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c85836040516119a79291906156e7565b60405180910390a15050505050565b6119be613115565b6000818152600560205260409020546001600160a01b03166119f357604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611a228385615b56565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611a6a9190615b56565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611abd9190615b1c565b604051611acb92919061575d565b60405180910390a25050565b6000611ae1613115565b6020808301356000908152600590915260409020546001600160a01b0316611b1c57604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611b69578260200135336040516379bfd40160e01b8152600401610f2092919061588e565b600c5461ffff16611b8060608501604086016153cd565b61ffff161080611ba3575060c8611b9d60608501604086016153cd565b61ffff16115b15611bdd57611bb860608401604085016153cd565b600c5460405163539c34bb60e11b8152610f20929161ffff169060c890600401615811565b600c5462010000900463ffffffff16611bfc60808501606086016154e9565b63ffffffff161115611c4257611c1860808401606085016154e9565b600c54604051637aebf00f60e11b8152610f20929162010000900463ffffffff16906004016159b1565b6101f4611c5560a08501608086016154e9565b63ffffffff161115611c8f57611c7160a08401608085016154e9565b6101f46040516311ce1afb60e21b8152600401610f209291906159b1565b6000611c9c826001615b34565b9050600080611cb2863533602089013586613907565b90925090506000611cce611cc960a0890189615a31565b613990565b90506000611cdb82613a0d565b905083611ce6613a7e565b60208a0135611cfb60808c0160608d016154e9565b611d0b60a08d0160808e016154e9565b3386604051602001611d239796959493929190615911565b60405160208183030381529060405280519060200120600f600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611d9a91906153cd565b8e6060016020810190611dad91906154e9565b8f6080016020810190611dc091906154e9565b89604051611dd3969594939291906158d2565b60405180910390a45050336000908152600460209081526040808320898301358452909152902080546001600160401b0319166001600160401b039490941693909317909255925050505b919050565b6000611e2d613115565b600033611e3b600143615bab565b600754604051606093841b6001600160601b03199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b03909116906000611eb583615c61565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b03811115611ef457611ef4615cf4565b604051908082528060200260200182016040528015611f1d578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b039283161783559251600183018054909416911617909155925180519495509093611ffe9260028501920190614c80565b5061200e91506008905083613b0e565b50817f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161203f91906156d3565b60405180910390a250905090565b612055613115565b6002546001600160a01b03163314612080576040516344b0e3c360e01b815260040160405180910390fd5b602081146120a157604051638129bbcd60e01b815260040160405180910390fd5b60006120af82840184615489565b6000818152600560205260409020549091506001600160a01b03166120e757604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061210e8385615b56565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166121569190615b56565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846121a99190615b1c565b6040516121b792919061575d565b60405180910390a2505050505050565b6121cf6132f6565b60c861ffff8a1611156121fc57888960c860405163539c34bb60e11b8152600401610f2093929190615811565b60008513612220576040516321ea67b360e11b815260048101869052602401610f20565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b90990298909816600160781b600160b81b0319600160581b90960263ffffffff60581b19600160381b90980297909716600160301b600160781b03196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f95cb2ddab6d2297c29a4861691de69b3969c464aa4a9c44258b101ff02ff375a906123bd908b908b908b908b908b908990899061ffff97909716875263ffffffff95861660208801529385166040870152919093166060850152608084019290925260ff91821660a08401521660c082015260e00190565b60405180910390a1505050505050505050565b6123d86132f6565b6000818152600560205260409020546001600160a01b031661240d57604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020546124309082906001600160a01b0316613142565b50565b606060006124416008613b1a565b905080841061246357604051631390f2a160e01b815260040160405180910390fd5b600061246f8486615b1c565b90508181118061247d575083155b6124875780612489565b815b905060006124978683615bab565b6001600160401b038111156124ae576124ae615cf4565b6040519080825280602002602001820160405280156124d7578160200160208202803683370190505b50905060005b815181101561252a576124fb6124f38883615b1c565b600890613b24565b82828151811061250d5761250d615cde565b60209081029190910101528061252281615c46565b9150506124dd565b50925050505b92915050565b61253e613115565b6000818152600560205260409020546001600160a01b031661257357604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b031633146125ca576000818152600560205260409081902060010154905163d084e97560e01b8152610f20916001600160a01b0316906004016156d3565b6000818152600560205260409081902080546001600160a01b031980821633908117845560019093018054909116905591516001600160a01b039092169183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611acb918591615700565b81612641816130b4565b612649613115565b6000838152600560205260409020600201546064141561267c576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b0316156126b357505050565b6001600160a01b0382166000818152600460209081526040808320878452825280832080546001600160401b031916600190811790915560058352818420600201805491820181558452919092200180546001600160a01b0319169092179091555183907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1906127449085906156d3565b60405180910390a2505050565b600081604051602001612764919061573c565b604051602081830303815290604052805190602001209050919050565b8161278b816130b4565b612793613115565b61279c836112c1565b156127ba57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b03166128085782826040516379bfd40160e01b8152600401610f2092919061588e565b60008381526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561286b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161284d575b505050505090506000600182516128829190615bab565b905060005b825181101561298e57846001600160a01b03168382815181106128ac576128ac615cde565b60200260200101516001600160a01b0316141561297c5760008383815181106128d7576128d7615cde565b602002602001015190508060056000898152602001908152602001600020600201838154811061290957612909615cde565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925588815260059091526040902060020180548061295457612954615cc8565b600082815260209020810160001990810180546001600160a01b03191690550190555061298e565b8061298681615c46565b915050612887565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160401b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7906129f29087906156d3565b60405180910390a25050505050565b6000612a0f8284018461529b565b9050806000015160ff16600114612a4857805160405163237d181f60e21b815260ff909116600482015260016024820152604401610f20565b8060a001516001600160601b03163414612a8c5760a08101516040516306acf13560e41b81523460048201526001600160601b039091166024820152604401610f20565b6020808201516000908152600590915260409020546001600160a01b031615612ac8576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612b685760016004600084606001518481518110612af457612af4615cde565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060008460200151815260200190815260200160002060006101000a8154816001600160401b0302191690836001600160401b031602179055508080612b6090615c46565b915050612acb565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612c6792600285019290910190614c80565b5050506080810151600a8054600090612c8a9084906001600160601b0316615b56565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612cd69190615b56565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612d1281602001516008613b0e90919063ffffffff16565b50505050565b600e8181548110612d2857600080fd5b600091825260209091200154905081565b81612d43816130b4565b612d4b613115565b6000838152600560205260409020600101546001600160a01b03838116911614610909576000838152600560205260409081902060010180546001600160a01b0319166001600160a01b0385161790555183907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1906127449033908690615700565b6000818152600560205260408120548190819081906060906001600160a01b0316612e0b57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b0390941693918391830182828015612eae57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612e90575b505050505090509450945094509450945091939590929450565b612ed06132f6565b6002546001600160a01b0316612ef95760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612f2a9030906004016156d3565b60206040518083038186803b158015612f4257600080fd5b505afa158015612f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7a91906150ce565b600a549091506001600160601b031681811115612fae5780826040516354ced18160e11b8152600401610f2092919061575d565b81811015610909576000612fc28284615bab565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612ff590879085906004016156e7565b602060405180830381600087803b15801561300f57600080fd5b505af1158015613023573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304791906150b1565b61306457604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b43660084826040516130959291906156e7565b60405180910390a150505050565b6130ab6132f6565b61243081613b30565b6000818152600560205260409020546001600160a01b0316806130ea57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146115ec5780604051636c51fda960e11b8152600401610f2091906156d3565b600c54600160301b900460ff16156131405760405163769dd35360e11b815260040160405180910390fd5b565b60008061314e846136b9565b60025491935091506001600160a01b03161580159061317557506001600160601b03821615155b156132245760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906131b59086906001600160601b038716906004016156e7565b602060405180830381600087803b1580156131cf57600080fd5b505af11580156131e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320791906150b1565b61322457604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d806000811461327a576040519150601f19603f3d011682016040523d82523d6000602084013e61327f565b606091505b50509050806132a15760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4906060016129f2565b6000546001600160a01b031633146131405760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610f20565b604080516060810182526000808252602082018190529181019190915260006133758460000151612751565b6000818152600d602052604090205490915060ff166133aa57604051631dfd6e1360e21b815260048101829052602401610f20565b60008185608001516040516020016133c392919061575d565b60408051601f1981840301815291815281516020928301206000818152600f9093529120549091508061340957604051631b44092560e11b815260040160405180910390fd5b845160208087015160408089015160608a015160808b015160a08c01519351613438978a97909695910161595d565b60405160208183030381529060405280519060200120811461346d5760405163354a450b60e21b815260040160405180910390fd5b600061347c8660000151613bd4565b905080613543578551604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d38916134d091906004016159c8565b60206040518083038186803b1580156134e857600080fd5b505afa1580156134fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352091906150ce565b90508061354357855160405163175dadad60e01b8152610f2091906004016159c8565b6000876080015182604051602001613565929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c9050600061358c8983613cb1565b6040805160608101825297885260208801969096529486019490945250929695505050505050565b60005a6113888110156135c657600080fd5b6113888103905084604082048203116135de57600080fd5b50823b6135ea57600080fd5b60008083516020850160008789f1949350505050565b6000811561362d576011546136269086908690600160201b900463ffffffff1686613d1c565b9050613647565b601154613644908690869063ffffffff1686613dbe565b90505b949350505050565b6000805b6012548110156136b057826001600160a01b03166012828154811061367a5761367a615cde565b6000918252602090912001546001600160a01b0316141561369e5750600192915050565b806136a881615c46565b915050613653565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796879694959486019391929083018282801561374557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613727575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b8260400151518110156138215760046000846040015183815181106137d1576137d1615cde565b6020908102919091018101516001600160a01b031682528181019290925260409081016000908120898252909252902080546001600160401b03191690558061381981615c46565b9150506137aa565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906138596002830182614ce5565b5050600085815260066020526040812055613875600886613ee3565b50600a80548591906000906138949084906001600160601b0316615bc2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b03166138dc9190615bc2565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f19818403018152908290528051602091820120925061396c91899184910161575d565b60408051808303601f19018152919052805160209091012097909650945050505050565b604080516020810190915260008152816139b95750604080516020810190915260008152612530565b63125fa26760e31b6139cb8385615bea565b6001600160e01b031916146139f357604051632923fee760e11b815260040160405180910390fd5b613a008260048186615af2565b810190610ee99190615128565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613a4691511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613a8a81613eef565b15613b075760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613ac957600080fd5b505afa158015613add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0191906150ce565b91505090565b4391505090565b6000610ee98383613f12565b6000612530825490565b6000610ee98383613f61565b6001600160a01b038116331415613b835760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610f20565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613be081613eef565b15613ca257610100836001600160401b0316613bfa613a7e565b613c049190615bab565b1180613c205750613c13613a7e565b836001600160401b031610155b15613c2e5750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613c529086906004016159c8565b60206040518083038186803b158015613c6a57600080fd5b505afa158015613c7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee991906150ce565b50506001600160401b03164090565b6000613ce58360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f8b565b60038360200151604051602001613cfd9291906158a5565b60408051601f1981840301815291905280516020909101209392505050565b600080613d5f6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506141a692505050565b905060005a613d6e8888615b1c565b613d789190615bab565b613d829085615b8c565b90506000613d9b63ffffffff871664e8d4a51000615b8c565b905082613da88284615b1c565b613db29190615b1c565b98975050505050505050565b600080613dc961426b565b905060008113613def576040516321ea67b360e11b815260048101829052602401610f20565b6000613e316000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506141a692505050565b9050600082825a613e428b8b615b1c565b613e4c9190615bab565b613e569088615b8c565b613e609190615b1c565b613e7290670de0b6b3a7640000615b8c565b613e7c9190615b78565b90506000613e9563ffffffff881664e8d4a51000615b8c565b9050613eac81676765c793fa10079d601b1b615bab565b821115613ecc5760405163e80fa38160e01b815260040160405180910390fd5b613ed68183615b1c565b9998505050505050505050565b6000610ee98383614336565b600061a4b1821480613f03575062066eed82145b8061253057505062066eee1490565b6000818152600183016020526040812054613f5957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612530565b506000612530565b6000826000018281548110613f7857613f78615cde565b9060005260206000200154905092915050565b613f9489614429565b613fdd5760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610f20565b613fe688614429565b61402a5760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610f20565b61403383614429565b61407f5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610f20565b61408882614429565b6140d35760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b6044820152606401610f20565b6140df878a88876144ec565b6141275760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610f20565b60006141338a87614600565b90506000614146898b878b868989614664565b90506000614157838d8d8a86614777565b9050808a146141985760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610f20565b505050505050505050505050565b6000466141b281613eef565b156141f157606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c6a57600080fd5b6141fa816147b7565b156136b057600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615d2e60489139604051602001614240929190615629565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613c529190615789565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b1580156142c957600080fd5b505afa1580156142dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143019190615504565b509450909250849150508015614325575061431c8242615bab565b8463ffffffff16105b156136475750601054949350505050565b6000818152600183016020526040812054801561441f57600061435a600183615bab565b855490915060009061436e90600190615bab565b90508181146143d357600086600001828154811061438e5761438e615cde565b90600052602060002001549050808760000184815481106143b1576143b1615cde565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806143e4576143e4615cc8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612530565b6000915050612530565b80516000906401000003d019116144775760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610f20565b60208201516401000003d019116144c55760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610f20565b60208201516401000003d0199080096144e58360005b60200201516147f1565b1492915050565b60006001600160a01b0382166145325760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610f20565b60208401516000906001161561454957601c61454c565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020909101918290529293506001916145b69186918891879061576b565b6020604051602081039080840390855afa1580156145d8573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614608614d03565b61463560018484604051602001614621939291906156b2565b604051602081830303815290604052614815565b90505b61464181614429565b61253057805160408051602081019290925261465d9101614621565b9050614638565b61466c614d03565b825186516401000003d01990819006910614156146cb5760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610f20565b6146d6878988614863565b61471b5760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610f20565b614726848685614863565b61476c5760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610f20565b613db286848461497e565b60006002868686858760405160200161479596959493929190615658565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a8214806147c957506101a482145b806147d6575062aa37dc82145b806147e2575061210582145b8061253057505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b61481d614d03565b61482682614a41565b815261483b6148368260006144db565b614a7c565b602082018190526002900660011415611e1e576020810180516401000003d019039052919050565b6000826148a05760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610f20565b835160208501516000906148b690600290615c88565b156148c257601c6148c5565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1983870960408051600080825260209091019182905291925060019061490890839086908890879061576b565b6020604051602081039080840390855afa15801561492a573d6000803e3d6000fd5b5050506020604051035190506000866040516020016149499190615617565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614986614d03565b8351602080860151855191860151600093849384936149a793909190614a9c565b919450925090506401000003d019858209600114614a035760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610f20565b60405180604001604052806401000003d01980614a2257614a22615cb2565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611e1e57604080516020808201939093528151808203840181529082019091528051910120614a49565b6000612530826002614a956401000003d0196001615b1c565b901c614b7c565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614adc83838585614c13565b9098509050614aed88828e88614c37565b9098509050614afe88828c87614c37565b90985090506000614b118d878b85614c37565b9098509050614b2288828686614c13565b9098509050614b3388828e89614c37565b9098509050818114614b68576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614b6c565b8196505b5050505050509450945094915050565b600080614b87614d21565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614bb9614d3f565b60208160c0846005600019fa925082614c095760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610f20565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614cd5579160200282015b82811115614cd557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614ca0565b50614ce1929150614d5d565b5090565b50805460008255906000526020600020908101906124309190614d5d565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614ce15760008155600101614d5e565b8035611e1e81615d0a565b600082601f830112614d8e57600080fd5b604080519081016001600160401b0381118282101715614db057614db0615cf4565b8060405250808385604086011115614dc757600080fd5b60005b6002811015614de9578135835260209283019290910190600101614dca565b509195945050505050565b8035611e1e81615d1f565b60008083601f840112614e1157600080fd5b5081356001600160401b03811115614e2857600080fd5b602083019150836020828501011115614e4057600080fd5b9250929050565b600082601f830112614e5857600080fd5b81356001600160401b03811115614e7157614e71615cf4565b614e84601f8201601f1916602001615ac2565b818152846020838601011115614e9957600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614ec857600080fd5b614ed0615a77565b905081356001600160401b038082168214614eea57600080fd5b81835260208401356020840152614f0360408501614f69565b6040840152614f1460608501614f69565b6060840152614f2560808501614d72565b608084015260a0840135915080821115614f3e57600080fd5b50614f4b84828501614e47565b60a08301525092915050565b803561ffff81168114611e1e57600080fd5b803563ffffffff81168114611e1e57600080fd5b803560ff81168114611e1e57600080fd5b80516001600160501b0381168114611e1e57600080fd5b80356001600160601b0381168114611e1e57600080fd5b600060208284031215614fce57600080fd5b8135610ee981615d0a565b60008060408385031215614fec57600080fd5b8235614ff781615d0a565b9150602083013561500781615d0a565b809150509250929050565b6000806000806060858703121561502857600080fd5b843561503381615d0a565b93506020850135925060408501356001600160401b0381111561505557600080fd5b61506187828801614dff565b95989497509550505050565b60006040828403121561507f57600080fd5b8260408301111561508f57600080fd5b50919050565b6000604082840312156150a757600080fd5b610ee98383614d7d565b6000602082840312156150c357600080fd5b8151610ee981615d1f565b6000602082840312156150e057600080fd5b5051919050565b600080602083850312156150fa57600080fd5b82356001600160401b0381111561511057600080fd5b61511c85828601614dff565b90969095509350505050565b60006020828403121561513a57600080fd5b604051602081016001600160401b038111828210171561515c5761515c615cf4565b604052823561516a81615d1f565b81529392505050565b60008060008385036101e081121561518a57600080fd5b6101a08082121561519a57600080fd5b6151a2615a9f565b91506151ae8787614d7d565b82526151bd8760408801614d7d565b60208301526080860135604083015260a0860135606083015260c086013560808301526151ec60e08701614d72565b60a083015261010061520088828901614d7d565b60c0840152615213886101408901614d7d565b60e0840152610180870135908301529093508401356001600160401b0381111561523c57600080fd5b61524886828701614eb6565b9250506152586101c08501614df4565b90509250925092565b60006020828403121561527357600080fd5b81356001600160401b0381111561528957600080fd5b820160c08185031215610ee957600080fd5b600060208083850312156152ae57600080fd5b82356001600160401b03808211156152c557600080fd5b9084019060c082870312156152d957600080fd5b6152e1615a77565b6152ea83614f7d565b81528383013584820152604083013561530281615d0a565b604082015260608301358281111561531957600080fd5b8301601f8101881361532a57600080fd5b80358381111561533c5761533c615cf4565b8060051b935061534d868501615ac2565b8181528681019083880186850189018c101561536857600080fd5b600096505b83871015615397578035945061538285615d0a565b8483526001969096019591880191880161536d565b506060850152506153ad91505060808401614fa5565b60808201526153be60a08401614fa5565b60a08201529695505050505050565b6000602082840312156153df57600080fd5b610ee982614f57565b60008060008060008060008060006101208a8c03121561540757600080fd5b6154108a614f57565b985061541e60208b01614f69565b975061542c60408b01614f69565b965061543a60608b01614f69565b955060808a0135945061544f60a08b01614f69565b935061545d60c08b01614f69565b925061546b60e08b01614f7d565b915061547a6101008b01614f7d565b90509295985092959850929598565b60006020828403121561549b57600080fd5b5035919050565b600080604083850312156154b557600080fd5b82359150602083013561500781615d0a565b600080604083850312156154da57600080fd5b50508035926020909101359150565b6000602082840312156154fb57600080fd5b610ee982614f69565b600080600080600060a0868803121561551c57600080fd5b61552586614f8e565b945060208601519350604086015192506060860151915061554860808701614f8e565b90509295509295909350565b600081518084526020808501945080840160005b8381101561558d5781516001600160a01b031687529582019590820190600101615568565b509495945050505050565b8060005b6002811015612d1257815184526020938401939091019060010161559c565b600081518084526020808501945080840160005b8381101561558d578151875295820195908201906001016155cf565b60008151808452615603816020860160208601615c1a565b601f01601f19169290920160200192915050565b6156218183615598565b604001919050565b6000835161563b818460208801615c1a565b83519083019061564f818360208801615c1a565b01949350505050565b8681526156686020820187615598565b6156756060820186615598565b61568260a0820185615598565b61568f60e0820184615598565b60609190911b6001600160601b0319166101208201526101340195945050505050565b8381526156c26020820184615598565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b604081016125308284615598565b602081526000610ee960208301846155bb565b918252602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b602081526000610ee960208301846155eb565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c060808401526157e160e0840182615554565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b61ffff93841681529183166020830152909116604082015260600190565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b8181101561588057845183529383019391830191600101615864565b509098975050505050505050565b9182526001600160a01b0316602082015260400190565b82815260608101610ee96020830184615598565b82815260406020820152600061364760408301846155bb565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a0830152613db260c08301846155eb565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ed6908301846155eb565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ed6908301846155eb565b63ffffffff92831681529116602082015260400190565b6001600160401b0391909116815260200190565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a060808201819052600090615a2690830184615554565b979650505050505050565b6000808335601e19843603018112615a4857600080fd5b8301803591506001600160401b03821115615a6257600080fd5b602001915036819003821315614e4057600080fd5b60405160c081016001600160401b0381118282101715615a9957615a99615cf4565b60405290565b60405161012081016001600160401b0381118282101715615a9957615a99615cf4565b604051601f8201601f191681016001600160401b0381118282101715615aea57615aea615cf4565b604052919050565b60008085851115615b0257600080fd5b83861115615b0f57600080fd5b5050820193919092039150565b60008219821115615b2f57615b2f615c9c565b500190565b60006001600160401b0382811684821680830382111561564f5761564f615c9c565b60006001600160601b0382811684821680830382111561564f5761564f615c9c565b600082615b8757615b87615cb2565b500490565b6000816000190483118215151615615ba657615ba6615c9c565b500290565b600082821015615bbd57615bbd615c9c565b500390565b60006001600160601b0383811690831681811015615be257615be2615c9c565b039392505050565b6001600160e01b03198135818116916004851015615c125780818660040360031b1b83161692505b505092915050565b60005b83811015615c35578181015183820152602001615c1d565b83811115612d125750506000910152565b6000600019821415615c5a57615c5a615c9c565b5060010190565b60006001600160401b0382811680821415615c7e57615c7e615c9c565b6001019392505050565b600082615c9757615c97615cb2565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461243057600080fd5b801515811461243057600080fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162005dec38038062005dec833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615c11620001db600039600081816104f401526133f80152615c116000f3fe6080604052600436106101e05760003560e01c8062012291146101e5578063088070f5146102125780630ae09540146102e057806315c48b841461030257806318e3dd271461032a5780631b6b6d2314610369578063294daa49146103965780632f622e6b146103b2578063301f42e9146103d2578063405b84fa146103f257806340d6bb821461041257806341af6c871461043d57806351cff8d91461046d5780635d06b4ab1461048d57806364d51a2a146104ad57806365982744146104c2578063689c4517146104e257806372e9d5651461051657806379ba5097146105365780637bce14d11461054b5780638402595e1461056b57806386fe91c71461058b5780638da5cb5b146105ab57806395b55cfc146105c95780639b1c385e146105dc5780639d40a6fd1461060a578063a21a23e414610637578063a4c0ed361461064c578063a63e0bfb1461066c578063aa433aff1461068c578063aefb212f146106ac578063b2a7cac5146106d9578063bec4c08c146106f9578063caf70c4a14610719578063cb63179714610739578063ce3f471914610759578063d98e620e1461076c578063dac83d291461078c578063dc311dd3146107ac578063e72f6e30146107dd578063ee9d2d38146107fd578063f2fde38b1461082a575b600080fd5b3480156101f157600080fd5b506101fa61084a565b604051610209939291906156e5565b60405180910390f35b34801561021e57600080fd5b50600c546102839061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610209565b3480156102ec57600080fd5b506103006102fb366004615358565b6108c6565b005b34801561030e57600080fd5b5061031760c881565b60405161ffff9091168152602001610209565b34801561033657600080fd5b50600a5461035190600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610209565b34801561037557600080fd5b50600254610389906001600160a01b031681565b6040516102099190615589565b3480156103a257600080fd5b5060405160028152602001610209565b3480156103be57600080fd5b506103006103cd366004614e72565b61090e565b3480156103de57600080fd5b506103516103ed366004615029565b610a5a565b3480156103fe57600080fd5b5061030061040d366004615358565b610ef0565b34801561041e57600080fd5b506104286101f481565b60405163ffffffff9091168152602001610209565b34801561044957600080fd5b5061045d61045836600461533f565b6112c1565b6040519015158152602001610209565b34801561047957600080fd5b50610300610488366004614e72565b611462565b34801561049957600080fd5b506103006104a8366004614e72565b6115f0565b3480156104b957600080fd5b50610317606481565b3480156104ce57600080fd5b506103006104dd366004614e8f565b6116a7565b3480156104ee57600080fd5b506103897f000000000000000000000000000000000000000000000000000000000000000081565b34801561052257600080fd5b50600354610389906001600160a01b031681565b34801561054257600080fd5b50610300611707565b34801561055757600080fd5b50610300610566366004614f23565b6117b1565b34801561057757600080fd5b50610300610586366004614e72565b6118aa565b34801561059757600080fd5b50600a54610351906001600160601b031681565b3480156105b757600080fd5b506000546001600160a01b0316610389565b6103006105d736600461533f565b6119b6565b3480156105e857600080fd5b506105fc6105f7366004615117565b611ad7565b604051908152602001610209565b34801561061657600080fd5b5060075461062a906001600160401b031681565b604051610209919061587e565b34801561064357600080fd5b506105fc611e23565b34801561065857600080fd5b50610300610667366004614ec8565b611ff6565b34801561067857600080fd5b5061030061068736600461529e565b612170565b34801561069857600080fd5b506103006106a736600461533f565b612379565b3480156106b857600080fd5b506106cc6106c736600461537d565b6123c1565b6040516102099190615600565b3480156106e557600080fd5b506103006106f436600461533f565b6124c3565b34801561070557600080fd5b50610300610714366004615358565b6125b8565b34801561072557600080fd5b506105fc610734366004614f4b565b6126c4565b34801561074557600080fd5b50610300610754366004615358565b6126f4565b610300610767366004614f9d565b612965565b34801561077857600080fd5b506105fc61078736600461533f565b612c7c565b34801561079857600080fd5b506103006107a7366004615358565b612c9d565b3480156107b857600080fd5b506107cc6107c736600461533f565b612d33565b604051610209959493929190615892565b3480156107e957600080fd5b506103006107f8366004614e72565b612e21565b34801561080957600080fd5b506105fc61081836600461533f565b600f6020526000908152604090205481565b34801561083657600080fd5b50610300610845366004614e72565b612ffc565b600c54600e805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff169391928391908301828280156108b457602002820191906000526020600020905b8154815260200190600101908083116108a0575b50505050509050925092509250909192565b816108d081613010565b6108d8613071565b6108e1836112c1565b156108ff57604051631685ecdd60e31b815260040160405180910390fd5b610909838361309e565b505050565b610916613071565b61091e613252565b600b54600160601b90046001600160601b031661094e57604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c6109718380615a78565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b03166109b99190615a78565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610a33576040519150601f19603f3d011682016040523d82523d6000602084013e610a38565b606091505b50509050806109095760405163950b247960e01b815260040160405180910390fd5b6000610a64613071565b60005a90506000610a7586866132a5565b90506000856060015163ffffffff166001600160401b03811115610a9b57610a9b615b83565b604051908082528060200260200182016040528015610ac4578160200160208202803683370190505b50905060005b866060015163ffffffff16811015610b3b57826040015181604051602001610af3929190615613565b6040516020818303038152906040528051906020012060001c828281518110610b1e57610b1e615b6d565b602090810291909101015280610b3381615afc565b915050610aca565b50602080830180516000908152600f9092526040808320839055905190518291631fe543e360e01b91610b739190869060240161576f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559089015160808a0151919250600091610bd89163ffffffff169084613510565b600c805460ff60301b1916905560208a810151600090815260069091526040902054909150600160c01b90046001600160401b0316610c188160016159ea565b6020808c0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08b01518051610c6590600190615a61565b81518110610c7557610c75615b6d565b602091010151600c5460f89190911c6001149150600090610ca6908a90600160581b900463ffffffff163a8561355c565b90508115610d9e576020808d01516000908152600690915260409020546001600160601b03808316600160601b909204161015610cf657604051631e9acf1760e31b815260040160405180910390fd5b60208c81015160009081526006909152604090208054829190600c90610d2d908490600160601b90046001600160601b0316615a78565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b600c8282829054906101000a90046001600160601b0316610d759190615a0c565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610e79565b6020808d01516000908152600690915260409020546001600160601b0380831691161015610ddf57604051631e9acf1760e31b815260040160405180910390fd5b6020808d015160009081526006909152604081208054839290610e0c9084906001600160601b0316615a78565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b60008282829054906101000a90046001600160601b0316610e549190615a0c565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8b6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051610ed6939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b9392505050565b610ef8613071565b610f01816135ab565b610f295780604051635428d44960e01b8152600401610f209190615589565b60405180910390fd5b600080600080610f3886612d33565b945094505093509350336001600160a01b0316826001600160a01b031614610f9b5760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610f20565b610fa4866112c1565b15610fea5760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610f20565b60006040518060c00160405280610fff600290565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016110539190615652565b604051602081830303815290604052905061106d88613615565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906110a690859060040161563f565b6000604051808303818588803b1580156110bf57600080fd5b505af11580156110d3573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506110fc905057506001600160601b03861615155b156111c65760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611133908a908a906004016155d0565b602060405180830381600087803b15801561114d57600080fd5b505af1158015611161573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111859190614f67565b6111c65760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610f20565b600c805460ff60301b1916600160301b17905560005b835181101561126f578381815181106111f7576111f7615b6d565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b815260040161122a9190615589565b600060405180830381600087803b15801561124457600080fd5b505af1158015611258573d6000803e3d6000fd5b50505050808061126790615afc565b9150506111dc565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906112af9089908b9061559d565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561134b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161132d575b505050505081525050905060005b8160400151518110156114585760005b600e5481101561144557600061140e600e838154811061138b5761138b615b6d565b9060005260206000200154856040015185815181106113ac576113ac615b6d565b60200260200101518860046000896040015189815181106113cf576113cf615b6d565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d82529092529020546001600160401b03166137bd565b506000818152600f6020526040902054909150156114325750600195945050505050565b508061143d81615afc565b915050611369565b508061145081615afc565b915050611359565b5060009392505050565b61146a613071565b611472613252565b6002546001600160a01b031661149b5760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166114c457604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006114e08380615a78565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166115289190615a78565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061157d90859085906004016155d0565b602060405180830381600087803b15801561159757600080fd5b505af11580156115ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cf9190614f67565b6115ec57604051631e9acf1760e31b815260040160405180910390fd5b5050565b6115f8613252565b611601816135ab565b15611621578060405163ac8a27ef60e01b8152600401610f209190615589565b601280546001810182556000919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259061169c908390615589565b60405180910390a150565b6116af613252565b6002546001600160a01b0316156116d957604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b0316331461175a5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610f20565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6117b9613252565b6040805180820182526000916117e89190849060029083908390808284376000920191909152506126c4915050565b6000818152600d602052604090205490915060ff161561181e57604051634a0b8fa760e01b815260048101829052602401610f20565b6000818152600d6020526040808220805460ff19166001908117909155600e805491820181559092527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd909101829055517fc9583fd3afa3d7f16eb0b88d0268e7d05c09bafa4b21e092cbd1320e1bc8089d9061189e9083815260200190565b60405180910390a15050565b6118b2613252565b600a544790600160601b90046001600160601b0316818111156118ec5780826040516354ced18160e11b8152600401610f20929190615613565b818110156109095760006119008284615a61565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461194f576040519150601f19603f3d011682016040523d82523d6000602084013e611954565b606091505b50509050806119765760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c85836040516119a792919061559d565b60405180910390a15050505050565b6119be613071565b6000818152600560205260409020546001600160a01b03166119f357604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611a228385615a0c565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611a6a9190615a0c565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611abd91906159d2565b604051611acb929190615613565b60405180910390a25050565b6000611ae1613071565b6020808301356000908152600590915260409020546001600160a01b0316611b1c57604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611b69578260200135336040516379bfd40160e01b8152600401610f20929190615744565b600c5461ffff16611b806060850160408601615283565b61ffff161080611ba3575060c8611b9d6060850160408601615283565b61ffff16115b15611bdd57611bb86060840160408501615283565b600c5460405163539c34bb60e11b8152610f20929161ffff169060c8906004016156c7565b600c5462010000900463ffffffff16611bfc608085016060860161539f565b63ffffffff161115611c4257611c18608084016060850161539f565b600c54604051637aebf00f60e11b8152610f20929162010000900463ffffffff1690600401615867565b6101f4611c5560a085016080860161539f565b63ffffffff161115611c8f57611c7160a084016080850161539f565b6101f46040516311ce1afb60e21b8152600401610f20929190615867565b6000611c9c8260016159ea565b9050600080611cb28635336020890135866137bd565b90925090506000611cce611cc960a08901896158e7565b613846565b90506000611cdb826138c3565b905083611ce6613934565b60208a0135611cfb60808c0160608d0161539f565b611d0b60a08d0160808e0161539f565b3386604051602001611d2397969594939291906157c7565b60405160208183030381529060405280519060200120600f600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611d9a9190615283565b8e6060016020810190611dad919061539f565b8f6080016020810190611dc0919061539f565b89604051611dd396959493929190615788565b60405180910390a45050336000908152600460209081526040808320898301358452909152902080546001600160401b0319166001600160401b039490941693909317909255925050505b919050565b6000611e2d613071565b6007546001600160401b031633611e45600143615a61565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611eaa8160016159ea565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b039283161783559351600183018054909516911617909255925180519294939192611fa89260028501920190614b36565b50611fb8915060089050846139c4565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d33604051611fe99190615589565b60405180910390a2505090565b611ffe613071565b6002546001600160a01b03163314612029576040516344b0e3c360e01b815260040160405180910390fd5b6020811461204a57604051638129bbcd60e01b815260040160405180910390fd5b60006120588284018461533f565b6000818152600560205260409020549091506001600160a01b031661209057604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906120b78385615a0c565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166120ff9190615a0c565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a82878461215291906159d2565b604051612160929190615613565b60405180910390a2505050505050565b612178613252565b60c861ffff8a1611156121a557888960c860405163539c34bb60e11b8152600401610f20939291906156c7565b600085136121c9576040516321ea67b360e11b815260048101869052602401610f20565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b90990298909816600160781b600160b81b0319600160581b90960263ffffffff60581b19600160381b90980297909716600160301b600160781b03196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f95cb2ddab6d2297c29a4861691de69b3969c464aa4a9c44258b101ff02ff375a90612366908b908b908b908b908b908990899061ffff97909716875263ffffffff95861660208801529385166040870152919093166060850152608084019290925260ff91821660a08401521660c082015260e00190565b60405180910390a1505050505050505050565b612381613252565b6000818152600560205260409020546001600160a01b0316806123b757604051630fb532db60e11b815260040160405180910390fd5b6115ec828261309e565b606060006123cf60086139d0565b90508084106123f157604051631390f2a160e01b815260040160405180910390fd5b60006123fd84866159d2565b90508181118061240b575083155b6124155780612417565b815b905060006124258683615a61565b9050806001600160401b0381111561243f5761243f615b83565b604051908082528060200260200182016040528015612468578160200160208202803683370190505b50935060005b818110156124b85761248b61248388836159d2565b6008906139da565b85828151811061249d5761249d615b6d565b60209081029190910101526124b181615afc565b905061246e565b505050505b92915050565b6124cb613071565b6000818152600560205260409020546001600160a01b03168061250157604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b03163314612558576000828152600560205260409081902060010154905163d084e97560e01b8152610f20916001600160a01b031690600401615589565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611acb9185916155b6565b816125c281613010565b6125ca613071565b60008381526005602052604090206002018054606414156125fe576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b038316600090815260046020908152604080832087845291829052909120546001600160401b031615612639575050505050565b600085815260208281526040808320805460016001600160401b0319909116811790915585549081018655858452919092200180546001600160a01b0319166001600160a01b0387161790555185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1906126b5908790615589565b60405180910390a25050505050565b6000816040516020016126d791906155f2565b604051602081830303815290604052805190602001209050919050565b816126fe81613010565b612706613071565b61270f836112c1565b1561272d57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b031661277b5782826040516379bfd40160e01b8152600401610f20929190615744565b6000838152600560209081526040808320600201805482518185028101850190935280835291929091908301828280156127de57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116127c0575b505050505090506000600182516127f59190615a61565b905060005b825181101561290157846001600160a01b031683828151811061281f5761281f615b6d565b60200260200101516001600160a01b031614156128ef57600083838151811061284a5761284a615b6d565b602002602001015190508060056000898152602001908152602001600020600201838154811061287c5761287c615b6d565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558881526005909152604090206002018054806128c7576128c7615b57565b600082815260209020810160001990810180546001600160a01b031916905501905550612901565b806128f981615afc565b9150506127fa565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160401b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7906126b5908790615589565b600061297382840184615151565b9050806000015160ff166001146129ac57805160405163237d181f60e21b815260ff909116600482015260016024820152604401610f20565b8060a001516001600160601b031634146129f05760a08101516040516306acf13560e41b81523460048201526001600160601b039091166024820152604401610f20565b6020808201516000908152600590915260409020546001600160a01b031615612a2c576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612acc5760016004600084606001518481518110612a5857612a58615b6d565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060008460200151815260200190815260200160002060006101000a8154816001600160401b0302191690836001600160401b031602179055508080612ac490615afc565b915050612a2f565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612bcb92600285019290910190614b36565b5050506080810151600a8054600090612bee9084906001600160601b0316615a0c565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612c3a9190615a0c565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612c76816020015160086139c490919063ffffffff16565b50505050565b600e8181548110612c8c57600080fd5b600091825260209091200154905081565b81612ca781613010565b612caf613071565b600083815260056020526040902060018101546001600160a01b03848116911614612c76576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612d2590339087906155b6565b60405180910390a250505050565b600081815260056020526040812054819081906001600160a01b0316606081612d6f57604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612e0757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612de9575b505050505090509450945094509450945091939590929450565b612e29613252565b6002546001600160a01b0316612e525760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612e83903090600401615589565b60206040518083038186803b158015612e9b57600080fd5b505afa158015612eaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed39190614f84565b600a549091506001600160601b031681811115612f075780826040516354ced18160e11b8152600401610f20929190615613565b81811015610909576000612f1b8284615a61565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612f4e908790859060040161559d565b602060405180830381600087803b158015612f6857600080fd5b505af1158015612f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa09190614f67565b612fbd57604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366008482604051612fee92919061559d565b60405180910390a150505050565b613004613252565b61300d816139e6565b50565b6000818152600560205260409020546001600160a01b03168061304657604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146115ec5780604051636c51fda960e11b8152600401610f209190615589565b600c54600160301b900460ff161561309c5760405163769dd35360e11b815260040160405180910390fd5b565b6000806130aa84613615565b60025491935091506001600160a01b0316158015906130d157506001600160601b03821615155b156131805760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906131119086906001600160601b0387169060040161559d565b602060405180830381600087803b15801561312b57600080fd5b505af115801561313f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131639190614f67565b61318057604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d80600081146131d6576040519150601f19603f3d011682016040523d82523d6000602084013e6131db565b606091505b50509050806131fd5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4906060016126b5565b6000546001600160a01b0316331461309c5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610f20565b604080516060810182526000808252602082018190529181019190915260006132d184600001516126c4565b6000818152600d602052604090205490915060ff1661330657604051631dfd6e1360e21b815260048101829052602401610f20565b600081856080015160405160200161331f929190615613565b60408051601f1981840301815291815281516020928301206000818152600f9093529120549091508061336557604051631b44092560e11b815260040160405180910390fd5b845160208087015160408089015160608a015160808b015160a08c01519351613394978a979096959101615813565b6040516020818303038152906040528051906020012081146133c95760405163354a450b60e21b815260040160405180910390fd5b60006133d88660000151613a8a565b90508061349f578551604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d389161342c919060040161587e565b60206040518083038186803b15801561344457600080fd5b505afa158015613458573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347c9190614f84565b90508061349f57855160405163175dadad60e01b8152610f20919060040161587e565b60008760800151826040516020016134c1929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006134e88983613b67565b6040805160608101825297885260208801969096529486019490945250929695505050505050565b60005a61138881101561352257600080fd5b61138881039050846040820482031161353a57600080fd5b50823b61354657600080fd5b60008083516020850160008789f1949350505050565b60008115613589576011546135829086908690600160201b900463ffffffff1686613bd2565b90506135a3565b6011546135a0908690869063ffffffff1686613c74565b90505b949350505050565b6000805b60125481101561360c57826001600160a01b0316601282815481106135d6576135d6615b6d565b6000918252602090912001546001600160a01b031614156135fa5750600192915050565b8061360481615afc565b9150506135af565b50600092915050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b818110156136b7576004600084838154811061366a5761366a615b6d565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160401b03191690556136b081615afc565b905061364c565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906136ef6002830182614b9b565b505060008581526006602052604081205561370b600886613d99565b506001600160601b0384161561375e57600a80548591906000906137399084906001600160601b0316615a78565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156137b65782600a600c8282829054906101000a90046001600160601b03166137919190615a78565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f198184030181529082905280516020918201209250613822918991849101615613565b60408051808303601f19018152919052805160209091012097909650945050505050565b6040805160208101909152600081528161386f57506040805160208101909152600081526124bd565b63125fa26760e31b6138818385615aa0565b6001600160e01b031916146138a957604051632923fee760e11b815260040160405180910390fd5b6138b682600481866159a8565b810190610ee99190614fde565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016138fc91511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661394081613da5565b156139bd5760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561397f57600080fd5b505afa158015613993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139b79190614f84565b91505090565b4391505090565b6000610ee98383613dc8565b60006124bd825490565b6000610ee98383613e17565b6001600160a01b038116331415613a395760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610f20565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613a9681613da5565b15613b5857610100836001600160401b0316613ab0613934565b613aba9190615a61565b1180613ad65750613ac9613934565b836001600160401b031610155b15613ae45750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613b0890869060040161587e565b60206040518083038186803b158015613b2057600080fd5b505afa158015613b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee99190614f84565b50506001600160401b03164090565b6000613b9b8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613e41565b60038360200151604051602001613bb392919061575b565b60408051601f1981840301815291905280516020909101209392505050565b600080613c156000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061405c92505050565b905060005a613c2488886159d2565b613c2e9190615a61565b613c389085615a42565b90506000613c5163ffffffff871664e8d4a51000615a42565b905082613c5e82846159d2565b613c6891906159d2565b98975050505050505050565b600080613c7f614121565b905060008113613ca5576040516321ea67b360e11b815260048101829052602401610f20565b6000613ce76000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061405c92505050565b9050600082825a613cf88b8b6159d2565b613d029190615a61565b613d0c9088615a42565b613d1691906159d2565b613d2890670de0b6b3a7640000615a42565b613d329190615a2e565b90506000613d4b63ffffffff881664e8d4a51000615a42565b9050613d6281676765c793fa10079d601b1b615a61565b821115613d825760405163e80fa38160e01b815260040160405180910390fd5b613d8c81836159d2565b9998505050505050505050565b6000610ee983836141ec565b600061a4b1821480613db9575062066eed82145b806124bd57505062066eee1490565b6000818152600183016020526040812054613e0f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556124bd565b5060006124bd565b6000826000018281548110613e2e57613e2e615b6d565b9060005260206000200154905092915050565b613e4a896142df565b613e935760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610f20565b613e9c886142df565b613ee05760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610f20565b613ee9836142df565b613f355760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610f20565b613f3e826142df565b613f895760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b6044820152606401610f20565b613f95878a88876143a2565b613fdd5760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610f20565b6000613fe98a876144b6565b90506000613ffc898b878b86898961451a565b9050600061400d838d8d8a8661462d565b9050808a1461404e5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610f20565b505050505050505050505050565b60004661406881613da5565b156140a757606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613b2057600080fd5b6140b08161466d565b1561360c57600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615bbd604891396040516020016140f69291906154df565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613b08919061563f565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561417f57600080fd5b505afa158015614193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141b791906153ba565b5094509092508491505080156141db57506141d28242615a61565b8463ffffffff16105b156135a35750601054949350505050565b600081815260018301602052604081205480156142d5576000614210600183615a61565b855490915060009061422490600190615a61565b905081811461428957600086600001828154811061424457614244615b6d565b906000526020600020015490508087600001848154811061426757614267615b6d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061429a5761429a615b57565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506124bd565b60009150506124bd565b80516000906401000003d0191161432d5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610f20565b60208201516401000003d0191161437b5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610f20565b60208201516401000003d01990800961439b8360005b60200201516146a7565b1492915050565b60006001600160a01b0382166143e85760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610f20565b6020840151600090600116156143ff57601c614402565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe199182039250600091908909875160408051600080825260209091019182905292935060019161446c91869188918790615621565b6020604051602081039080840390855afa15801561448e573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b6144be614bb9565b6144eb600184846040516020016144d793929190615568565b6040516020818303038152906040526146cb565b90505b6144f7816142df565b6124bd57805160408051602081019290925261451391016144d7565b90506144ee565b614522614bb9565b825186516401000003d01990819006910614156145815760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610f20565b61458c878988614719565b6145d15760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610f20565b6145dc848685614719565b6146225760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610f20565b613c68868484614834565b60006002868686858760405160200161464b9695949392919061550e565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a82148061467f57506101a482145b8061468c575062aa37dc82145b80614698575061210582145b806124bd57505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b6146d3614bb9565b6146dc826148f7565b81526146f16146ec826000614391565b614932565b602082018190526002900660011415611e1e576020810180516401000003d019039052919050565b6000826147565760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610f20565b8351602085015160009061476c90600290615b17565b1561477857601c61477b565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020909101918290529192506001906147be908390869088908790615621565b6020604051602081039080840390855afa1580156147e0573d6000803e3d6000fd5b5050506020604051035190506000866040516020016147ff91906154cd565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b61483c614bb9565b83516020808601518551918601516000938493849361485d93909190614952565b919450925090506401000003d0198582096001146148b95760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610f20565b60405180604001604052806401000003d019806148d8576148d8615b41565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611e1e576040805160208082019390935281518082038401815290820190915280519101206148ff565b60006124bd82600261494b6401000003d01960016159d2565b901c614a32565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a089050600061499283838585614ac9565b90985090506149a388828e88614aed565b90985090506149b488828c87614aed565b909850905060006149c78d878b85614aed565b90985090506149d888828686614ac9565b90985090506149e988828e89614aed565b9098509050818114614a1e576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614a22565b8196505b5050505050509450945094915050565b600080614a3d614bd7565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614a6f614bf5565b60208160c0846005600019fa925082614abf5760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610f20565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614b8b579160200282015b82811115614b8b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614b56565b50614b97929150614c13565b5090565b508054600082559060005260206000209081019061300d9190614c13565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614b975760008155600101614c14565b8035611e1e81615b99565b600082601f830112614c4457600080fd5b604080519081016001600160401b0381118282101715614c6657614c66615b83565b8060405250808385604086011115614c7d57600080fd5b60005b6002811015614c9f578135835260209283019290910190600101614c80565b509195945050505050565b8035611e1e81615bae565b60008083601f840112614cc757600080fd5b5081356001600160401b03811115614cde57600080fd5b602083019150836020828501011115614cf657600080fd5b9250929050565b600082601f830112614d0e57600080fd5b81356001600160401b03811115614d2757614d27615b83565b614d3a601f8201601f1916602001615978565b818152846020838601011115614d4f57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614d7e57600080fd5b614d8661592d565b905081356001600160401b038082168214614da057600080fd5b81835260208401356020840152614db960408501614e1f565b6040840152614dca60608501614e1f565b6060840152614ddb60808501614c28565b608084015260a0840135915080821115614df457600080fd5b50614e0184828501614cfd565b60a08301525092915050565b803561ffff81168114611e1e57600080fd5b803563ffffffff81168114611e1e57600080fd5b803560ff81168114611e1e57600080fd5b80516001600160501b0381168114611e1e57600080fd5b80356001600160601b0381168114611e1e57600080fd5b600060208284031215614e8457600080fd5b8135610ee981615b99565b60008060408385031215614ea257600080fd5b8235614ead81615b99565b91506020830135614ebd81615b99565b809150509250929050565b60008060008060608587031215614ede57600080fd5b8435614ee981615b99565b93506020850135925060408501356001600160401b03811115614f0b57600080fd5b614f1787828801614cb5565b95989497509550505050565b600060408284031215614f3557600080fd5b82604083011115614f4557600080fd5b50919050565b600060408284031215614f5d57600080fd5b610ee98383614c33565b600060208284031215614f7957600080fd5b8151610ee981615bae565b600060208284031215614f9657600080fd5b5051919050565b60008060208385031215614fb057600080fd5b82356001600160401b03811115614fc657600080fd5b614fd285828601614cb5565b90969095509350505050565b600060208284031215614ff057600080fd5b604051602081016001600160401b038111828210171561501257615012615b83565b604052823561502081615bae565b81529392505050565b60008060008385036101e081121561504057600080fd5b6101a08082121561505057600080fd5b615058615955565b91506150648787614c33565b82526150738760408801614c33565b60208301526080860135604083015260a0860135606083015260c086013560808301526150a260e08701614c28565b60a08301526101006150b688828901614c33565b60c08401526150c9886101408901614c33565b60e0840152610180870135908301529093508401356001600160401b038111156150f257600080fd5b6150fe86828701614d6c565b92505061510e6101c08501614caa565b90509250925092565b60006020828403121561512957600080fd5b81356001600160401b0381111561513f57600080fd5b820160c08185031215610ee957600080fd5b6000602080838503121561516457600080fd5b82356001600160401b038082111561517b57600080fd5b9084019060c0828703121561518f57600080fd5b61519761592d565b6151a083614e33565b8152838301358482015260408301356151b881615b99565b60408201526060830135828111156151cf57600080fd5b8301601f810188136151e057600080fd5b8035838111156151f2576151f2615b83565b8060051b9350615203868501615978565b8181528681019083880186850189018c101561521e57600080fd5b600096505b8387101561524d578035945061523885615b99565b84835260019690960195918801918801615223565b5060608501525061526391505060808401614e5b565b608082015261527460a08401614e5b565b60a08201529695505050505050565b60006020828403121561529557600080fd5b610ee982614e0d565b60008060008060008060008060006101208a8c0312156152bd57600080fd5b6152c68a614e0d565b98506152d460208b01614e1f565b97506152e260408b01614e1f565b96506152f060608b01614e1f565b955060808a0135945061530560a08b01614e1f565b935061531360c08b01614e1f565b925061532160e08b01614e33565b91506153306101008b01614e33565b90509295985092959850929598565b60006020828403121561535157600080fd5b5035919050565b6000806040838503121561536b57600080fd5b823591506020830135614ebd81615b99565b6000806040838503121561539057600080fd5b50508035926020909101359150565b6000602082840312156153b157600080fd5b610ee982614e1f565b600080600080600060a086880312156153d257600080fd5b6153db86614e44565b94506020860151935060408601519250606086015191506153fe60808701614e44565b90509295509295909350565b600081518084526020808501945080840160005b838110156154435781516001600160a01b03168752958201959082019060010161541e565b509495945050505050565b8060005b6002811015612c76578151845260209384019390910190600101615452565b600081518084526020808501945080840160005b8381101561544357815187529582019590820190600101615485565b600081518084526154b9816020860160208601615ad0565b601f01601f19169290920160200192915050565b6154d7818361544e565b604001919050565b600083516154f1818460208801615ad0565b835190830190615505818360208801615ad0565b01949350505050565b86815261551e602082018761544e565b61552b606082018661544e565b61553860a082018561544e565b61554560e082018461544e565b60609190911b6001600160601b0319166101208201526101340195945050505050565b838152615578602082018461544e565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b604081016124bd828461544e565b602081526000610ee96020830184615471565b918252602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b602081526000610ee960208301846154a1565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261569760e084018261540a565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b61ffff93841681529183166020830152909116604082015260600190565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b818110156157365784518352938301939183019160010161571a565b509098975050505050505050565b9182526001600160a01b0316602082015260400190565b82815260608101610ee9602083018461544e565b8281526040602082015260006135a36040830184615471565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a0830152613c6860c08301846154a1565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613d8c908301846154a1565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613d8c908301846154a1565b63ffffffff92831681529116602082015260400190565b6001600160401b0391909116815260200190565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a0608082018190526000906158dc9083018461540a565b979650505050505050565b6000808335601e198436030181126158fe57600080fd5b8301803591506001600160401b0382111561591857600080fd5b602001915036819003821315614cf657600080fd5b60405160c081016001600160401b038111828210171561594f5761594f615b83565b60405290565b60405161012081016001600160401b038111828210171561594f5761594f615b83565b604051601f8201601f191681016001600160401b03811182821017156159a0576159a0615b83565b604052919050565b600080858511156159b857600080fd5b838611156159c557600080fd5b5050820193919092039150565b600082198211156159e5576159e5615b2b565b500190565b60006001600160401b0382811684821680830382111561550557615505615b2b565b60006001600160601b0382811684821680830382111561550557615505615b2b565b600082615a3d57615a3d615b41565b500490565b6000816000190483118215151615615a5c57615a5c615b2b565b500290565b600082821015615a7357615a73615b2b565b500390565b60006001600160601b0383811690831681811015615a9857615a98615b2b565b039392505050565b6001600160e01b03198135818116916004851015615ac85780818660040360031b1b83161692505b505092915050565b60005b83811015615aeb578181015183820152602001615ad3565b83811115612c765750506000910152565b6000600019821415615b1057615b10615b2b565b5060010190565b600082615b2657615b26615b41565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461300d57600080fd5b801515811461300d57600080fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000806000a", } var VRFCoordinatorV2PlusUpgradedVersionABI = VRFCoordinatorV2PlusUpgradedVersionMetaData.ABI diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 2a3cab65636..0e7743a661a 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -83,7 +83,7 @@ vrf_consumer_v2_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2Up vrf_coordinator_mock: ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.bin 5c495cf8df1f46d8736b9150cdf174cce358cb8352f60f0d5bb9581e23920501 vrf_coordinator_test_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.bin eaefd785c38bac67fb11a7fc2737ab2da68c988ca170e7db8ff235c80893e01c vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.bin 295f35ce282060317dfd01f45959f5a2b05ba26913e422fbd4fb6bf90b107006 -vrf_coordinator_v2_5: ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.bin 12525cb6921e9e89a50676f9bfb627d91c89ba94d4217ca8968abb8a5416786e +vrf_coordinator_v2_5: ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.bin aa5875f42461b4f128483ee0fd8b1f1b72a395ee857e6153197e92bcb21d149f vrf_coordinator_v2_plus_v2_example: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example/VRFCoordinatorV2Plus_V2Example.bin 4a5b86701983b1b65f0a8dfa116b3f6d75f8f706fa274004b57bdf5992e4cec3 vrf_coordinator_v2plus_interface: ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal/IVRFCoordinatorV2PlusInternal.abi ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal/IVRFCoordinatorV2PlusInternal.bin 86b8e23aab28c5b98e3d2384dc4f702b093e382dc985c88101278e6e4bf6f7b8 vrf_external_sub_owner_example: ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample/VRFExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample/VRFExternalSubOwnerExample.bin 14f888eb313930b50233a6f01ea31eba0206b7f41a41f6311670da8bb8a26963 @@ -102,7 +102,7 @@ vrf_v2_consumer_wrapper: ../../contracts/solc/v0.8.6/VRFv2Consumer/VRFv2Consumer vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.bin 0a89cb7ed9dfb42f91e559b03dc351ccdbe14d281a7ab71c63bd3f47eeed7711 vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.bin 6226d05afa1664033b182bfbdde11d5dfb1d4c8e3eb0bd0448c8bfb76f5b96e4 vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.bin 7541f986571b8a5671a256edc27ae9b8df9bcdff45ac3b96e5609bbfcc320e4e -vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin 6e5c249189ad4f8f0bf0c76424dede22f9e4f70c1b9af4ad1c89f2afc202438c +vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin 09e4186c64cdaf1e5d36405467fb86996d7e4177cb08ecec425a4352d4246140 vrfv2_proxy_admin: ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin/VRFV2ProxyAdmin.abi ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin/VRFV2ProxyAdmin.bin 402b1103087ffe1aa598854a8f8b38f8cd3de2e3aaa86369e28017a9157f4980 vrfv2_reverting_example: ../../contracts/solc/v0.8.6/VRFV2RevertingExample/VRFV2RevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2RevertingExample/VRFV2RevertingExample.bin 1ae46f80351d428bd85ba58b9041b2a608a1845300d79a8fed83edf96606de87 vrfv2_transparent_upgradeable_proxy: ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy/VRFV2TransparentUpgradeableProxy.abi ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy/VRFV2TransparentUpgradeableProxy.bin fe1a8e6852fbd06d91f64315c5cede86d340891f5b5cc981fb5b86563f7eac3f From 9a687b043e7968620d9af50bff9176c458b377c3 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 14 Feb 2024 09:11:39 -0500 Subject: [PATCH 26/98] AUTO-8804: create chain specific modules for l1 gas calculations (#11896) * AUTO-8804: added a chain specific module for automation * add modules * create specific modules for different chains * implement modules * addressed some feedbacks * update tests * generate wrappers * fix foundry * run yarn prettier:write * remove unnecessary import * remove unnecessary checks * update gas overheads to pass tests * regen wrappers * fix sonarcube issues * address some comments * adjust gas overheads * prettier * remove only * adjust gas overhead again * dont use const * rebase to latest and add chainmodule getter --------- Co-authored-by: lei shi Co-authored-by: Akshay Aggarwal --- .../automation/dev/chains/ArbitrumModule.sol | 39 ++++ .../automation/dev/chains/ChainModuleBase.sol | 25 +++ .../automation/dev/chains/OptimismModule.sol | 26 +++ .../automation/dev/chains/ScrollModule.sol | 29 +++ .../v2_2/IAutomationRegistryMaster.sol | 9 +- .../dev/interfaces/v2_2/IChainModule.sol | 19 ++ .../dev/test/AutomationRegistry2_2.t.sol | 34 ++- .../dev/v2_2/AutomationRegistry2_2.sol | 26 +-- .../dev/v2_2/AutomationRegistryBase2_2.sol | 119 +++-------- .../dev/v2_2/AutomationRegistryLogicA2_2.sol | 5 +- .../dev/v2_2/AutomationRegistryLogicB2_2.sol | 27 ++- contracts/src/v0.8/tests/MockChainModule.sol | 28 +++ .../L2/predeploys/IScrollL1GasPriceOracle.sol | 55 +++++ .../automation/AutomationRegistry2_2.test.ts | 120 +++++++---- contracts/test/v0.8/automation/helpers.ts | 10 +- .../automation_utils_2_2.go | 5 +- .../i_keeper_registry_master_wrapper_2_2.go | 194 ++++++++++++++--- .../keeper_registry_logic_a_wrapper_2_2.go | 133 +++++++++++- .../keeper_registry_logic_b_wrapper_2_2.go | 199 +++++++++++++++--- .../keeper_registry_wrapper_2_2.go | 134 +++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 10 +- 21 files changed, 1002 insertions(+), 244 deletions(-) create mode 100644 contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol create mode 100644 contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol create mode 100644 contracts/src/v0.8/automation/dev/chains/OptimismModule.sol create mode 100644 contracts/src/v0.8/automation/dev/chains/ScrollModule.sol create mode 100644 contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol create mode 100644 contracts/src/v0.8/tests/MockChainModule.sol create mode 100644 contracts/src/v0.8/vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol diff --git a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol new file mode 100644 index 00000000000..62e9ff9ea1c --- /dev/null +++ b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbGasInfo} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; +import {ChainModuleBase} from "./ChainModuleBase.sol"; + +contract ArbitrumModule is ChainModuleBase { + /// @dev ARB_SYS_ADDR is the address of the ArbSys precompile on Arbitrum. + /// @dev reference: https://github.com/OffchainLabs/nitro/blob/v2.0.14/contracts/src/precompiles/ArbSys.sol#L10 + address private constant ARB_SYS_ADDR = 0x0000000000000000000000000000000000000064; + ArbSys private constant ARB_SYS = ArbSys(ARB_SYS_ADDR); + + /// @dev ARB_GAS_ADDR is the address of the ArbGasInfo precompile on Arbitrum. + /// @dev reference: https://github.com/OffchainLabs/nitro/blob/v2.0.14/contracts/src/precompiles/ArbGasInfo.sol#L10 + address private constant ARB_GAS_ADDR = 0x000000000000000000000000000000000000006C; + ArbGasInfo private constant ARB_GAS = ArbGasInfo(ARB_GAS_ADDR); + + function blockHash(uint256 n) external view override returns (bytes32) { + uint256 blockNum = ARB_SYS.arbBlockNumber(); + if (n >= blockNum || blockNum - n > 256) { + return ""; + } + return ARB_SYS.arbBlockHash(n); + } + + function blockNumber() external view override returns (uint256) { + return ARB_SYS.arbBlockNumber(); + } + + function getCurrentL1Fee() external view override returns (uint256) { + return ARB_GAS.getCurrentTxL1GasFees(); + } + + function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { + (, uint256 perL1CalldataUnit, , , , ) = ARB_GAS.getPricesInWei(); + return perL1CalldataUnit * dataSize * 16; + } +} diff --git a/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol b/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol new file mode 100644 index 00000000000..f8685e651f4 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {IChainModule} from "../interfaces/v2_2/IChainModule.sol"; + +contract ChainModuleBase is IChainModule { + function blockNumber() external view virtual returns (uint256) { + return block.number; + } + + function blockHash(uint256 n) external view virtual returns (bytes32) { + if (n >= block.number || block.number - n > 256) { + return ""; + } + return blockhash(n); + } + + function getCurrentL1Fee() external view virtual returns (uint256) { + return 0; + } + + function getMaxL1Fee(uint256) external view virtual returns (uint256) { + return 0; + } +} diff --git a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol b/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol new file mode 100644 index 00000000000..7f26440c154 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {OVM_GasPriceOracle} from "../../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; +import {ChainModuleBase} from "./ChainModuleBase.sol"; + +contract OptimismModule is ChainModuleBase { + /// @dev OP_L1_DATA_FEE_PADDING includes 35 bytes for L1 data padding for Optimism and BASE + bytes private constant OP_L1_DATA_FEE_PADDING = + hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + /// @dev OVM_GASPRICEORACLE_ADDR is the address of the OVM_GasPriceOracle precompile on Optimism. + /// @dev reference: https://community.optimism.io/docs/developers/build/transaction-fees/#estimating-the-l1-data-fee + address private constant OVM_GASPRICEORACLE_ADDR = 0x420000000000000000000000000000000000000F; + OVM_GasPriceOracle private constant OVM_GASPRICEORACLE = OVM_GasPriceOracle(OVM_GASPRICEORACLE_ADDR); + + function getCurrentL1Fee() external view override returns (uint256) { + return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(msg.data, OP_L1_DATA_FEE_PADDING)); + } + + function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { + // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. + // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. + bytes memory txCallData = new bytes(4 * dataSize); + return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(txCallData, OP_L1_DATA_FEE_PADDING)); + } +} diff --git a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol b/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol new file mode 100644 index 00000000000..a2f585dd381 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {IScrollL1GasPriceOracle} from "../../../vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol"; +import {ChainModuleBase} from "./ChainModuleBase.sol"; + +contract ScrollModule is ChainModuleBase { + /// @dev SCROLL_L1_FEE_DATA_PADDING includes 120 bytes for L1 data padding for Optimism + /// @dev according to testing, this padding allows automation registry to properly estimates L1 data fee with 3-5% buffer + /// @dev this MAY NOT work for a different product and this may get out of date if transmit function is changed + bytes private constant SCROLL_L1_FEE_DATA_PADDING = + hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + /// @dev SCROLL_ORACLE_ADDR is the address of the L1GasPriceOracle precompile on Optimism. + /// @dev reference: https://docs.scroll.io/en/developers/transaction-fees-on-scroll/#estimating-the-l1-data-fee + address private constant SCROLL_ORACLE_ADDR = 0x5300000000000000000000000000000000000002; + IScrollL1GasPriceOracle private constant SCROLL_ORACLE = IScrollL1GasPriceOracle(SCROLL_ORACLE_ADDR); + + function getCurrentL1Fee() external view override returns (uint256) { + return SCROLL_ORACLE.getL1Fee(bytes.concat(msg.data, SCROLL_L1_FEE_DATA_PADDING)); + } + + function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { + // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. + // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. + // this is the same as OP. + bytes memory txCallData = new bytes(4 * dataSize); + return SCROLL_ORACLE.getL1Fee(bytes.concat(txCallData, SCROLL_L1_FEE_DATA_PADDING)); + } +} diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol index 5798a4cd2ba..2c0d8f05297 100644 --- a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol +++ b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol @@ -1,4 +1,4 @@ -// abi-checksum: 0x8c20867ddb05274d8f63e6760a8ba7c988280a535e63497917958948611c0765 +// abi-checksum: 0x71da69c27646c421cbde8ef39597eb47197351f8c89dee37447b35d8ad1d572e // SPDX-License-Identifier: MIT // !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !! pragma solidity ^0.8.4; @@ -58,6 +58,7 @@ interface IAutomationRegistryMaster { error ValueNotChanged(); event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); event CancelledUpkeepReport(uint256 indexed id, bytes trigger); + event ChainSpecificModuleUpdated(address newModule); event ConfigSet( uint32 previousConfigBlockNumber, bytes32 configDigest, @@ -212,6 +213,7 @@ interface IAutomationRegistryMaster { function getAutomationForwarderLogic() external view returns (address); function getBalance(uint256 id) external view returns (uint96 balance); function getCancellationDelay() external pure returns (uint256); + function getChainModule() external view returns (address chainModule); function getConditionalGasOverhead() external pure returns (uint256); function getFastGasFeedAddress() external view returns (address); function getForwarder(uint256 upkeepID) external view returns (address); @@ -221,7 +223,6 @@ interface IAutomationRegistryMaster { function getMaxPaymentForGas(uint8 triggerType, uint32 gasLimit) external view returns (uint96 maxPayment); function getMinBalance(uint256 id) external view returns (uint96); function getMinBalanceForUpkeep(uint256 id) external view returns (uint96 minBalance); - function getMode() external view returns (uint8); function getPeerRegistryMigrationPermission(address peer) external view returns (uint8); function getPerPerformByteGasOverhead() external pure returns (uint256); function getPerSignerGasOverhead() external pure returns (uint256); @@ -249,6 +250,7 @@ interface IAutomationRegistryMaster { function pauseUpkeep(uint256 id) external; function recoverFunds() external; function setAdminPrivilegeConfig(address admin, bytes memory newPrivilegeConfig) external; + function setChainSpecificModule(address newModule) external; function setPayees(address[] memory payees) external; function setPeerRegistryMigrationPermission(address peer, uint8 permission) external; function setUpkeepCheckData(uint256 id, bytes memory newCheckData) external; @@ -283,6 +285,7 @@ interface AutomationRegistryBase2_2 { address transcoder; address[] registrars; address upkeepPrivilegeManager; + address chainModule; bool reorgProtectionEnabled; } @@ -333,5 +336,5 @@ interface AutomationRegistryBase2_2 { // THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON: /* -[{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MaxCheckDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MaxPerformDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"PaymentGreaterThanAllLINK","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"OwnerFundsWithdrawn","type":"event"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum AutomationRegistryBase2_2.Mode","name":"mode","type":"uint8"},{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkNativeFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkNativeFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMode","outputs":[{"internalType":"enum AutomationRegistryBase2_2.Mode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.State","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct AutomationRegistryBase2_2.UpkeepInfo","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepTranscoderVersion","outputs":[{"internalType":"enum UpkeepFormat","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwnerFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MaxCheckDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MaxPerformDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"PaymentGreaterThanAllLINK","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"OwnerFundsWithdrawn","type":"event"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkNativeFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkNativeFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.State","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct AutomationRegistryBase2_2.UpkeepInfo","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IChainModule","name":"newModule","type":"address"}],"name":"setChainSpecificModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepTranscoderVersion","outputs":[{"internalType":"enum UpkeepFormat","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwnerFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] */ diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol new file mode 100644 index 00000000000..dd5613fbf36 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +interface IChainModule { + // retrieve the native block number of a chain. e.g. L2 block number on Arbitrum + function blockNumber() external view returns (uint256); + + // retrieve the native block hash of a chain. + function blockHash(uint256) external view returns (bytes32); + + // retrieve the L1 data fee for a L2 transaction. it should return 0 for L1 chains and + // L2 chains which don't have L1 fee component. it uses msg.data to estimate L1 data so + // it must be used with a transaction. + function getCurrentL1Fee() external view returns (uint256); + + // retrieve the L1 data fee for a L2 simulation. it should return 0 for L1 chains and + // L2 chains which don't have L1 fee component. + function getMaxL1Fee(uint256 dataSize) external view returns (uint256); +} diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol index 20cebacc1b2..6b05e4f6465 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol +++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol @@ -8,7 +8,7 @@ import {AutomationRegistryBase2_2} from "../v2_2/AutomationRegistryBase2_2.sol"; import {AutomationRegistryLogicA2_2} from "../v2_2/AutomationRegistryLogicA2_2.sol"; import {AutomationRegistryLogicB2_2} from "../v2_2/AutomationRegistryLogicB2_2.sol"; import {IAutomationRegistryMaster} from "../interfaces/v2_2/IAutomationRegistryMaster.sol"; -import {AutomationCompatibleInterface} from "../../interfaces/AutomationCompatibleInterface.sol"; +import {ChainModuleBase} from "../chains/ChainModuleBase.sol"; contract AutomationRegistry2_2_SetUp is BaseTest { address internal constant LINK_ETH_FEED = 0x1111111111111111111111111111111111111110; @@ -29,6 +29,8 @@ contract AutomationRegistry2_2_SetUp is BaseTest { address[] internal s_valid_transmitters; address[] internal s_registrars; + IAutomationRegistryMaster internal registryMaster; + function setUp() public override { s_valid_transmitters = new address[](4); for (uint160 i = 0; i < 4; ++i) { @@ -43,12 +45,9 @@ contract AutomationRegistry2_2_SetUp is BaseTest { s_registrars = new address[](1); s_registrars[0] = 0x3a0eDE26aa188BFE00b9A0C9A431A1a0CA5f7966; - } - function deployRegistry2_2(AutomationRegistryBase2_2.Mode mode) public returns (IAutomationRegistryMaster) { AutomationForwarderLogic forwarderLogic = new AutomationForwarderLogic(); AutomationRegistryLogicB2_2 logicB2_2 = new AutomationRegistryLogicB2_2( - mode, LINK_TOKEN, LINK_ETH_FEED, FAST_GAS_FEED, @@ -56,19 +55,15 @@ contract AutomationRegistry2_2_SetUp is BaseTest { ZERO_ADDRESS ); AutomationRegistryLogicA2_2 logicA2_2 = new AutomationRegistryLogicA2_2(logicB2_2); - IAutomationRegistryMaster registry2_2 = IAutomationRegistryMaster( + registryMaster = IAutomationRegistryMaster( address(new AutomationRegistry2_2(AutomationRegistryLogicB2_2(address(logicA2_2)))) ); - return registry2_2; } } contract AutomationRegistry2_2_LatestConfigDetails is AutomationRegistry2_2_SetUp { function testGet() public { - IAutomationRegistryMaster registry = IAutomationRegistryMaster( - address(deployRegistry2_2(AutomationRegistryBase2_2.Mode(0))) - ); - (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = registry.latestConfigDetails(); + (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = registryMaster.latestConfigDetails(); assertEq(configCount, 0); assertEq(blockNumber, 0); assertEq(configDigest, ""); @@ -77,17 +72,13 @@ contract AutomationRegistry2_2_LatestConfigDetails is AutomationRegistry2_2_SetU contract AutomationRegistry2_2_CheckUpkeep is AutomationRegistry2_2_SetUp { function testPreventExecutionOnCheckUpkeep() public { - IAutomationRegistryMaster registry = IAutomationRegistryMaster( - address(deployRegistry2_2(AutomationRegistryBase2_2.Mode(0))) - ); - uint256 id = 1; bytes memory triggerData = abi.encodePacked("trigger_data"); // The tx.origin is the DEFAULT_SENDER (0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38) of foundry // Expecting a revert since the tx.origin is not address(0) vm.expectRevert(abi.encodeWithSelector(IAutomationRegistryMaster.OnlySimulatedBackend.selector)); - registry.checkUpkeep(id, triggerData); + registryMaster.checkUpkeep(id, triggerData); } } @@ -105,11 +96,9 @@ contract AutomationRegistry2_2_SetConfig is AutomationRegistry2_2_SetUp { ); function testSetConfigSuccess() public { - IAutomationRegistryMaster registry = IAutomationRegistryMaster( - address(deployRegistry2_2(AutomationRegistryBase2_2.Mode(0))) - ); - (uint32 configCount, , ) = registry.latestConfigDetails(); + (uint32 configCount, , ) = registryMaster.latestConfigDetails(); assertEq(configCount, 0); + ChainModuleBase module = new ChainModuleBase(); AutomationRegistryBase2_2.OnchainConfig memory cfg = AutomationRegistryBase2_2.OnchainConfig({ paymentPremiumPPB: 10_000, @@ -127,6 +116,7 @@ contract AutomationRegistry2_2_SetConfig is AutomationRegistry2_2_SetUp { transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c, registrars: s_registrars, upkeepPrivilegeManager: 0xD9c855F08A7e460691F41bBDDe6eC310bc0593D8, + chainModule: module, reorgProtectionEnabled: true }); bytes memory onchainConfigBytes = abi.encode(cfg); @@ -136,7 +126,7 @@ contract AutomationRegistry2_2_SetConfig is AutomationRegistry2_2_SetUp { bytes memory offchainConfigBytes = abi.encode(a, b); bytes32 configDigest = _configDigestFromConfigData( block.chainid, - address(registry), + address(registryMaster), ++configCount, s_valid_signers, s_valid_transmitters, @@ -159,7 +149,7 @@ contract AutomationRegistry2_2_SetConfig is AutomationRegistry2_2_SetUp { offchainConfigBytes ); - registry.setConfig( + registryMaster.setConfig( s_valid_signers, s_valid_transmitters, F, @@ -168,7 +158,7 @@ contract AutomationRegistry2_2_SetConfig is AutomationRegistry2_2_SetUp { offchainConfigBytes ); - (, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState(); + (, , address[] memory signers, address[] memory transmitters, uint8 f) = registryMaster.getState(); assertEq(signers, s_valid_signers); assertEq(transmitters, s_valid_transmitters); diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol index dc501d82334..f988787d574 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol @@ -20,7 +20,7 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain /** * @notice versions: - * AutomationRegistry 2.2.0: moves chain-spicific integration code into a separate module + * AutomationRegistry 2.2.0: moves chain-specific integration code into a separate module * KeeperRegistry 2.1.0: introduces support for log triggers * removes the need for "wrapped perform data" * KeeperRegistry 2.0.2: pass revert bytes as performData when target contract reverts @@ -48,7 +48,6 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain AutomationRegistryLogicB2_2 logicA ) AutomationRegistryBase2_2( - logicA.getMode(), logicA.getLinkAddress(), logicA.getLinkNativeFeedAddress(), logicA.getFastGasFeedAddress(), @@ -88,13 +87,18 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain uint40 epochAndRound = uint40(uint256(reportContext[1])); uint32 epoch = uint32(epochAndRound >> 8); - _handleReport(hotVars, report, gasOverhead, epoch); + _handleReport(hotVars, report, gasOverhead); + + if (epoch > hotVars.latestEpoch) { + s_hotVars.latestEpoch = epoch; + } } - function _handleReport(HotVars memory hotVars, Report memory report, uint256 gasOverhead, uint32 epoch) private { + function _handleReport(HotVars memory hotVars, Report memory report, uint256 gasOverhead) private { UpkeepTransmitInfo[] memory upkeepTransmitInfo = new UpkeepTransmitInfo[](report.upkeepIds.length); uint16 numUpkeepsPassedChecks; + uint256 blocknumber = hotVars.chainModule.blockNumber(); for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; upkeepTransmitInfo[i].triggerType = _getTriggerType(report.upkeepIds[i]); @@ -109,6 +113,7 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain ); (upkeepTransmitInfo[i].earlyChecksPassed, upkeepTransmitInfo[i].dedupID) = _prePerformChecks( report.upkeepIds[i], + blocknumber, report.triggers[i], upkeepTransmitInfo[i], hotVars @@ -131,7 +136,7 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain gasOverhead -= upkeepTransmitInfo[i].gasUsed; // Store last perform block number / deduping key for upkeep - _updateTriggerMarker(report.upkeepIds[i], upkeepTransmitInfo[i]); + _updateTriggerMarker(report.upkeepIds[i], blocknumber, upkeepTransmitInfo[i]); } // No upkeeps to be performed in this report if (numUpkeepsPassedChecks == 0) { @@ -141,7 +146,7 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain // This is the overall gas overhead that will be split across performed upkeeps // Take upper bound of 16 gas per callData bytes, which is approximated to be reportLength // Rest of msg.data is accounted for in accounting overheads - // NOTE in process of changing acounting, so pre-emptively changed reportLength to msg.data.length + // NOTE in process of changing accounting, so pre-emptively changed reportLength to msg.data.length gasOverhead = (gasOverhead - gasleft() + 16 * msg.data.length) + ACCOUNTING_FIXED_GAS_OVERHEAD + @@ -187,10 +192,6 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain // record payments s_transmitters[msg.sender].balance += totalReimbursement; s_hotVars.totalPremium += totalPremium; - - if (epoch > hotVars.latestEpoch) { - s_hotVars.latestEpoch = epoch; - } } /** @@ -320,7 +321,8 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain reentrancyGuard: s_hotVars.reentrancyGuard, totalPremium: totalPremium, latestEpoch: 0, // DON restarts epoch - reorgProtectionEnabled: onchainConfig.reorgProtectionEnabled + reorgProtectionEnabled: onchainConfig.reorgProtectionEnabled, + chainModule: onchainConfig.chainModule }); s_storage = Storage({ @@ -341,7 +343,7 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain s_fallbackLinkPrice = onchainConfig.fallbackLinkPrice; uint32 previousConfigBlockNumber = s_storage.latestConfigBlockNumber; - s_storage.latestConfigBlockNumber = uint32(_blockNum()); + s_storage.latestConfigBlockNumber = uint32(onchainConfig.chainModule.blockNumber()); s_storage.configCount += 1; bytes memory onchainConfigBytes = abi.encode(onchainConfig); diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol index a419867c0d7..976c8dff80d 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol @@ -3,9 +3,6 @@ pragma solidity 0.8.19; import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; -import {ArbGasInfo} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; -import {OVM_GasPriceOracle} from "../../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; -import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; import {StreamsLookupCompatibleInterface} from "../../interfaces/StreamsLookupCompatibleInterface.sol"; import {ILogAutomation, Log} from "../../interfaces/ILogAutomation.sol"; import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; @@ -14,6 +11,7 @@ import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Inte import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; +import {IChainModule} from "../interfaces/v2_2/IChainModule.sol"; /** * @notice Base Keeper Registry contract, contains shared logic between @@ -46,27 +44,19 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { */ UpkeepFormat internal constant UPKEEP_TRANSCODER_VERSION_BASE = UpkeepFormat.V1; uint8 internal constant UPKEEP_VERSION_BASE = 3; - // L1_FEE_DATA_PADDING includes 35 bytes for L1 data padding for Optimism - bytes internal constant L1_FEE_DATA_PADDING = - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 90_000; // Used in maxPayment estimation, and in capping overheads during actual payment - uint256 internal constant REGISTRY_LOG_OVERHEAD = 110_000; // Used only in maxPayment estimation, and in capping overheads during actual payment. + uint256 internal constant REGISTRY_LOG_OVERHEAD = 110_400; // Used only in maxPayment estimation, and in capping overheads during actual payment. uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 20; // Used only in maxPayment estimation, and in capping overheads during actual payment. Value scales with performData length. uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 7_500; // Used only in maxPayment estimation, and in capping overheads during actual payment. Value scales with f. - uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 27_500; // Used in actual payment. Fixed overhead per tx + uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 28_100; // Used in actual payment. Fixed overhead per tx uint256 internal constant ACCOUNTING_PER_SIGNER_GAS_OVERHEAD = 1_100; // Used in actual payment. overhead per signer - uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 7_000; // Used in actual payment. overhead per upkeep performed - - OVM_GasPriceOracle internal constant OPTIMISM_ORACLE = OVM_GasPriceOracle(0x420000000000000000000000000000000000000F); - ArbGasInfo internal constant ARB_NITRO_ORACLE = ArbGasInfo(0x000000000000000000000000000000000000006C); - ArbSys internal constant ARB_SYS = ArbSys(0x0000000000000000000000000000000000000064); + uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 7_200; // Used in actual payment. overhead per upkeep performed LinkTokenInterface internal immutable i_link; AggregatorV3Interface internal immutable i_linkNativeFeed; AggregatorV3Interface internal immutable i_fastGasFeed; - Mode internal immutable i_mode; address internal immutable i_automationForwarderLogic; address internal immutable i_allowedReadOnlyAddress; @@ -162,12 +152,6 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { BIDIRECTIONAL } - enum Mode { - DEFAULT, - ARBITRUM, - OPTIMISM - } - enum Trigger { CONDITION, LOG @@ -252,6 +236,9 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { * @member registrars addresses of the registrar contracts * @member upkeepPrivilegeManager address which can set privilege for upkeeps * @member reorgProtectionEnabled if this registry enables re-org protection checks + * @member chainSpecificModule the chain specific module + * @member chainModule the chain specific module + * @member reorgProtectionEnabled if this registry will enable re-org protection checks */ struct OnchainConfig { uint32 paymentPremiumPPB; @@ -269,6 +256,7 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { address transcoder; address[] registrars; address upkeepPrivilegeManager; + IChainModule chainModule; bool reorgProtectionEnabled; } @@ -362,6 +350,7 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { bool paused; // │ pause switch for all upkeeps in the registry bool reentrancyGuard; // ────────╯ guard against reentrancy bool reorgProtectionEnabled; // if this registry should enable re-org protection mechanism + IChainModule chainModule; // the interface of chain specific module } /// @dev Config + State storage struct which is not on hot transmit path @@ -452,6 +441,7 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); event CancelledUpkeepReport(uint256 indexed id, bytes trigger); + event ChainSpecificModuleUpdated(address newModule); event DedupKeyAdded(bytes32 indexed dedupKey); event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); @@ -488,7 +478,6 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { event Unpaused(address account); /** - * @param mode the contract mode of default, Arbitrum, or Optimism * @param link address of the LINK Token * @param linkNativeFeed address of the LINK/Native price feed * @param fastGasFeed address of the Fast Gas price feed @@ -496,14 +485,12 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { * @param allowedReadOnlyAddress the address of the allowed read only address */ constructor( - Mode mode, address link, address linkNativeFeed, address fastGasFeed, address automationForwarderLogic, address allowedReadOnlyAddress ) ConfirmedOwner(msg.sender) { - i_mode = mode; i_link = LinkTokenInterface(link); i_linkNativeFeed = AggregatorV3Interface(linkNativeFeed); i_fastGasFeed = AggregatorV3Interface(fastGasFeed); @@ -560,8 +547,9 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { */ function _createID(Trigger triggerType) internal view returns (uint256) { bytes1 empty; + IChainModule chainModule = s_hotVars.chainModule; bytes memory idBytes = abi.encodePacked( - keccak256(abi.encode(_blockHash(_blockNum() - 1), address(this), s_storage.nonce)) + keccak256(abi.encode(chainModule.blockHash((chainModule.blockNumber() - 1)), address(this), s_storage.nonce)) ); for (uint256 idx = 4; idx < 15; idx++) { idBytes[idx] = empty; @@ -625,30 +613,11 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { } uint256 l1CostWei = 0; - if (i_mode == Mode.OPTIMISM) { - bytes memory txCallData = new bytes(0); - if (isExecution) { - txCallData = bytes.concat(msg.data, L1_FEE_DATA_PADDING); - } else { - // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have - // s_storage.maxPerformDataSize non zero-bytes. Instead of setting bytes to non-zero - // we initialize 'new bytes' of length 4*maxPerformDataSize to cover for zero bytes. - txCallData = new bytes(4 * s_storage.maxPerformDataSize); - } - l1CostWei = OPTIMISM_ORACLE.getL1Fee(txCallData); - } else if (i_mode == Mode.ARBITRUM) { - if (isExecution) { - l1CostWei = ARB_NITRO_ORACLE.getCurrentTxL1GasFees(); - } else { - // fee is 4 per 0 byte, 16 per non-zero byte - we assume all non-zero and - // max data size to calculate max payment - (, uint256 perL1CalldataUnit, , , , ) = ARB_NITRO_ORACLE.getPricesInWei(); - l1CostWei = perL1CalldataUnit * s_storage.maxPerformDataSize * 16; - } - } - // if it's not performing upkeeps, use gas ceiling multiplier to estimate the upper bound - if (!isExecution) { - l1CostWei = hotVars.gasCeilingMultiplier * l1CostWei; + if (isExecution) { + l1CostWei = hotVars.chainModule.getCurrentL1Fee(); + } else { + // if it's not performing upkeeps, use gas ceiling multiplier to estimate the upper bound + l1CostWei = hotVars.gasCeilingMultiplier * hotVars.chainModule.getMaxL1Fee(s_storage.maxPerformDataSize); } // Divide l1CostWei among all batched upkeeps. Spare change from division is not charged l1CostWei = l1CostWei / numBatchedUpkeeps; @@ -781,21 +750,23 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { */ function _prePerformChecks( uint256 upkeepId, + uint256 blocknumber, bytes memory rawTrigger, UpkeepTransmitInfo memory transmitInfo, HotVars memory hotVars ) internal returns (bool, bytes32) { bytes32 dedupID; if (transmitInfo.triggerType == Trigger.CONDITION) { - if (!_validateConditionalTrigger(upkeepId, rawTrigger, transmitInfo, hotVars)) return (false, dedupID); + if (!_validateConditionalTrigger(upkeepId, blocknumber, rawTrigger, transmitInfo, hotVars)) + return (false, dedupID); } else if (transmitInfo.triggerType == Trigger.LOG) { bool valid; - (valid, dedupID) = _validateLogTrigger(upkeepId, rawTrigger, hotVars); + (valid, dedupID) = _validateLogTrigger(upkeepId, blocknumber, rawTrigger, hotVars); if (!valid) return (false, dedupID); } else { revert InvalidTriggerType(); } - if (transmitInfo.upkeep.maxValidBlocknumber <= _blockNum()) { + if (transmitInfo.upkeep.maxValidBlocknumber <= blocknumber) { // Can happen when an upkeep got cancelled after report was generated. // However we have a CANCELLATION_DELAY of 50 blocks so shouldn't happen in practice emit CancelledUpkeepReport(upkeepId, rawTrigger); @@ -814,6 +785,7 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { */ function _validateConditionalTrigger( uint256 upkeepId, + uint256 blocknumber, bytes memory rawTrigger, UpkeepTransmitInfo memory transmitInfo, HotVars memory hotVars @@ -826,8 +798,8 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { } if ( (hotVars.reorgProtectionEnabled && - (trigger.blockHash != bytes32("") && _blockHash(trigger.blockNum) != trigger.blockHash)) || - trigger.blockNum >= _blockNum() + (trigger.blockHash != bytes32("") && hotVars.chainModule.blockHash(trigger.blockNum) != trigger.blockHash)) || + trigger.blockNum >= blocknumber ) { // There are two cases of reorged report // 1. trigger block number is in future: this is an edge case during extreme deep reorgs of chain @@ -843,6 +815,7 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { function _validateLogTrigger( uint256 upkeepId, + uint256 blocknumber, bytes memory rawTrigger, HotVars memory hotVars ) internal returns (bool, bytes32) { @@ -850,8 +823,8 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { bytes32 dedupID = keccak256(abi.encodePacked(upkeepId, trigger.logBlockHash, trigger.txHash, trigger.logIndex)); if ( (hotVars.reorgProtectionEnabled && - (trigger.blockHash != bytes32("") && _blockHash(trigger.blockNum) != trigger.blockHash)) || - trigger.blockNum >= _blockNum() + (trigger.blockHash != bytes32("") && hotVars.chainModule.blockHash(trigger.blockNum) != trigger.blockHash)) || + trigger.blockNum >= blocknumber ) { // Reorg protection is same as conditional trigger upkeeps emit ReorgedUpkeepReport(upkeepId, rawTrigger); @@ -896,9 +869,13 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { * @dev updates a storage marker for this upkeep to prevent duplicate and out of order performances * @dev for conditional triggers we set the latest block number, for log triggers we store a dedupID */ - function _updateTriggerMarker(uint256 upkeepID, UpkeepTransmitInfo memory upkeepTransmitInfo) internal { + function _updateTriggerMarker( + uint256 upkeepID, + uint256 blocknumber, + UpkeepTransmitInfo memory upkeepTransmitInfo + ) internal { if (upkeepTransmitInfo.triggerType == Trigger.CONDITION) { - s_upkeep[upkeepID].lastPerformedBlockNumber = uint32(_blockNum()); + s_upkeep[upkeepID].lastPerformedBlockNumber = uint32(blocknumber); } else if (upkeepTransmitInfo.triggerType == Trigger.LOG) { s_dedupKeys[upkeepTransmitInfo.dedupID] = true; emit DedupKeyAdded(upkeepTransmitInfo.dedupID); @@ -972,34 +949,6 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { if (s_upkeep[upkeepId].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); } - /** - * @dev returns the current block number in a chain agnostic manner - */ - function _blockNum() internal view returns (uint256) { - if (i_mode == Mode.ARBITRUM) { - return ARB_SYS.arbBlockNumber(); - } else { - return block.number; - } - } - - /** - * @dev returns the blockhash of the provided block number in a chain agnostic manner - * @param n the blocknumber to retrieve the blockhash for - * @return blockhash the blockhash of block number n, or 0 if n is out queryable of range - */ - function _blockHash(uint256 n) internal view returns (bytes32) { - if (i_mode == Mode.ARBITRUM) { - uint256 blockNum = ARB_SYS.arbBlockNumber(); - if (n >= blockNum || blockNum - n > 256) { - return ""; - } - return ARB_SYS.arbBlockHash(n); - } else { - return blockhash(n); - } - } - /** * @dev replicates Open Zeppelin's ReentrancyGuard but optimized to fit our storage */ diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol index d261fc2552c..4663c172e67 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol @@ -26,7 +26,6 @@ contract AutomationRegistryLogicA2_2 is AutomationRegistryBase2_2, Chainable { AutomationRegistryLogicB2_2 logicB ) AutomationRegistryBase2_2( - logicB.getMode(), logicB.getLinkAddress(), logicB.getLinkNativeFeedAddress(), logicB.getFastGasFeedAddress(), @@ -287,10 +286,10 @@ contract AutomationRegistryLogicA2_2 is AutomationRegistryBase2_2, Chainable { bool canceled = upkeep.maxValidBlocknumber != UINT32_MAX; bool isOwner = msg.sender == owner(); - if (canceled && !(isOwner && upkeep.maxValidBlocknumber > _blockNum())) revert CannotCancel(); + uint256 height = s_hotVars.chainModule.blockNumber(); + if (canceled && !(isOwner && upkeep.maxValidBlocknumber > height)) revert CannotCancel(); if (!isOwner && msg.sender != s_upkeepAdmin[id]) revert OnlyCallableByOwnerOrAdmin(); - uint256 height = _blockNum(); if (!isOwner) { height = height + CANCELLATION_DELAY; } diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol index cf5293ec064..d7e1edf7bc8 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol @@ -6,6 +6,7 @@ import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contra import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; +import {IChainModule} from "../interfaces/v2_2/IChainModule.sol"; contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { using Address for address; @@ -16,15 +17,12 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { * @dev see AutomationRegistry master contract for constructor description */ constructor( - Mode mode, address link, address linkNativeFeed, address fastGasFeed, address automationForwarderLogic, address allowedReadOnlyAddress - ) - AutomationRegistryBase2_2(mode, link, linkNativeFeed, fastGasFeed, automationForwarderLogic, allowedReadOnlyAddress) - {} + ) AutomationRegistryBase2_2(link, linkNativeFeed, fastGasFeed, automationForwarderLogic, allowedReadOnlyAddress) {} // ================================================================ // | UPKEEP MANAGEMENT | @@ -119,7 +117,7 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { if (to == ZERO_ADDRESS) revert InvalidRecipient(); Upkeep memory upkeep = s_upkeep[id]; if (s_upkeepAdmin[id] != msg.sender) revert OnlyCallableByAdmin(); - if (upkeep.maxValidBlocknumber > _blockNum()) revert UpkeepNotCanceled(); + if (upkeep.maxValidBlocknumber > s_hotVars.chainModule.blockNumber()) revert UpkeepNotCanceled(); uint96 amountToWithdraw = s_upkeep[id].balance; s_expectedLinkBalance = s_expectedLinkBalance - amountToWithdraw; s_upkeep[id].balance = 0; @@ -173,6 +171,14 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { // | OWNER / MANAGER ACTIONS | // ================================================================ + /** + * @notice sets the chain specific module + */ + function setChainSpecificModule(IChainModule newModule) external onlyOwner { + s_hotVars.chainModule = newModule; + emit ChainSpecificModuleUpdated(address(newModule)); + } + /** * @notice sets the privilege config for an upkeep */ @@ -283,10 +289,6 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { return CANCELLATION_DELAY; } - function getMode() external view returns (Mode) { - return i_mode; - } - function getLinkAddress() external view returns (address) { return address(i_link); } @@ -451,6 +453,13 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { return (state, config, s_signersList, s_transmittersList, s_hotVars.f); } + /** + * @notice get the chain module + */ + function getChainModule() external view returns (IChainModule chainModule) { + return s_hotVars.chainModule; + } + /** * @notice if this registry has reorg protection enabled */ diff --git a/contracts/src/v0.8/tests/MockChainModule.sol b/contracts/src/v0.8/tests/MockChainModule.sol new file mode 100644 index 00000000000..192e86e9a88 --- /dev/null +++ b/contracts/src/v0.8/tests/MockChainModule.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.16; + +import {IChainModule} from "../automation/dev/interfaces/v2_2/IChainModule.sol"; + +contract MockChainModule is IChainModule { + //uint256 internal blockNum; + + function blockNumber() external view returns (uint256) { + return 1256; + } + + function blockHash(uint256 blocknumber) external view returns (bytes32) { + require(1000 >= blocknumber, "block too old"); + + return keccak256(abi.encode(blocknumber)); + } + + function getCurrentL1Fee() external view returns (uint256) { + return 0; + } + + // retrieve the L1 data fee for a L2 simulation. it should return 0 for L1 chains and + // L2 chains which don't have L1 fee component. + function getMaxL1Fee(uint256 dataSize) external view returns (uint256) { + return 0; + } +} diff --git a/contracts/src/v0.8/vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol b/contracts/src/v0.8/vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol new file mode 100644 index 00000000000..95b88e98456 --- /dev/null +++ b/contracts/src/v0.8/vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.16; + +interface IScrollL1GasPriceOracle { + /********** + * Events * + **********/ + + /// @notice Emitted when current fee overhead is updated. + /// @param overhead The current fee overhead updated. + event OverheadUpdated(uint256 overhead); + + /// @notice Emitted when current fee scalar is updated. + /// @param scalar The current fee scalar updated. + event ScalarUpdated(uint256 scalar); + + /// @notice Emitted when current l1 base fee is updated. + /// @param l1BaseFee The current l1 base fee updated. + event L1BaseFeeUpdated(uint256 l1BaseFee); + + /************************* + * Public View Functions * + *************************/ + + /// @notice Return the current l1 fee overhead. + function overhead() external view returns (uint256); + + /// @notice Return the current l1 fee scalar. + function scalar() external view returns (uint256); + + /// @notice Return the latest known l1 base fee. + function l1BaseFee() external view returns (uint256); + + /// @notice Computes the L1 portion of the fee based on the size of the rlp encoded input + /// transaction, the current L1 base fee, and the various dynamic parameters. + /// @param data Unsigned fully RLP-encoded transaction to get the L1 fee for. + /// @return L1 fee that should be paid for the tx + function getL1Fee(bytes memory data) external view returns (uint256); + + /// @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which + /// represents the per-transaction gas overhead of posting the transaction and state + /// roots to L1. Adds 74 bytes of padding to account for the fact that the input does + /// not have a signature. + /// @param data Unsigned fully RLP-encoded transaction to get the L1 gas for. + /// @return Amount of L1 gas used to publish the transaction. + function getL1GasUsed(bytes memory data) external view returns (uint256); + + /***************************** + * Public Mutating Functions * + *****************************/ + + /// @notice Allows whitelisted caller to modify the l1 base fee. + /// @param _l1BaseFee New l1 base fee. + function setL1BaseFee(uint256 _l1BaseFee) external; +} \ No newline at end of file diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts index b750a0619bf..8d022ddfe64 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts @@ -21,15 +21,21 @@ import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/fac import { UpkeepAutoFunder__factory as UpkeepAutoFunderFactory } from '../../../typechain/factories/UpkeepAutoFunder__factory' import { MockArbGasInfo__factory as MockArbGasInfoFactory } from '../../../typechain/factories/MockArbGasInfo__factory' import { MockOVMGasPriceOracle__factory as MockOVMGasPriceOracleFactory } from '../../../typechain/factories/MockOVMGasPriceOracle__factory' +import { ChainModuleBase__factory as ChainModuleBaseFactory } from '../../../typechain/factories/ChainModuleBase__factory' +import { ArbitrumModule__factory as ArbitrumModuleFactory } from '../../../typechain/factories/ArbitrumModule__factory' +import { OptimismModule__factory as OptimismModuleFactory } from '../../../typechain/factories/OptimismModule__factory' import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory' import { IAutomationForwarder__factory as IAutomationForwarderFactory } from '../../../typechain/factories/IAutomationForwarder__factory' import { MockArbSys__factory as MockArbSysFactory } from '../../../typechain/factories/MockArbSys__factory' import { AutomationUtils2_2 as AutomationUtils } from '../../../typechain/AutomationUtils2_2' +import { MockArbGasInfo } from '../../../typechain/MockArbGasInfo' +import { MockOVMGasPriceOracle } from '../../../typechain/MockOVMGasPriceOracle' import { StreamsLookupUpkeep } from '../../../typechain/StreamsLookupUpkeep' import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' import { UpkeepMock } from '../../../typechain/UpkeepMock' -import { MockArbGasInfo } from '../../../typechain/MockArbGasInfo' -import { MockOVMGasPriceOracle } from '../../../typechain/MockOVMGasPriceOracle' +import { ChainModuleBase } from '../../../typechain/ChainModuleBase' +import { ArbitrumModule } from '../../../typechain/ArbitrumModule' +import { OptimismModule } from '../../../typechain/OptimismModule' import { UpkeepTranscoder } from '../../../typechain/UpkeepTranscoder' import { UpkeepAutoFunder } from '../../../typechain' import { @@ -63,13 +69,6 @@ enum UpkeepFailureReason { REGISTRY_PAUSED, } -// copied from AutomationRegistryInterface2_2.sol -enum Mode { - DEFAULT, - ARBITRUM, - OPTIMISM, -} - // copied from AutomationRegistryBase2_2.sol enum Trigger { CONDITION, @@ -112,7 +111,7 @@ const emptyBytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000' const transmitGasOverhead = 1_000_000 -const checkGasOverhead = 400_000 +const checkGasOverhead = 400_000 + 3_500 // 3_500 for the overhead to call chain module const stalenessSeconds = BigNumber.from(43820) const gasCeilingMultiplier = BigNumber.from(2) @@ -137,11 +136,14 @@ let logTriggerConfig: string // Smart contract factories let linkTokenFactory: ContractFactory +let mockArbGasInfoFactory: MockArbGasInfoFactory +let mockOVMGasPriceOracleFactory: MockOVMGasPriceOracleFactory let mockV3AggregatorFactory: MockV3AggregatorFactory let upkeepMockFactory: UpkeepMockFactory let upkeepAutoFunderFactory: UpkeepAutoFunderFactory -let mockArbGasInfoFactory: MockArbGasInfoFactory -let mockOVMGasPriceOracleFactory: MockOVMGasPriceOracleFactory +let chainModuleBaseFactory: ChainModuleBaseFactory +let arbitrumModuleFactory: ArbitrumModuleFactory +let optimismModuleFactory: OptimismModuleFactory let streamsLookupUpkeepFactory: StreamsLookupUpkeepFactory let personas: Personas @@ -154,12 +156,15 @@ let arbRegistry: IAutomationRegistry // arbitrum registry let opRegistry: IAutomationRegistry // optimism registry let mgRegistry: IAutomationRegistry // "migrate registry" used in migration tests let blankRegistry: IAutomationRegistry // used to test initial configurations +let mockArbGasInfo: MockArbGasInfo +let mockOVMGasPriceOracle: MockOVMGasPriceOracle let mock: UpkeepMock let autoFunderUpkeep: UpkeepAutoFunder let ltUpkeep: MockContract let transcoder: UpkeepTranscoder -let mockArbGasInfo: MockArbGasInfo -let mockOVMGasPriceOracle: MockOVMGasPriceOracle +let chainModuleBase: ChainModuleBase +let arbitrumModule: ArbitrumModule +let optimismModule: OptimismModule let streamsLookupUpkeep: StreamsLookupUpkeep let automationUtils: AutomationUtils @@ -418,7 +423,11 @@ describe('AutomationRegistry2_2', () => { let signers: Wallet[] let signerAddresses: string[] let config: any + let arbConfig: any + let opConfig: any let baseConfig: Parameters + let arbConfigParams: Parameters + let opConfigParams: Parameters let upkeepManager: string before(async () => { @@ -434,13 +443,16 @@ describe('AutomationRegistry2_2', () => { mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', )) as unknown as MockV3AggregatorFactory - upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') - upkeepAutoFunderFactory = - await ethers.getContractFactory('UpkeepAutoFunder') mockArbGasInfoFactory = await ethers.getContractFactory('MockArbGasInfo') mockOVMGasPriceOracleFactory = await ethers.getContractFactory( 'MockOVMGasPriceOracle', ) + upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') + upkeepAutoFunderFactory = + await ethers.getContractFactory('UpkeepAutoFunder') + chainModuleBaseFactory = await ethers.getContractFactory('ChainModuleBase') + arbitrumModuleFactory = await ethers.getContractFactory('ArbitrumModule') + optimismModuleFactory = await ethers.getContractFactory('OptimismModule') streamsLookupUpkeepFactory = await ethers.getContractFactory( 'StreamsLookupUpkeep', ) @@ -565,6 +577,7 @@ describe('AutomationRegistry2_2', () => { const verifyMaxPayment = async ( registry: IAutomationRegistry, + chainModuleAddress: string, l1CostWei?: BigNumber, ) => { type TestCase = { @@ -628,6 +641,7 @@ describe('AutomationRegistry2_2', () => { transcoder: transcoder.address, registrars: [], upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleAddress, reorgProtectionEnabled: true, }), offchainVersion, @@ -830,6 +844,9 @@ describe('AutomationRegistry2_2', () => { mockOVMGasPriceOracle = await mockOVMGasPriceOracleFactory .connect(owner) .deploy() + chainModuleBase = await chainModuleBaseFactory.connect(owner).deploy() + arbitrumModule = await arbitrumModuleFactory.connect(owner).deploy() + optimismModule = await optimismModuleFactory.connect(owner).deploy() streamsLookupUpkeep = await streamsLookupUpkeepFactory .connect(owner) .deploy( @@ -881,9 +898,15 @@ describe('AutomationRegistry2_2', () => { transcoder: transcoder.address, registrars: [], upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, reorgProtectionEnabled: true, } + arbConfig = { ...config } + arbConfig.chainModule = arbitrumModule.address + opConfig = { ...config } + opConfig.chainModule = optimismModule.address + baseConfig = [ signerAddresses, keeperAddresses, @@ -892,10 +915,25 @@ describe('AutomationRegistry2_2', () => { offchainVersion, offchainBytes, ] + arbConfigParams = [ + signerAddresses, + keeperAddresses, + f, + encodeConfig(arbConfig), + offchainVersion, + offchainBytes, + ] + opConfigParams = [ + signerAddresses, + keeperAddresses, + f, + encodeConfig(opConfig), + offchainVersion, + offchainBytes, + ] registry = await deployRegistry22( owner, - Mode.DEFAULT, linkToken.address, linkEthFeed.address, gasPriceFeed.address, @@ -904,7 +942,6 @@ describe('AutomationRegistry2_2', () => { arbRegistry = await deployRegistry22( owner, - Mode.ARBITRUM, linkToken.address, linkEthFeed.address, gasPriceFeed.address, @@ -913,7 +950,6 @@ describe('AutomationRegistry2_2', () => { opRegistry = await deployRegistry22( owner, - Mode.OPTIMISM, linkToken.address, linkEthFeed.address, gasPriceFeed.address, @@ -922,7 +958,6 @@ describe('AutomationRegistry2_2', () => { mgRegistry = await deployRegistry22( owner, - Mode.DEFAULT, linkToken.address, linkEthFeed.address, gasPriceFeed.address, @@ -931,7 +966,6 @@ describe('AutomationRegistry2_2', () => { blankRegistry = await deployRegistry22( owner, - Mode.DEFAULT, linkToken.address, linkEthFeed.address, gasPriceFeed.address, @@ -945,8 +979,11 @@ describe('AutomationRegistry2_2', () => { await registry.getPerPerformByteGasOverhead() cancellationDelay = (await registry.getCancellationDelay()).toNumber() + await registry.connect(owner).setConfig(...baseConfig) + await mgRegistry.connect(owner).setConfig(...baseConfig) + await arbRegistry.connect(owner).setConfig(...arbConfigParams) + await opRegistry.connect(owner).setConfig(...opConfigParams) for (const reg of [registry, arbRegistry, opRegistry, mgRegistry]) { - await reg.connect(owner).setConfig(...baseConfig) await reg.connect(owner).setPayees(payees) await linkToken.connect(admin).approve(reg.address, toWei('1000')) await linkToken.connect(owner).approve(reg.address, toWei('1000')) @@ -2735,12 +2772,12 @@ describe('AutomationRegistry2_2', () => { // upkeep 1 perform should succeed with empty performData await getTransmitTx(registry, keeper1, [upkeepID1], { gasPrice: gasWei.mul(gasCeilingMultiplier), - }), - // upkeep 2 perform should succeed with max performData size - await getTransmitTx(registry, keeper1, [upkeepID2], { - gasPrice: gasWei.mul(gasCeilingMultiplier), - performData: maxPerformData, - }) + }) + // upkeep 2 perform should succeed with max performData size + await getTransmitTx(registry, keeper1, [upkeepID2], { + gasPrice: gasWei.mul(gasCeilingMultiplier), + performData: maxPerformData, + }) }) }) @@ -3247,15 +3284,15 @@ describe('AutomationRegistry2_2', () => { const l1CostWeiArb = arbL1PriceinWei.mul(16).mul(maxPerformDataSize) const l1CostWeiOpt = BigNumber.from(2000000) // Same as MockOVMGasPriceOracle.sol itMaybe('calculates the max fee appropriately', async () => { - await verifyMaxPayment(registry) + await verifyMaxPayment(registry, chainModuleBase.address) }) itMaybe('calculates the max fee appropriately for Arbitrum', async () => { - await verifyMaxPayment(arbRegistry, l1CostWeiArb) + await verifyMaxPayment(arbRegistry, arbitrumModule.address, l1CostWeiArb) }) itMaybe('calculates the max fee appropriately for Optimism', async () => { - await verifyMaxPayment(opRegistry, l1CostWeiOpt) + await verifyMaxPayment(opRegistry, optimismModule.address, l1CostWeiOpt) }) it('uses the fallback gas price if the feed has issues', async () => { @@ -3436,7 +3473,7 @@ describe('AutomationRegistry2_2', () => { }) }) - describeMaybe('#setConfig - onchain', () => { + describeMaybe('#setConfig - onchain', async () => { const payment = BigNumber.from(1) const flatFee = BigNumber.from(2) const maxGas = BigNumber.from(6) @@ -3469,6 +3506,7 @@ describe('AutomationRegistry2_2', () => { transcoder: newTranscoder, registrars: newRegistrars, upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, reorgProtectionEnabled: true, } @@ -3804,23 +3842,21 @@ describe('AutomationRegistry2_2', () => { for (let i = 0; i < signerAddresses.length; i++) { const signer = signerAddresses[i] if (!newSigners.includes(signer)) { - assert((await registry.getSignerInfo(signer)).active == false) + assert(!(await registry.getSignerInfo(signer)).active) assert((await registry.getSignerInfo(signer)).index == 0) } } // New signer addresses should be active for (let i = 0; i < newSigners.length; i++) { const signer = newSigners[i] - assert((await registry.getSignerInfo(signer)).active == true) + assert((await registry.getSignerInfo(signer)).active) assert((await registry.getSignerInfo(signer)).index == i) } // Old transmitter addresses which are not in new transmitter should be non active, update lastCollected but retain other info for (let i = 0; i < keeperAddresses.length; i++) { const transmitter = keeperAddresses[i] if (!newKeepers.includes(transmitter)) { - assert( - (await registry.getTransmitterInfo(transmitter)).active == false, - ) + assert(!(await registry.getTransmitterInfo(transmitter)).active) assert((await registry.getTransmitterInfo(transmitter)).index == i) assert( (await registry.getTransmitterInfo(transmitter)).lastCollected.eq( @@ -3834,7 +3870,7 @@ describe('AutomationRegistry2_2', () => { // New transmitter addresses should be active for (let i = 0; i < newKeepers.length; i++) { const transmitter = newKeepers[i] - assert((await registry.getTransmitterInfo(transmitter)).active == true) + assert((await registry.getTransmitterInfo(transmitter)).active) assert((await registry.getTransmitterInfo(transmitter)).index == i) assert( (await registry.getTransmitterInfo(transmitter)).lastCollected.eq( @@ -4463,6 +4499,7 @@ describe('AutomationRegistry2_2', () => { transcoder: transcoder.address, registrars: [], upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, reorgProtectionEnabled: true, }, offchainVersion, @@ -4685,7 +4722,7 @@ describe('AutomationRegistry2_2', () => { expect((await registry.getState()).state.numUpkeeps).to.equal( numUpkeeps, ) - const forwarder = await IAutomationForwarderFactory.connect( + const forwarder = IAutomationForwarderFactory.connect( forwarderAddress, owner, ) @@ -5104,6 +5141,7 @@ describe('AutomationRegistry2_2', () => { transcoder: transcoder.address, registrars: [], upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, reorgProtectionEnabled: true, }, offchainVersion, @@ -5158,6 +5196,7 @@ describe('AutomationRegistry2_2', () => { transcoder: transcoder.address, registrars: [], upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, reorgProtectionEnabled: true, }, offchainVersion, @@ -5207,6 +5246,7 @@ describe('AutomationRegistry2_2', () => { transcoder: transcoder.address, registrars: [], upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, reorgProtectionEnabled: true, }, offchainVersion, diff --git a/contracts/test/v0.8/automation/helpers.ts b/contracts/test/v0.8/automation/helpers.ts index 32086f62e85..b3b4f0ef8b4 100644 --- a/contracts/test/v0.8/automation/helpers.ts +++ b/contracts/test/v0.8/automation/helpers.ts @@ -35,13 +35,12 @@ export const deployRegistry21 = async ( export const deployRegistry22 = async ( from: Signer, - mode: Parameters[0], - link: Parameters[1], - linkNative: Parameters[2], - fastgas: Parameters[3], + link: Parameters[0], + linkNative: Parameters[1], + fastgas: Parameters[2], allowedReadOnlyAddress: Parameters< AutomationRegistryLogicBFactory['deploy'] - >[4], + >[3], ): Promise => { const logicBFactory = await ethers.getContractFactory( 'AutomationRegistryLogicB2_2', @@ -59,7 +58,6 @@ export const deployRegistry22 = async ( const logicB = await logicBFactory .connect(from) .deploy( - mode, link, linkNative, fastgas, diff --git a/core/gethwrappers/generated/automation_utils_2_2/automation_utils_2_2.go b/core/gethwrappers/generated/automation_utils_2_2/automation_utils_2_2.go index 745cca66170..187193cb956 100644 --- a/core/gethwrappers/generated/automation_utils_2_2/automation_utils_2_2.go +++ b/core/gethwrappers/generated/automation_utils_2_2/automation_utils_2_2.go @@ -57,6 +57,7 @@ type AutomationRegistryBase22OnchainConfig struct { Transcoder common.Address Registrars []common.Address UpkeepPrivilegeManager common.Address + ChainModule common.Address ReorgProtectionEnabled bool } @@ -90,8 +91,8 @@ type LogTriggerConfig struct { } var AutomationUtilsMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structAutomationRegistryBase2_2.ConditionalTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_conditionalTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_log\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"logBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structAutomationRegistryBase2_2.LogTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"filterSelector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"internalType\":\"structLogTriggerConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_onChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimits\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"triggers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"performDatas\",\"type\":\"bytes[]\"}],\"internalType\":\"structAutomationRegistryBase2_2.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506108d0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063e32442c911610050578063e32442c9146100a6578063e65d6546146100b4578063e9720a49146100c257600080fd5b806321f373d7146100775780634b6df2941461008a578063776f306114610098575b600080fd5b6100886100853660046101e8565b50565b005b61008861008536600461026e565b6100886100853660046102c5565b61008861008536600461042a565b610088610085366004610701565b6100886100853660046107ee565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715610122576101226100d0565b60405290565b604051610200810167ffffffffffffffff81118282101715610122576101226100d0565b604051610100810167ffffffffffffffff81118282101715610122576101226100d0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101b7576101b76100d0565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101e357600080fd5b919050565b600060c082840312156101fa57600080fd5b6102026100ff565b61020b836101bf565b8152602083013560ff8116811461022157600080fd5b8060208301525060408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b803563ffffffff811681146101e357600080fd5b60006040828403121561028057600080fd5b6040516040810181811067ffffffffffffffff821117156102a3576102a36100d0565b6040526102af8361025a565b8152602083013560208201528091505092915050565b600060a082840312156102d757600080fd5b60405160a0810181811067ffffffffffffffff821117156102fa576102fa6100d0565b806040525082358152602083013560208201526103196040840161025a565b604082015261032a6060840161025a565b6060820152608083013560808201528091505092915050565b803562ffffff811681146101e357600080fd5b803561ffff811681146101e357600080fd5b80356bffffffffffffffffffffffff811681146101e357600080fd5b600067ffffffffffffffff82111561039e5761039e6100d0565b5060051b60200190565b600082601f8301126103b957600080fd5b813560206103ce6103c983610384565b610170565b82815260059290921b840181019181810190868411156103ed57600080fd5b8286015b8481101561040f57610402816101bf565b83529183019183016103f1565b509695505050505050565b803580151581146101e357600080fd5b60006020828403121561043c57600080fd5b813567ffffffffffffffff8082111561045457600080fd5b90830190610200828603121561046957600080fd5b610471610128565b61047a8361025a565b81526104886020840161025a565b60208201526104996040840161025a565b60408201526104aa60608401610343565b60608201526104bb60808401610356565b60808201526104cc60a08401610368565b60a08201526104dd60c0840161025a565b60c08201526104ee60e0840161025a565b60e082015261010061050181850161025a565b9082015261012061051384820161025a565b908201526101408381013590820152610160808401359082015261018061053b8185016101bf565b908201526101a0838101358381111561055357600080fd5b61055f888287016103a8565b8284015250506101c091506105758284016101bf565b828201526101e0915061058982840161041a565b91810191909152949350505050565b600082601f8301126105a957600080fd5b813560206105b96103c983610384565b82815260059290921b840181019181810190868411156105d857600080fd5b8286015b8481101561040f57803583529183019183016105dc565b600082601f83011261060457600080fd5b813567ffffffffffffffff81111561061e5761061e6100d0565b61064f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610170565b81815284602083860101111561066457600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261069257600080fd5b813560206106a26103c983610384565b82815260059290921b840181019181810190868411156106c157600080fd5b8286015b8481101561040f57803567ffffffffffffffff8111156106e55760008081fd5b6106f38986838b01016105f3565b8452509183019183016106c5565b60006020828403121561071357600080fd5b813567ffffffffffffffff8082111561072b57600080fd5b9083019060c0828603121561073f57600080fd5b6107476100ff565b823581526020830135602082015260408301358281111561076757600080fd5b61077387828601610598565b60408301525060608301358281111561078b57600080fd5b61079787828601610598565b6060830152506080830135828111156107af57600080fd5b6107bb87828601610681565b60808301525060a0830135828111156107d357600080fd5b6107df87828601610681565b60a08301525095945050505050565b60006020828403121561080057600080fd5b813567ffffffffffffffff8082111561081857600080fd5b90830190610100828603121561082d57600080fd5b61083561014c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261086d60a084016101bf565b60a082015260c08301358281111561088457600080fd5b61089087828601610598565b60c08301525060e0830135828111156108a857600080fd5b6108b4878286016105f3565b60e0830152509594505050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structAutomationRegistryBase2_2.ConditionalTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_conditionalTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_log\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"logBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structAutomationRegistryBase2_2.LogTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"filterSelector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"internalType\":\"structLogTriggerConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_onChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimits\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"triggers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"performDatas\",\"type\":\"bytes[]\"}],\"internalType\":\"structAutomationRegistryBase2_2.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506108f1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063a4860f2311610050578063a4860f23146100a6578063e65d6546146100b4578063e9720a49146100c257600080fd5b806321f373d7146100775780634b6df2941461008a578063776f306114610098575b600080fd5b6100886100853660046101f1565b50565b005b610088610085366004610279565b6100886100853660046102d0565b610088610085366004610437565b610088610085366004610722565b61008861008536600461080f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715610122576101226100d0565b60405290565b604051610220810167ffffffffffffffff81118282101715610122576101226100d0565b604051610100810167ffffffffffffffff81118282101715610122576101226100d0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101b7576101b76100d0565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461008557600080fd5b80356101ec816101bf565b919050565b600060c0828403121561020357600080fd5b61020b6100ff565b8235610216816101bf565b8152602083013560ff8116811461022c57600080fd5b8060208301525060408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b803563ffffffff811681146101ec57600080fd5b60006040828403121561028b57600080fd5b6040516040810181811067ffffffffffffffff821117156102ae576102ae6100d0565b6040526102ba83610265565b8152602083013560208201528091505092915050565b600060a082840312156102e257600080fd5b60405160a0810181811067ffffffffffffffff82111715610305576103056100d0565b8060405250823581526020830135602082015261032460408401610265565b604082015261033560608401610265565b6060820152608083013560808201528091505092915050565b803562ffffff811681146101ec57600080fd5b803561ffff811681146101ec57600080fd5b80356bffffffffffffffffffffffff811681146101ec57600080fd5b600067ffffffffffffffff8211156103a9576103a96100d0565b5060051b60200190565b600082601f8301126103c457600080fd5b813560206103d96103d48361038f565b610170565b82815260059290921b840181019181810190868411156103f857600080fd5b8286015b8481101561041c57803561040f816101bf565b83529183019183016103fc565b509695505050505050565b803580151581146101ec57600080fd5b60006020828403121561044957600080fd5b813567ffffffffffffffff8082111561046157600080fd5b90830190610220828603121561047657600080fd5b61047e610128565b61048783610265565b815261049560208401610265565b60208201526104a660408401610265565b60408201526104b76060840161034e565b60608201526104c860808401610361565b60808201526104d960a08401610373565b60a08201526104ea60c08401610265565b60c08201526104fb60e08401610265565b60e082015261010061050e818501610265565b90820152610120610520848201610265565b90820152610140838101359082015261016080840135908201526101806105488185016101e1565b908201526101a0838101358381111561056057600080fd5b61056c888287016103b3565b8284015250506101c091506105828284016101e1565b828201526101e091506105968284016101e1565b8282015261020091506105aa828401610427565b91810191909152949350505050565b600082601f8301126105ca57600080fd5b813560206105da6103d48361038f565b82815260059290921b840181019181810190868411156105f957600080fd5b8286015b8481101561041c57803583529183019183016105fd565b600082601f83011261062557600080fd5b813567ffffffffffffffff81111561063f5761063f6100d0565b61067060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610170565b81815284602083860101111561068557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126106b357600080fd5b813560206106c36103d48361038f565b82815260059290921b840181019181810190868411156106e257600080fd5b8286015b8481101561041c57803567ffffffffffffffff8111156107065760008081fd5b6107148986838b0101610614565b8452509183019183016106e6565b60006020828403121561073457600080fd5b813567ffffffffffffffff8082111561074c57600080fd5b9083019060c0828603121561076057600080fd5b6107686100ff565b823581526020830135602082015260408301358281111561078857600080fd5b610794878286016105b9565b6040830152506060830135828111156107ac57600080fd5b6107b8878286016105b9565b6060830152506080830135828111156107d057600080fd5b6107dc878286016106a2565b60808301525060a0830135828111156107f457600080fd5b610800878286016106a2565b60a08301525095945050505050565b60006020828403121561082157600080fd5b813567ffffffffffffffff8082111561083957600080fd5b90830190610100828603121561084e57600080fd5b61085661014c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261088e60a084016101e1565b60a082015260c0830135828111156108a557600080fd5b6108b1878286016105b9565b60c08301525060e0830135828111156108c957600080fd5b6108d587828601610614565b60e0830152509594505050505056fea164736f6c6343000813000a", } var AutomationUtilsABI = AutomationUtilsMetaData.ABI diff --git a/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go b/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go index a00ae9595cf..829f3a57e4b 100644 --- a/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go +++ b/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go @@ -46,6 +46,7 @@ type AutomationRegistryBase22OnchainConfig struct { Transcoder common.Address Registrars []common.Address UpkeepPrivilegeManager common.Address + ChainModule common.Address ReorgProtectionEnabled bool } @@ -94,7 +95,7 @@ type AutomationRegistryBase22UpkeepInfo struct { } var IAutomationRegistryMasterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMode\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"setChainSpecificModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var IAutomationRegistryMasterABI = IAutomationRegistryMasterMetaData.ABI @@ -471,6 +472,28 @@ func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetCan return _IAutomationRegistryMaster.Contract.GetCancellationDelay(&_IAutomationRegistryMaster.CallOpts) } +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetChainModule(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getChainModule") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetChainModule() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetChainModule(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetChainModule() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetChainModule(&_IAutomationRegistryMaster.CallOpts) +} + func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getConditionalGasOverhead") @@ -669,28 +692,6 @@ func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetMin return _IAutomationRegistryMaster.Contract.GetMinBalanceForUpkeep(&_IAutomationRegistryMaster.CallOpts, id) } -func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetMode(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getMode") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) - - return out0, err - -} - -func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetMode() (uint8, error) { - return _IAutomationRegistryMaster.Contract.GetMode(&_IAutomationRegistryMaster.CallOpts) -} - -func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetMode() (uint8, error) { - return _IAutomationRegistryMaster.Contract.GetMode(&_IAutomationRegistryMaster.CallOpts) -} - func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) { var out []interface{} err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getPeerRegistryMigrationPermission", peer) @@ -1345,6 +1346,18 @@ func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) Se return _IAutomationRegistryMaster.Contract.SetAdminPrivilegeConfig(&_IAutomationRegistryMaster.TransactOpts, admin, newPrivilegeConfig) } +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setChainSpecificModule", newModule) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetChainSpecificModule(&_IAutomationRegistryMaster.TransactOpts, newModule) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetChainSpecificModule(&_IAutomationRegistryMaster.TransactOpts, newModule) +} + func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { return _IAutomationRegistryMaster.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } @@ -1829,6 +1842,123 @@ func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseCancel return event, nil } +type IAutomationRegistryMasterChainSpecificModuleUpdatedIterator struct { + Event *IAutomationRegistryMasterChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*IAutomationRegistryMasterChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterChainSpecificModuleUpdatedIterator{contract: _IAutomationRegistryMaster.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*IAutomationRegistryMasterChainSpecificModuleUpdated, error) { + event := new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type IAutomationRegistryMasterConfigSetIterator struct { Event *IAutomationRegistryMasterConfigSet @@ -5936,6 +6066,8 @@ func (_IAutomationRegistryMaster *IAutomationRegistryMaster) ParseLog(log types. return _IAutomationRegistryMaster.ParseAdminPrivilegeConfigSet(log) case _IAutomationRegistryMaster.abi.Events["CancelledUpkeepReport"].ID: return _IAutomationRegistryMaster.ParseCancelledUpkeepReport(log) + case _IAutomationRegistryMaster.abi.Events["ChainSpecificModuleUpdated"].ID: + return _IAutomationRegistryMaster.ParseChainSpecificModuleUpdated(log) case _IAutomationRegistryMaster.abi.Events["ConfigSet"].ID: return _IAutomationRegistryMaster.ParseConfigSet(log) case _IAutomationRegistryMaster.abi.Events["DedupKeyAdded"].ID: @@ -6012,6 +6144,10 @@ func (IAutomationRegistryMasterCancelledUpkeepReport) Topic() common.Hash { return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") } +func (IAutomationRegistryMasterChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + func (IAutomationRegistryMasterConfigSet) Topic() common.Hash { return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") } @@ -6167,6 +6303,8 @@ type IAutomationRegistryMasterInterface interface { GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) + GetChainModule(opts *bind.CallOpts) (common.Address, error) + GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) @@ -6185,8 +6323,6 @@ type IAutomationRegistryMasterInterface interface { GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) - GetMode(opts *bind.CallOpts) (uint8, error) - GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) GetPerPerformByteGasOverhead(opts *bind.CallOpts) (*big.Int, error) @@ -6267,6 +6403,8 @@ type IAutomationRegistryMasterInterface interface { SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) + SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) + SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase22OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) @@ -6317,6 +6455,12 @@ type IAutomationRegistryMasterInterface interface { ParseCancelledUpkeepReport(log types.Log) (*IAutomationRegistryMasterCancelledUpkeepReport, error) + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*IAutomationRegistryMasterChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*IAutomationRegistryMasterChainSpecificModuleUpdated, error) + FilterConfigSet(opts *bind.FilterOpts) (*IAutomationRegistryMasterConfigSetIterator, error) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterConfigSet) (event.Subscription, error) diff --git a/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go b/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go index 1c2db92f8a2..942459c7eda 100644 --- a/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go +++ b/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go @@ -31,8 +31,8 @@ var ( ) var AutomationRegistryLogicAMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101606040523480156200001257600080fd5b50604051620062773803806200627783398101604081905262000035916200044b565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000472565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200044b565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200044b565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200044b565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200044b565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200044b565b3380600081620002eb5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200031e576200031e8162000387565b50505085600281111562000336576200033662000495565b60e08160028111156200034d576200034d62000495565b9052506001600160a01b0394851660805292841660a05290831660c052821661010052811661012052919091166101405250620004ab9050565b336001600160a01b03821603620003e15760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620002e2565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200044857600080fd5b50565b6000602082840312156200045e57600080fd5b81516200046b8162000432565b9392505050565b6000602082840312156200048557600080fd5b8151600381106200046b57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e051610100516101205161014051615d47620005306000396000818161010e01526101a901526000612f590152600081816103e10152611fbd015260008181613590015281816137c601528181613a0e0152613bb60152600061313a0152600061321e015260008181611dff01526123cb0152615d476000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b6200016536600462004243565b62000313565b6040519081526020015b60405180910390f35b620001956200018f36600462004329565b6200068d565b60405162000175949392919062004451565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b62000152620002003660046200448e565b62000931565b6200016b62000217366004620044de565b62000999565b620002346200022e36600462004329565b620009ff565b60405162000175979695949392919062004591565b620001526200110c565b6200015262000264366004620045e3565b6200120f565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a36600462004670565b62001e80565b62000152620002b1366004620046d3565b62002208565b62000152620002c836600462004702565b6200249b565b62000195620002df366004620047d8565b62002862565b62000152620002f63660046200484f565b62002928565b620002346200030d36600462004702565b62002940565b6000805473ffffffffffffffffffffffffffffffffffffffff163314801590620003475750620003456009336200297e565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d986620029b2565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003fd4565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002b569050565b6015805474010000000000000000000000000000000000000000900463ffffffff169060146200054f836200489e565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c892919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8787604051620006049291906200490d565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063e919062004923565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508460405162000678919062004923565b60405180910390a25098975050505050505050565b600060606000806200069e62002f41565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007de919062004945565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168960405162000820919062004965565b60006040518083038160008787f1925050503d806000811462000860576040519150601f19603f3d011682016040523d82523d6000602084013e62000865565b606091505b50915091505a62000877908562004983565b935081620008a257600060405180602001604052806000815250600796509650965050505062000928565b80806020019051810190620008b89190620049f4565b909750955086620008e657600060405180602001604052806000815250600496509650965050505062000928565b601654865164010000000090910463ffffffff1610156200092457600060405180602001604052806000815250600596509650965050505062000928565b5050505b92959194509250565b6200093c8362002fb3565b6000838152601b602052604090206200095782848362004ae9565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098c9291906200490d565b60405180910390a2505050565b6000620009f388888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a1562002f41565b600062000a228a62003069565b905060006012604051806101400160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160189054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201601b9054906101000a900461ffff1661ffff1661ffff16815260200160008201601d9054906101000a900460ff1660ff1660ff16815260200160008201601e9054906101000a900460ff1615151515815260200160008201601f9054906101000a900460ff161515151581526020016001820160009054906101000a900460ff16151515158152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160e001511562000d61576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001100565b604081015163ffffffff9081161462000db2576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001100565b80511562000df8576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001100565b62000e038262003117565b602083015160165492975090955060009162000e35918591879190640100000000900463ffffffff168a8a8762003309565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000e9f576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001100565b600062000eae8e868f6200335a565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f06573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f2c919062004945565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168460405162000f6e919062004965565b60006040518083038160008787f1925050503d806000811462000fae576040519150601f19603f3d011682016040523d82523d6000602084013e62000fb3565b606091505b50915091505a62000fc5908c62004983565b9a5081620010455760165481516801000000000000000090910463ffffffff1610156200102257505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200110092505050565b602090940151939b5060039a505063ffffffff9092169650620011009350505050565b808060200190518101906200105b9190620049f4565b909e509c508d6200109c57505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200110092505050565b6016548d5164010000000090910463ffffffff161015620010ed57505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200110092505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff16331462001193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff1660038111156200124e576200124e620043e6565b141580156200129a5750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012975762001297620043e6565b14155b15620012d2576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001332576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008290036200136e576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff811115620013c557620013c5620040ca565b604051908082528060200260200182016040528015620013ef578160200160208202803683370190505b50905060008667ffffffffffffffff811115620014105762001410620040ca565b6040519080825280602002602001820160405280156200149757816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816200142f5790505b50905060008767ffffffffffffffff811115620014b857620014b8620040ca565b604051908082528060200260200182016040528015620014ed57816020015b6060815260200190600190039081620014d75790505b50905060008867ffffffffffffffff8111156200150e576200150e620040ca565b6040519080825280602002602001820160405280156200154357816020015b60608152602001906001900390816200152d5790505b50905060008967ffffffffffffffff811115620015645762001564620040ca565b6040519080825280602002602001820160405280156200159957816020015b6060815260200190600190039081620015835790505b50905060005b8a81101562001b7d578b8b82818110620015bd57620015bd62004c11565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a509098506200169c90508962002fb3565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200170c57600080fd5b505af115801562001721573d6000803e3d6000fd5b50505050878582815181106200173b576200173b62004c11565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168682815181106200178f576200178f62004c11565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a81526007909152604090208054620017ce9062004a41565b80601f0160208091040260200160405190810160405280929190818152602001828054620017fc9062004a41565b80156200184d5780601f1062001821576101008083540402835291602001916200184d565b820191906000526020600020905b8154815290600101906020018083116200182f57829003601f168201915b505050505084828151811062001867576200186762004c11565b6020026020010181905250601b60008a81526020019081526020016000208054620018929062004a41565b80601f0160208091040260200160405190810160405280929190818152602001828054620018c09062004a41565b8015620019115780601f10620018e55761010080835404028352916020019162001911565b820191906000526020600020905b815481529060010190602001808311620018f357829003601f168201915b50505050508382815181106200192b576200192b62004c11565b6020026020010181905250601c60008a81526020019081526020016000208054620019569062004a41565b80601f0160208091040260200160405190810160405280929190818152602001828054620019849062004a41565b8015620019d55780601f10620019a957610100808354040283529160200191620019d5565b820191906000526020600020905b815481529060010190602001808311620019b757829003601f168201915b5050505050828281518110620019ef57620019ef62004c11565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a1a919062004c40565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001a90919062003fe2565b6000898152601b6020526040812062001aa99162003fe2565b6000898152601c6020526040812062001ac29162003fe2565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b0360028a6200357c565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001b748162004c56565b9150506200159f565b508560195462001b8e919062004983565b60195560008b8b868167ffffffffffffffff81111562001bb25762001bb2620040ca565b60405190808252806020026020018201604052801562001bdc578160200160208202803683370190505b508988888860405160200162001bfa98979695949392919062004dfc565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6014600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001cb6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cdc919062004ecc565b866040518463ffffffff1660e01b815260040162001cfd9392919062004ef1565b600060405180830381865afa15801562001d1b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001d63919081019062004f18565b6040518263ffffffff1660e01b815260040162001d81919062004923565b600060405180830381600087803b15801562001d9c57600080fd5b505af115801562001db1573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001e4b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001e71919062004f51565b50505050505050505050505050565b6002336000908152601a602052604090205460ff16600381111562001ea95762001ea9620043e6565b1415801562001edf57506003336000908152601a602052604090205460ff16600381111562001edc5762001edc620043e6565b14155b1562001f17576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f2d888a018a62005149565b965096509650965096509650965060005b8751811015620021fc57600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001f755762001f7562004c11565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020895785818151811062001fb25762001fb262004c11565b6020026020010151307f000000000000000000000000000000000000000000000000000000000000000060405162001fea9062003fd4565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562002034573d6000803e3d6000fd5b508782815181106200204a576200204a62004c11565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62002141888281518110620020a257620020a262004c11565b6020026020010151888381518110620020bf57620020bf62004c11565b6020026020010151878481518110620020dc57620020dc62004c11565b6020026020010151878581518110620020f957620020f962004c11565b602002602001015187868151811062002116576200211662004c11565b602002602001015187878151811062002133576200213362004c11565b602002602001015162002b56565b87818151811062002156576200215662004c11565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a7188838151811062002194576200219462004c11565b602002602001015160a0015133604051620021df9291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620021f38162004c56565b91505062001f3e565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c0820152911462002306576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a001516200231891906200527a565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601954620023809184169062004c40565b6019556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156200242a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002450919062004f51565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff6101008204811695830195909552650100000000008104851693820184905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004831660c082015292911415906200258460005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16149050818015620025df5750808015620025dd5750620025d06200358a565b836040015163ffffffff16115b155b1562002617576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801580156200264a575060008481526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562002682576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006200268e6200358a565b905081620026a657620026a360328262004c40565b90505b6000858152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620027029060029087906200357c16565b5060145460808501516bffffffffffffffffffffffff91821691600091168211156200276b576080860151620027399083620052a2565b90508560a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156200276b575060a08501515b808660a001516200277d9190620052a2565b600088815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601554620027e5918391166200527a565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169088907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a350505050505050565b600060606000806000634b56a42e60e01b8888886040516024016200288a93929190620052ca565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506200291589826200068d565b929c919b50995090975095505050505050565b6200293262003646565b6200293d81620036c9565b50565b600060606000806000806000620029678860405180602001604052806000815250620009ff565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000620029d96001620029c76200358a565b620029d3919062004983565b620037c0565b601554604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002ae5578282828151811062002aa15762002aa162004c11565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002adc8162004c56565b91505062002a81565b5083600181111562002afb5762002afb620043e6565b60f81b81600f8151811062002b145762002b1462004c11565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002b4e81620052fe565b949350505050565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff161562002bb6576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654835163ffffffff909116101562002bfc576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002c3a5750601554602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002c72576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002cdc576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169189169190911790556007909152902062002ecf848262005341565b508460a001516bffffffffffffffffffffffff1660195462002ef2919062004c40565b6019556000868152601b6020526040902062002f0f838262005341565b506000868152601c6020526040902062002f2a828262005341565b5062002f3860028762003928565b50505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161462002fb1576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16331462003011576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff908116146200293d576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620030fe577fff000000000000000000000000000000000000000000000000000000000000008216838260208110620030b257620030b262004c11565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620030e957506000949350505050565b80620030f58162004c56565b91505062003070565b5081600f1a600181111562002b4e5762002b4e620043e6565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015620031a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620031ca919062005483565b5094509092505050600081131580620031e257508142105b80620032075750828015620032075750620031fe824262004983565b8463ffffffff16105b15620032185760175495506200321c565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562003288573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620032ae919062005483565b5094509092505050600081131580620032c657508142105b80620032eb5750828015620032eb5750620032e2824262004983565b8463ffffffff16105b15620032fc57601854945062003300565b8094505b50505050915091565b6000806200331d88878b60c0015162003936565b90506000806200333a8b8a63ffffffff16858a8a60018b620039d5565b90925090506200334b81836200527a565b9b9a5050505050505050505050565b60606000836001811115620033735762003373620043e6565b0362003440576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620033bb916024016200557b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905062003575565b6001836001811115620034575762003457620043e6565b036200354357600082806020019051810190620034759190620055f2565b6000868152600760205260409081902090519192507f40691db40000000000000000000000000000000000000000000000000000000091620034bc91849160240162005706565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529150620035759050565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9392505050565b6000620029a9838362003e77565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115620035c357620035c3620043e6565b036200364157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562003616573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200363c9190620057ce565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff16331462002fb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016200118a565b3373ffffffffffffffffffffffffffffffffffffffff8216036200374a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200118a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115620037f957620037f9620043e6565b036200391e576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200384e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620038749190620057ce565b9050808310158062003892575061010062003890848362004983565b115b15620038a15750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015620038f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620035759190620057ce565b504090565b919050565b6000620029a9838362003f82565b600080808560018111156200394f576200394f620043e6565b0362003960575062015f9062003983565b6001856001811115620039775762003977620043e6565b036200354357506201adb05b6200399663ffffffff85166014620057e8565b620039a384600162005802565b620039b49060ff16611d4c620057e8565b620039c0908362004c40565b620039cc919062004c40565b95945050505050565b60008060008960a0015161ffff1687620039f09190620057e8565b9050838015620039ff5750803a105b1562003a0857503a5b600060027f0000000000000000000000000000000000000000000000000000000000000000600281111562003a415762003a41620043e6565b0362003bb257604080516000815260208101909152851562003aa55760003660405180608001604052806048815260200162005cf36048913960405160200162003a8e939291906200581e565b604051602081830303815290604052905062003b13565b60165462003ac390640100000000900463ffffffff16600462005847565b63ffffffff1667ffffffffffffffff81111562003ae45762003ae4620040ca565b6040519080825280601f01601f19166020018201604052801562003b0f576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e9062003b6590849060040162004923565b602060405180830381865afa15801562003b83573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003ba99190620057ce565b91505062003d1c565b60017f0000000000000000000000000000000000000000000000000000000000000000600281111562003be95762003be9620043e6565b0362003d1c57841562003c7157606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562003c43573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003c699190620057ce565b905062003d1c565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801562003cc0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003ce6919062005872565b505060165492945062003d0b93505050640100000000900463ffffffff1682620057e8565b62003d18906010620057e8565b9150505b8462003d3b57808b60a0015161ffff1662003d389190620057e8565b90505b62003d4b61ffff871682620058bd565b90506000878262003d5d8c8e62004c40565b62003d699086620057e8565b62003d75919062004c40565b62003d8990670de0b6b3a7640000620057e8565b62003d959190620058bd565b905060008c6040015163ffffffff1664e8d4a5100062003db69190620057e8565b898e6020015163ffffffff16858f8862003dd19190620057e8565b62003ddd919062004c40565b62003ded90633b9aca00620057e8565b62003df99190620057e8565b62003e059190620058bd565b62003e11919062004c40565b90506b033b2e3c9fd0803ce800000062003e2c828462004c40565b111562003e65576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000818152600183016020526040812054801562003f7057600062003e9e60018362004983565b855490915060009062003eb49060019062004983565b905081811462003f2057600086600001828154811062003ed85762003ed862004c11565b906000526020600020015490508087600001848154811062003efe5762003efe62004c11565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003f345762003f34620058f9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620029ac565b6000915050620029ac565b5092915050565b600081815260018301602052604081205462003fcb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620029ac565b506000620029ac565b6103ca806200592983390190565b50805462003ff09062004a41565b6000825580601f1062004001575050565b601f0160209004906000526020600020908101906200293d91905b808211156200403257600081556001016200401c565b5090565b73ffffffffffffffffffffffffffffffffffffffff811681146200293d57600080fd5b803563ffffffff811681146200392357600080fd5b8035600281106200392357600080fd5b60008083601f8401126200409157600080fd5b50813567ffffffffffffffff811115620040aa57600080fd5b602083019150836020828501011115620040c357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff811182821017156200411f576200411f620040ca565b60405290565b604051610100810167ffffffffffffffff811182821017156200411f576200411f620040ca565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715620041965762004196620040ca565b604052919050565b600067ffffffffffffffff821115620041bb57620041bb620040ca565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620041f957600080fd5b8135620042106200420a826200419e565b6200414c565b8181528460208386010111156200422657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200426057600080fd5b88356200426d8162004036565b97506200427d60208a0162004059565b965060408901356200428f8162004036565b95506200429f60608a016200406e565b9450608089013567ffffffffffffffff80821115620042bd57600080fd5b620042cb8c838d016200407e565b909650945060a08b0135915080821115620042e557600080fd5b620042f38c838d01620041e7565b935060c08b01359150808211156200430a57600080fd5b50620043198b828c01620041e7565b9150509295985092959890939650565b600080604083850312156200433d57600080fd5b82359150602083013567ffffffffffffffff8111156200435c57600080fd5b6200436a85828601620041e7565b9150509250929050565b60005b838110156200439157818101518382015260200162004377565b50506000910152565b60008151808452620043b481602086016020860162004374565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a81106200444d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b84151581526080602082015260006200446e60808301866200439a565b90506200447f604083018562004415565b82606083015295945050505050565b600080600060408486031215620044a457600080fd5b83359250602084013567ffffffffffffffff811115620044c357600080fd5b620044d1868287016200407e565b9497909650939450505050565b600080600080600080600060a0888a031215620044fa57600080fd5b8735620045078162004036565b9650620045176020890162004059565b95506040880135620045298162004036565b9450606088013567ffffffffffffffff808211156200454757600080fd5b620045558b838c016200407e565b909650945060808a01359150808211156200456f57600080fd5b506200457e8a828b016200407e565b989b979a50959850939692959293505050565b871515815260e060208201526000620045ae60e08301896200439a565b9050620045bf604083018862004415565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080600060408486031215620045f957600080fd5b833567ffffffffffffffff808211156200461257600080fd5b818601915086601f8301126200462757600080fd5b8135818111156200463757600080fd5b8760208260051b85010111156200464d57600080fd5b60209283019550935050840135620046658162004036565b809150509250925092565b600080602083850312156200468457600080fd5b823567ffffffffffffffff8111156200469c57600080fd5b620046aa858286016200407e565b90969095509350505050565b80356bffffffffffffffffffffffff811681146200392357600080fd5b60008060408385031215620046e757600080fd5b82359150620046f960208401620046b6565b90509250929050565b6000602082840312156200471557600080fd5b5035919050565b600067ffffffffffffffff821115620047395762004739620040ca565b5060051b60200190565b600082601f8301126200475557600080fd5b81356020620047686200420a836200471c565b82815260059290921b840181019181810190868411156200478857600080fd5b8286015b84811015620047cd57803567ffffffffffffffff811115620047ae5760008081fd5b620047be8986838b0101620041e7565b8452509183019183016200478c565b509695505050505050565b60008060008060608587031215620047ef57600080fd5b84359350602085013567ffffffffffffffff808211156200480f57600080fd5b6200481d8883890162004743565b945060408701359150808211156200483457600080fd5b5062004843878288016200407e565b95989497509550505050565b6000602082840312156200486257600080fd5b8135620035758162004036565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff808316818103620048ba57620048ba6200486f565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60208152600062002b4e602083018486620048c4565b602081526000620029a960208301846200439a565b8051620039238162004036565b6000602082840312156200495857600080fd5b8151620035758162004036565b600082516200497981846020870162004374565b9190910192915050565b81810381811115620029ac57620029ac6200486f565b80151581146200293d57600080fd5b600082601f830112620049ba57600080fd5b8151620049cb6200420a826200419e565b818152846020838601011115620049e157600080fd5b62002b4e82602083016020870162004374565b6000806040838503121562004a0857600080fd5b825162004a158162004999565b602084015190925067ffffffffffffffff81111562004a3357600080fd5b6200436a85828601620049a8565b600181811c9082168062004a5657607f821691505b60208210810362004a90577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111562004ae457600081815260208120601f850160051c8101602086101562004abf5750805b601f850160051c820191505b8181101562004ae05782815560010162004acb565b5050505b505050565b67ffffffffffffffff83111562004b045762004b04620040ca565b62004b1c8362004b15835462004a41565b8362004a96565b6000601f84116001811462004b71576000851562004b3a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835562004c0a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101562004bc2578685013582556020948501946001909201910162004ba0565b508682101562004bfe577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80820180821115620029ac57620029ac6200486f565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004c8a5762004c8a6200486f565b5060010190565b600081518084526020808501945080840160005b8381101562004d505781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004d2b828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004ca5565b509495945050505050565b600081518084526020808501945080840160005b8381101562004d5057815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004d6f565b600081518084526020808501808196508360051b8101915082860160005b8581101562004def57828403895262004ddc8483516200439a565b9885019893509084019060010162004dc1565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004e3957600080fd5b8960051b808c8386013783018381038201602085015262004e5d8282018b62004c91565b915050828103604084015262004e74818962004d5b565b9050828103606084015262004e8a818862004d5b565b9050828103608084015262004ea0818762004da3565b905082810360a084015262004eb6818662004da3565b905082810360c08401526200334b818562004da3565b60006020828403121562004edf57600080fd5b815160ff811681146200357557600080fd5b60ff8416815260ff83166020820152606060408201526000620039cc60608301846200439a565b60006020828403121562004f2b57600080fd5b815167ffffffffffffffff81111562004f4357600080fd5b62002b4e84828501620049a8565b60006020828403121562004f6457600080fd5b8151620035758162004999565b600082601f83011262004f8357600080fd5b8135602062004f966200420a836200471c565b82815260059290921b8401810191818101908684111562004fb657600080fd5b8286015b84811015620047cd578035835291830191830162004fba565b600082601f83011262004fe557600080fd5b8135602062004ff86200420a836200471c565b82815260e092830285018201928282019190878511156200501857600080fd5b8387015b85811015620050cf5781818a031215620050365760008081fd5b62005040620040f9565b81356200504d8162004999565b81526200505c82870162004059565b8682015260406200506f81840162004059565b90820152606082810135620050848162004036565b90820152608062005097838201620046b6565b9082015260a0620050aa838201620046b6565b9082015260c0620050bd83820162004059565b9082015284529284019281016200501c565b5090979650505050505050565b600082601f830112620050ee57600080fd5b81356020620051016200420a836200471c565b82815260059290921b840181019181810190868411156200512157600080fd5b8286015b84811015620047cd5780356200513b8162004036565b835291830191830162005125565b600080600080600080600060e0888a0312156200516557600080fd5b873567ffffffffffffffff808211156200517e57600080fd5b6200518c8b838c0162004f71565b985060208a0135915080821115620051a357600080fd5b620051b18b838c0162004fd3565b975060408a0135915080821115620051c857600080fd5b620051d68b838c01620050dc565b965060608a0135915080821115620051ed57600080fd5b620051fb8b838c01620050dc565b955060808a01359150808211156200521257600080fd5b620052208b838c0162004743565b945060a08a01359150808211156200523757600080fd5b620052458b838c0162004743565b935060c08a01359150808211156200525c57600080fd5b506200526b8a828b0162004743565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003f7b5762003f7b6200486f565b6bffffffffffffffffffffffff82811682821603908082111562003f7b5762003f7b6200486f565b604081526000620052df604083018662004da3565b8281036020840152620052f4818587620048c4565b9695505050505050565b8051602080830151919081101562004a90577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff8111156200535e576200535e620040ca565b62005376816200536f845462004a41565b8462004a96565b602080601f831160018114620053cc5760008415620053955750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562004ae0565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156200541b57888601518255948401946001909101908401620053fa565b50858210156200545857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff811681146200392357600080fd5b600080600080600060a086880312156200549c57600080fd5b620054a78662005468565b9450602086015193506040860151925060608601519150620054cc6080870162005468565b90509295509295909350565b60008154620054e78162004a41565b808552602060018381168015620055075760018114620055405762005570565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955062005570565b866000528260002060005b85811015620055685781548a82018601529083019084016200554b565b890184019650505b505050505092915050565b602081526000620029a96020830184620054d8565b600082601f830112620055a257600080fd5b81516020620055b56200420a836200471c565b82815260059290921b84018101918181019086841115620055d557600080fd5b8286015b84811015620047cd5780518352918301918301620055d9565b6000602082840312156200560557600080fd5b815167ffffffffffffffff808211156200561e57600080fd5b9083019061010082860312156200563457600080fd5b6200563e62004125565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200567860a0840162004938565b60a082015260c0830151828111156200569057600080fd5b6200569e8782860162005590565b60c08301525060e083015182811115620056b757600080fd5b620056c587828601620049a8565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004d5057815187529582019590820190600101620056e8565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c084015161010080818501525062005779610140840182620056d4565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084830301610120850152620057b782826200439a565b9150508281036020840152620039cc8185620054d8565b600060208284031215620057e157600080fd5b5051919050565b8082028115828204841417620029ac57620029ac6200486f565b60ff8181168382160190811115620029ac57620029ac6200486f565b8284823760008382016000815283516200583d81836020880162004374565b0195945050505050565b63ffffffff8181168382160280821691908281146200586a576200586a6200486f565b505092915050565b60008060008060008060c087890312156200588c57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600082620058f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000a307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b5060405162005e7538038062005e758339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051615a386200043d6000396000818161010e01526101a90152600061313b0152600081816103e101526120130152600061332401526000613408015260008181611e5501526124210152615a386000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b620001653660046200401b565b62000313565b6040519081526020015b60405180910390f35b620001956200018f36600462004101565b6200068d565b60405162000175949392919062004229565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b620001526200020036600462004266565b62000931565b6200016b62000217366004620042b6565b62000999565b620002346200022e36600462004101565b620009ff565b60405162000175979695949392919062004369565b6200015262001162565b6200015262000264366004620043bb565b62001265565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a36600462004448565b62001ed6565b62000152620002b1366004620044ab565b6200225e565b62000152620002c8366004620044da565b620024f1565b62000195620002df366004620045b0565b6200293c565b62000152620002f636600462004627565b62002a02565b620002346200030d366004620044da565b62002a1a565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200034757506200034560093362002a58565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d98662002a8c565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003da7565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002d389050565b6015805474010000000000000000000000000000000000000000900463ffffffff169060146200054f8362004676565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c892919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d878760405162000604929190620046e5565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063e9190620046fb565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf485084604051620006789190620046fb565b60405180910390a25098975050505050505050565b600060606000806200069e62003123565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007de91906200471d565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff16896040516200082091906200473d565b60006040518083038160008787f1925050503d806000811462000860576040519150601f19603f3d011682016040523d82523d6000602084013e62000865565b606091505b50915091505a6200087790856200475b565b935081620008a257600060405180602001604052806000815250600796509650965050505062000928565b80806020019051810190620008b89190620047cc565b909750955086620008e657600060405180602001604052806000815250600496509650965050505062000928565b601654865164010000000090910463ffffffff1610156200092457600060405180602001604052806000815250600596509650965050505062000928565b5050505b92959194509250565b6200093c8362003195565b6000838152601b6020526040902062000957828483620048c1565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098c929190620046e5565b60405180910390a2505050565b6000620009f388888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a1562003123565b600062000a228a6200324b565b905060006012604051806101600160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160189054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201601b9054906101000a900461ffff1661ffff1661ffff16815260200160008201601d9054906101000a900460ff1660ff1660ff16815260200160008201601e9054906101000a900460ff1615151515815260200160008201601f9054906101000a900460ff161515151581526020016001820160009054906101000a900460ff161515151581526020016001820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160e001511562000db7576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001156565b604081015163ffffffff9081161462000e08576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001156565b80511562000e4e576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001156565b62000e598262003301565b602083015160165492975090955060009162000e8b918591879190640100000000900463ffffffff168a8a87620034f3565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000ef5576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001156565b600062000f048e868f62003544565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f5c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f8291906200471d565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168460405162000fc491906200473d565b60006040518083038160008787f1925050503d806000811462001004576040519150601f19603f3d011682016040523d82523d6000602084013e62001009565b606091505b50915091505a6200101b908c6200475b565b9a50816200109b5760165481516801000000000000000090910463ffffffff1610156200107857505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200115692505050565b602090940151939b5060039a505063ffffffff9092169650620011569350505050565b80806020019051810190620010b19190620047cc565b909e509c508d620010f257505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200115692505050565b6016548d5164010000000090910463ffffffff1610156200114357505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200115692505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff163314620011e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012a457620012a4620041be565b14158015620012f05750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012ed57620012ed620041be565b14155b1562001328576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001388576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003620013c4576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff8111156200141b576200141b62003ea2565b60405190808252806020026020018201604052801562001445578160200160208202803683370190505b50905060008667ffffffffffffffff81111562001466576200146662003ea2565b604051908082528060200260200182016040528015620014ed57816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181620014855790505b50905060008767ffffffffffffffff8111156200150e576200150e62003ea2565b6040519080825280602002602001820160405280156200154357816020015b60608152602001906001900390816200152d5790505b50905060008867ffffffffffffffff81111562001564576200156462003ea2565b6040519080825280602002602001820160405280156200159957816020015b6060815260200190600190039081620015835790505b50905060008967ffffffffffffffff811115620015ba57620015ba62003ea2565b604051908082528060200260200182016040528015620015ef57816020015b6060815260200190600190039081620015d95790505b50905060005b8a81101562001bd3578b8b82818110620016135762001613620049e9565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a50909850620016f290508962003195565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200176257600080fd5b505af115801562001777573d6000803e3d6000fd5b5050505087858281518110620017915762001791620049e9565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868281518110620017e557620017e5620049e9565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a81526007909152604090208054620018249062004819565b80601f0160208091040260200160405190810160405280929190818152602001828054620018529062004819565b8015620018a35780601f106200187757610100808354040283529160200191620018a3565b820191906000526020600020905b8154815290600101906020018083116200188557829003601f168201915b5050505050848281518110620018bd57620018bd620049e9565b6020026020010181905250601b60008a81526020019081526020016000208054620018e89062004819565b80601f0160208091040260200160405190810160405280929190818152602001828054620019169062004819565b8015620019675780601f106200193b5761010080835404028352916020019162001967565b820191906000526020600020905b8154815290600101906020018083116200194957829003601f168201915b5050505050838281518110620019815762001981620049e9565b6020026020010181905250601c60008a81526020019081526020016000208054620019ac9062004819565b80601f0160208091040260200160405190810160405280929190818152602001828054620019da9062004819565b801562001a2b5780601f10620019ff5761010080835404028352916020019162001a2b565b820191906000526020600020905b81548152906001019060200180831162001a0d57829003601f168201915b505050505082828151811062001a455762001a45620049e9565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a70919062004a18565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001ae6919062003db5565b6000898152601b6020526040812062001aff9162003db5565b6000898152601c6020526040812062001b189162003db5565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b5960028a62003766565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001bca8162004a2e565b915050620015f5565b508560195462001be491906200475b565b60195560008b8b868167ffffffffffffffff81111562001c085762001c0862003ea2565b60405190808252806020026020018201604052801562001c32578160200160208202803683370190505b508988888860405160200162001c5098979695949392919062004bd4565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6014600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001d0c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d32919062004ca4565b866040518463ffffffff1660e01b815260040162001d539392919062004cc9565b600060405180830381865afa15801562001d71573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001db9919081019062004cf0565b6040518263ffffffff1660e01b815260040162001dd79190620046fb565b600060405180830381600087803b15801562001df257600080fd5b505af115801562001e07573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001ea1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ec7919062004d29565b50505050505050505050505050565b6002336000908152601a602052604090205460ff16600381111562001eff5762001eff620041be565b1415801562001f3557506003336000908152601a602052604090205460ff16600381111562001f325762001f32620041be565b14155b1562001f6d576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f83888a018a62004f21565b965096509650965096509650965060005b87518110156200225257600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001fcb5762001fcb620049e9565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020df57858181518110620020085762002008620049e9565b6020026020010151307f0000000000000000000000000000000000000000000000000000000000000000604051620020409062003da7565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f0801580156200208a573d6000803e3d6000fd5b50878281518110620020a057620020a0620049e9565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62002197888281518110620020f857620020f8620049e9565b6020026020010151888381518110620021155762002115620049e9565b6020026020010151878481518110620021325762002132620049e9565b60200260200101518785815181106200214f576200214f620049e9565b60200260200101518786815181106200216c576200216c620049e9565b6020026020010151878781518110620021895762002189620049e9565b602002602001015162002d38565b878181518110620021ac57620021ac620049e9565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620021ea57620021ea620049e9565b602002602001015160a0015133604051620022359291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620022498162004a2e565b91505062001f94565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c082015291146200235c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a001516200236e919062005052565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601954620023d69184169062004a18565b6019556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af115801562002480573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620024a6919062004d29565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff6101008204811695830195909552650100000000008104851693820184905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004831660c08201529291141590620025da60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490506000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200267d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026a391906200507a565b9050828015620026c75750818015620026c5575080846040015163ffffffff16115b155b15620026ff576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115801562002732575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b156200276a576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8162002780576200277d60328262004a18565b90505b6000858152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620027dc9060029087906200376616565b5060145460808501516bffffffffffffffffffffffff91821691600091168211156200284557608086015162002813908362005094565b90508560a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562002845575060a08501515b808660a0015162002857919062005094565b600088815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601554620028bf9183911662005052565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169088907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a350505050505050565b600060606000806000634b56a42e60e01b8888886040516024016200296493929190620050bc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050620029ef89826200068d565b929c919b50995090975095505050505050565b62002a0c62003774565b62002a1781620037f7565b50565b60006060600080600080600062002a418860405180602001604052806000815250620009ff565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166385df51fd60018473ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002b25573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b4b91906200507a565b62002b5791906200475b565b6040518263ffffffff1660e01b815260040162002b7691815260200190565b602060405180830381865afa15801562002b94573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002bba91906200507a565b601554604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002cc6578382828151811062002c825762002c82620049e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002cbd8162004a2e565b91505062002c62565b5084600181111562002cdc5762002cdc620041be565b60f81b81600f8151811062002cf55762002cf5620049e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002d2f81620050f0565b95945050505050565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff161562002d98576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654835163ffffffff909116101562002dde576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002e1c5750601554602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002e54576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002ebe576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691891691909117905560079091529020620030b1848262005133565b508460a001516bffffffffffffffffffffffff16601954620030d4919062004a18565b6019556000868152601b60205260409020620030f1838262005133565b506000868152601c602052604090206200310c828262005133565b506200311a600287620038ee565b50505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161462003193576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314620031f3576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161462002a17576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620032e0577fff000000000000000000000000000000000000000000000000000000000000008216838260208110620032945762003294620049e9565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620032cb57506000949350505050565b80620032d78162004a2e565b91505062003252565b5081600f1a6001811115620032f957620032f9620041be565b949350505050565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200338e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620033b4919062005275565b5094509092505050600081131580620033cc57508142105b80620033f15750828015620033f15750620033e882426200475b565b8463ffffffff16105b156200340257601754955062003406565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562003472573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003498919062005275565b5094509092505050600081131580620034b057508142105b80620034d55750828015620034d55750620034cc82426200475b565b8463ffffffff16105b15620034e6576018549450620034ea565b8094505b50505050915091565b6000806200350788878b60c00151620038fc565b9050600080620035248b8a63ffffffff16858a8a60018b62003992565b909250905062003535818362005052565b9b9a5050505050505050505050565b606060008360018111156200355d576200355d620041be565b036200362a576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620035a5916024016200536d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506200375f565b6001836001811115620036415762003641620041be565b036200372d576000828060200190518101906200365f9190620053e4565b6000868152600760205260409081902090519192507f40691db40000000000000000000000000000000000000000000000000000000091620036a6918491602401620054f8565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506200375f9050565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9392505050565b600062002a83838362003c4a565b60005473ffffffffffffffffffffffffffffffffffffffff16331462003193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620011e0565b3373ffffffffffffffffffffffffffffffffffffffff82160362003878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620011e0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600062002a83838362003d55565b60008080856001811115620039155762003915620041be565b0362003926575062015f9062003949565b60018560018111156200393d576200393d620041be565b036200372d57506201af405b6200395c63ffffffff85166014620055c0565b62003969846001620055da565b6200397a9060ff16611d4c620055c0565b62003986908362004a18565b62002d2f919062004a18565b60008060008960a0015161ffff1687620039ad9190620055c0565b9050838015620039bc5750803a105b15620039c557503a5b6000841562003a4d578a610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa15801562003a1f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003a4591906200507a565b905062003b0e565b6101408b01516016546040517f1254414000000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff90911690631254414090602401602060405180830381865afa15801562003ad0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003af691906200507a565b8b60a0015161ffff1662003b0b9190620055c0565b90505b62003b1e61ffff871682620055f6565b90506000878262003b308c8e62004a18565b62003b3c9086620055c0565b62003b48919062004a18565b62003b5c90670de0b6b3a7640000620055c0565b62003b689190620055f6565b905060008c6040015163ffffffff1664e8d4a5100062003b899190620055c0565b898e6020015163ffffffff16858f8862003ba49190620055c0565b62003bb0919062004a18565b62003bc090633b9aca00620055c0565b62003bcc9190620055c0565b62003bd89190620055f6565b62003be4919062004a18565b90506b033b2e3c9fd0803ce800000062003bff828462004a18565b111562003c38576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000818152600183016020526040812054801562003d4357600062003c716001836200475b565b855490915060009062003c87906001906200475b565b905081811462003cf357600086600001828154811062003cab5762003cab620049e9565b906000526020600020015490508087600001848154811062003cd15762003cd1620049e9565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003d075762003d0762005632565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062002a86565b600091505062002a86565b5092915050565b600081815260018301602052604081205462003d9e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562002a86565b50600062002a86565b6103ca806200566283390190565b50805462003dc39062004819565b6000825580601f1062003dd4575050565b601f01602090049060005260206000209081019062002a1791905b8082111562003e05576000815560010162003def565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462002a1757600080fd5b803563ffffffff8116811462003e4157600080fd5b919050565b80356002811062003e4157600080fd5b60008083601f84011262003e6957600080fd5b50813567ffffffffffffffff81111562003e8257600080fd5b60208301915083602082850101111562003e9b57600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171562003ef75762003ef762003ea2565b60405290565b604051610100810167ffffffffffffffff8111828210171562003ef75762003ef762003ea2565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562003f6e5762003f6e62003ea2565b604052919050565b600067ffffffffffffffff82111562003f935762003f9362003ea2565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262003fd157600080fd5b813562003fe862003fe28262003f76565b62003f24565b81815284602083860101111562003ffe57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200403857600080fd5b8835620040458162003e09565b97506200405560208a0162003e2c565b96506040890135620040678162003e09565b95506200407760608a0162003e46565b9450608089013567ffffffffffffffff808211156200409557600080fd5b620040a38c838d0162003e56565b909650945060a08b0135915080821115620040bd57600080fd5b620040cb8c838d0162003fbf565b935060c08b0135915080821115620040e257600080fd5b50620040f18b828c0162003fbf565b9150509295985092959890939650565b600080604083850312156200411557600080fd5b82359150602083013567ffffffffffffffff8111156200413457600080fd5b620041428582860162003fbf565b9150509250929050565b60005b83811015620041695781810151838201526020016200414f565b50506000910152565b600081518084526200418c8160208601602086016200414c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a811062004225577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b841515815260806020820152600062004246608083018662004172565b9050620042576040830185620041ed565b82606083015295945050505050565b6000806000604084860312156200427c57600080fd5b83359250602084013567ffffffffffffffff8111156200429b57600080fd5b620042a98682870162003e56565b9497909650939450505050565b600080600080600080600060a0888a031215620042d257600080fd5b8735620042df8162003e09565b9650620042ef6020890162003e2c565b95506040880135620043018162003e09565b9450606088013567ffffffffffffffff808211156200431f57600080fd5b6200432d8b838c0162003e56565b909650945060808a01359150808211156200434757600080fd5b50620043568a828b0162003e56565b989b979a50959850939692959293505050565b871515815260e0602082015260006200438660e083018962004172565b9050620043976040830188620041ed565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080600060408486031215620043d157600080fd5b833567ffffffffffffffff80821115620043ea57600080fd5b818601915086601f830112620043ff57600080fd5b8135818111156200440f57600080fd5b8760208260051b85010111156200442557600080fd5b602092830195509350508401356200443d8162003e09565b809150509250925092565b600080602083850312156200445c57600080fd5b823567ffffffffffffffff8111156200447457600080fd5b620044828582860162003e56565b90969095509350505050565b80356bffffffffffffffffffffffff8116811462003e4157600080fd5b60008060408385031215620044bf57600080fd5b82359150620044d1602084016200448e565b90509250929050565b600060208284031215620044ed57600080fd5b5035919050565b600067ffffffffffffffff82111562004511576200451162003ea2565b5060051b60200190565b600082601f8301126200452d57600080fd5b813560206200454062003fe283620044f4565b82815260059290921b840181019181810190868411156200456057600080fd5b8286015b84811015620045a557803567ffffffffffffffff811115620045865760008081fd5b620045968986838b010162003fbf565b84525091830191830162004564565b509695505050505050565b60008060008060608587031215620045c757600080fd5b84359350602085013567ffffffffffffffff80821115620045e757600080fd5b620045f5888389016200451b565b945060408701359150808211156200460c57600080fd5b506200461b8782880162003e56565b95989497509550505050565b6000602082840312156200463a57600080fd5b81356200375f8162003e09565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff80831681810362004692576200469262004647565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000620032f96020830184866200469c565b60208152600062002a83602083018462004172565b805162003e418162003e09565b6000602082840312156200473057600080fd5b81516200375f8162003e09565b60008251620047518184602087016200414c565b9190910192915050565b8181038181111562002a865762002a8662004647565b801515811462002a1757600080fd5b600082601f8301126200479257600080fd5b8151620047a362003fe28262003f76565b818152846020838601011115620047b957600080fd5b620032f98260208301602087016200414c565b60008060408385031215620047e057600080fd5b8251620047ed8162004771565b602084015190925067ffffffffffffffff8111156200480b57600080fd5b620041428582860162004780565b600181811c908216806200482e57607f821691505b60208210810362004868577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115620048bc57600081815260208120601f850160051c81016020861015620048975750805b601f850160051c820191505b81811015620048b857828155600101620048a3565b5050505b505050565b67ffffffffffffffff831115620048dc57620048dc62003ea2565b620048f483620048ed835462004819565b836200486e565b6000601f841160018114620049495760008515620049125750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355620049e2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156200499a578685013582556020948501946001909201910162004978565b5086821015620049d6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111562002a865762002a8662004647565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004a625762004a6262004647565b5060010190565b600081518084526020808501945080840160005b8381101562004b285781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004b03828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004a7d565b509495945050505050565b600081518084526020808501945080840160005b8381101562004b2857815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004b47565b600081518084526020808501808196508360051b8101915082860160005b8581101562004bc757828403895262004bb484835162004172565b9885019893509084019060010162004b99565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004c1157600080fd5b8960051b808c8386013783018381038201602085015262004c358282018b62004a69565b915050828103604084015262004c4c818962004b33565b9050828103606084015262004c62818862004b33565b9050828103608084015262004c78818762004b7b565b905082810360a084015262004c8e818662004b7b565b905082810360c084015262003535818562004b7b565b60006020828403121562004cb757600080fd5b815160ff811681146200375f57600080fd5b60ff8416815260ff8316602082015260606040820152600062002d2f606083018462004172565b60006020828403121562004d0357600080fd5b815167ffffffffffffffff81111562004d1b57600080fd5b620032f98482850162004780565b60006020828403121562004d3c57600080fd5b81516200375f8162004771565b600082601f83011262004d5b57600080fd5b8135602062004d6e62003fe283620044f4565b82815260059290921b8401810191818101908684111562004d8e57600080fd5b8286015b84811015620045a5578035835291830191830162004d92565b600082601f83011262004dbd57600080fd5b8135602062004dd062003fe283620044f4565b82815260e0928302850182019282820191908785111562004df057600080fd5b8387015b8581101562004ea75781818a03121562004e0e5760008081fd5b62004e1862003ed1565b813562004e258162004771565b815262004e3482870162003e2c565b86820152604062004e4781840162003e2c565b9082015260608281013562004e5c8162003e09565b90820152608062004e6f8382016200448e565b9082015260a062004e828382016200448e565b9082015260c062004e9583820162003e2c565b90820152845292840192810162004df4565b5090979650505050505050565b600082601f83011262004ec657600080fd5b8135602062004ed962003fe283620044f4565b82815260059290921b8401810191818101908684111562004ef957600080fd5b8286015b84811015620045a557803562004f138162003e09565b835291830191830162004efd565b600080600080600080600060e0888a03121562004f3d57600080fd5b873567ffffffffffffffff8082111562004f5657600080fd5b62004f648b838c0162004d49565b985060208a013591508082111562004f7b57600080fd5b62004f898b838c0162004dab565b975060408a013591508082111562004fa057600080fd5b62004fae8b838c0162004eb4565b965060608a013591508082111562004fc557600080fd5b62004fd38b838c0162004eb4565b955060808a013591508082111562004fea57600080fd5b62004ff88b838c016200451b565b945060a08a01359150808211156200500f57600080fd5b6200501d8b838c016200451b565b935060c08a01359150808211156200503457600080fd5b50620050438a828b016200451b565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003d4e5762003d4e62004647565b6000602082840312156200508d57600080fd5b5051919050565b6bffffffffffffffffffffffff82811682821603908082111562003d4e5762003d4e62004647565b604081526000620050d1604083018662004b7b565b8281036020840152620050e68185876200469c565b9695505050505050565b8051602080830151919081101562004868577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff81111562005150576200515062003ea2565b620051688162005161845462004819565b846200486e565b602080601f831160018114620051be5760008415620051875750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555620048b8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156200520d57888601518255948401946001909101908401620051ec565b50858210156200524a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff8116811462003e4157600080fd5b600080600080600060a086880312156200528e57600080fd5b62005299866200525a565b9450602086015193506040860151925060608601519150620052be608087016200525a565b90509295509295909350565b60008154620052d98162004819565b808552602060018381168015620052f95760018114620053325762005362565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955062005362565b866000528260002060005b858110156200535a5781548a82018601529083019084016200533d565b890184019650505b505050505092915050565b60208152600062002a836020830184620052ca565b600082601f8301126200539457600080fd5b81516020620053a762003fe283620044f4565b82815260059290921b84018101918181019086841115620053c757600080fd5b8286015b84811015620045a55780518352918301918301620053cb565b600060208284031215620053f757600080fd5b815167ffffffffffffffff808211156200541057600080fd5b9083019061010082860312156200542657600080fd5b6200543062003efd565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200546a60a0840162004710565b60a082015260c0830151828111156200548257600080fd5b620054908782860162005382565b60c08301525060e083015182811115620054a957600080fd5b620054b78782860162004780565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004b2857815187529582019590820190600101620054da565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c08401516101008081850152506200556b610140840182620054c6565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084830301610120850152620055a9828262004172565b915050828103602084015262002d2f8185620052ca565b808202811582820484141762002a865762002a8662004647565b60ff818116838216019081111562002a865762002a8662004647565b6000826200562d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", } var AutomationRegistryLogicAABI = AutomationRegistryLogicAMetaData.ABI @@ -639,6 +639,123 @@ func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseCancelle return event, nil } +type AutomationRegistryLogicAChainSpecificModuleUpdatedIterator struct { + Event *AutomationRegistryLogicAChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicAChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAChainSpecificModuleUpdatedIterator{contract: _AutomationRegistryLogicA.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicAChainSpecificModuleUpdated, error) { + event := new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type AutomationRegistryLogicADedupKeyAddedIterator struct { Event *AutomationRegistryLogicADedupKeyAdded @@ -4446,6 +4563,8 @@ func (_AutomationRegistryLogicA *AutomationRegistryLogicA) ParseLog(log types.Lo return _AutomationRegistryLogicA.ParseAdminPrivilegeConfigSet(log) case _AutomationRegistryLogicA.abi.Events["CancelledUpkeepReport"].ID: return _AutomationRegistryLogicA.ParseCancelledUpkeepReport(log) + case _AutomationRegistryLogicA.abi.Events["ChainSpecificModuleUpdated"].ID: + return _AutomationRegistryLogicA.ParseChainSpecificModuleUpdated(log) case _AutomationRegistryLogicA.abi.Events["DedupKeyAdded"].ID: return _AutomationRegistryLogicA.ParseDedupKeyAdded(log) case _AutomationRegistryLogicA.abi.Events["FundsAdded"].ID: @@ -4518,6 +4637,10 @@ func (AutomationRegistryLogicACancelledUpkeepReport) Topic() common.Hash { return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") } +func (AutomationRegistryLogicAChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + func (AutomationRegistryLogicADedupKeyAdded) Topic() common.Hash { return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") } @@ -4683,6 +4806,12 @@ type AutomationRegistryLogicAInterface interface { ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryLogicACancelledUpkeepReport, error) + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicAChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicAChainSpecificModuleUpdated, error) + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryLogicADedupKeyAddedIterator, error) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicADedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) diff --git a/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go b/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go index d9b0742aa76..d15bc458774 100644 --- a/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go +++ b/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go @@ -75,15 +75,15 @@ type AutomationRegistryBase22UpkeepInfo struct { } var AutomationRegistryLogicBMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Mode\",\"name\":\"mode\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"automationForwarderLogic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowedReadOnlyAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"contractIAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMode\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Mode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"enumUpkeepFormat\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b5060405162005094380380620050948339810160408190526200003591620001f2565b8585858585853380600081620000925760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c557620000c5816200012a565b505050856002811115620000dd57620000dd62000278565b60e0816002811115620000f457620000f462000278565b9052506001600160a01b0394851660805292841660a05290831660c0528216610100521661012052506200028e95505050505050565b336001600160a01b03821603620001845760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000089565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ed57600080fd5b919050565b60008060008060008060c087890312156200020c57600080fd5b8651600381106200021c57600080fd5b95506200022c60208801620001d5565b94506200023c60408801620001d5565b93506200024c60608801620001d5565b92506200025c60808801620001d5565b91506200026c60a08801620001d5565b90509295509295509295565b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e0516101005161012051614d706200032460003960006106fc015260006105a401526000818161054201528181613432015281816139b50152613b48015260008181610611015261322601526000818161075f01526133000152600081816107ed01528181611c9001528181611f65015281816123ce015281816128e101526129650152614d706000f3fe608060405234801561001057600080fd5b506004361061034c5760003560e01c806379ba5097116101bd578063b121e147116100f9578063ca30e603116100a2578063eb5dcd6c1161007c578063eb5dcd6c14610837578063ed56b3e11461084a578063f2fde38b146108bd578063faa3e996146108d057600080fd5b8063ca30e603146107eb578063cd7f71b514610811578063d76326481461082457600080fd5b8063b657bc9c116100d3578063b657bc9c146107b0578063b79550be146107c3578063c7c3a19a146107cb57600080fd5b8063b121e14714610783578063b148ab6b14610796578063b6511a2a146107a957600080fd5b80638dcf0fe711610166578063a72aa27e11610140578063a72aa27e14610733578063aab9edd614610746578063abc76ae014610755578063b10b673c1461075d57600080fd5b80638dcf0fe7146106e7578063a08714c0146106fa578063a710b2211461072057600080fd5b80638456cb59116101975780638456cb59146106ae5780638765ecbe146106b65780638da5cb5b146106c957600080fd5b806379ba50971461065b57806379ea9943146106635780637d9b97e0146106a657600080fd5b806343cc055c1161028c5780635165f2f5116102355780636209e1e91161020f5780636209e1e9146105fc5780636709d0e51461060f578063671d36ed14610635578063744bfe611461064857600080fd5b80635165f2f51461058f5780635425d8ac146105a25780635b6aa71c146105e957600080fd5b80634b4fd03b116102665780634b4fd03b146105405780634ca16c52146105665780635147cd591461056f57600080fd5b806343cc055c146104f657806344cb70b81461050d57806348013d7b1461053057600080fd5b80631a2af011116102f9578063232c1cc5116102d3578063232c1cc51461046e5780633b9cce59146104755780633f4ba83a14610488578063421d183b1461049057600080fd5b80631a2af011146103ea5780631e010439146103fd578063207b65161461045b57600080fd5b80631865c57d1161032a5780631865c57d1461039e578063187256e8146103b757806319d97a94146103ca57600080fd5b8063050ee65d1461035157806306e3b632146103695780630b7d33e614610389575b600080fd5b6201adb05b6040519081526020015b60405180910390f35b61037c610377366004613ed3565b610916565b6040516103609190613ef5565b61039c610397366004613f82565b610a33565b005b6103a6610aed565b604051610360959493929190614185565b61039c6103c53660046142bc565b610f37565b6103dd6103d83660046142f9565b610fa8565b6040516103609190614380565b61039c6103f8366004614393565b61104a565b61043e61040b3660046142f9565b6000908152600460205260409020600101546c0100000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff9091168152602001610360565b6103dd6104693660046142f9565b611150565b6014610356565b61039c6104833660046143b8565b61116d565b61039c6113c3565b6104a361049e36600461442d565b611429565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a001610360565b60135460ff165b6040519015158152602001610360565b6104fd61051b3660046142f9565b60009081526008602052604090205460ff1690565b60005b6040516103609190614489565b7f0000000000000000000000000000000000000000000000000000000000000000610533565b62015f90610356565b61058261057d3660046142f9565b611548565b604051610360919061449c565b61039c61059d3660046142f9565b611553565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610360565b61043e6105f73660046144c9565b6116ca565b6103dd61060a36600461442d565b611862565b7f00000000000000000000000000000000000000000000000000000000000000006105c4565b61039c610643366004614502565b611896565b61039c610656366004614393565b611970565b61039c611d8b565b6105c46106713660046142f9565b6000908152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61039c611e8d565b61039c611fe8565b61039c6106c43660046142f9565b612069565b60005473ffffffffffffffffffffffffffffffffffffffff166105c4565b61039c6106f5366004613f82565b6121e3565b7f00000000000000000000000000000000000000000000000000000000000000006105c4565b61039c61072e36600461453e565b612238565b61039c61074136600461456c565b6124a0565b60405160038152602001610360565b611d4c610356565b7f00000000000000000000000000000000000000000000000000000000000000006105c4565b61039c61079136600461442d565b612595565b61039c6107a43660046142f9565b61268d565b6032610356565b61043e6107be3660046142f9565b61287b565b61039c6128a8565b6107de6107d93660046142f9565b612a04565b604051610360919061458f565b7f00000000000000000000000000000000000000000000000000000000000000006105c4565b61039c61081f366004613f82565b612dd7565b61043e6108323660046142f9565b612e6e565b61039c61084536600461453e565b612e79565b6108a461085836600461442d565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff909116602083015201610360565b61039c6108cb36600461442d565b612fd7565b6109096108de36600461442d565b73ffffffffffffffffffffffffffffffffffffffff166000908152601a602052604090205460ff1690565b60405161036091906146c6565b606060006109246002612feb565b905080841061095f576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061096b8486614709565b905081811180610979575083155b6109835780610985565b815b90506000610993868361471c565b67ffffffffffffffff8111156109ab576109ab61472f565b6040519080825280602002602001820160405280156109d4578160200160208202803683370190505b50905060005b8151811015610a27576109f86109f08883614709565b600290612ff5565b828281518110610a0a57610a0a61475e565b602090810291909101015280610a1f8161478d565b9150506109da565b50925050505b92915050565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610a94576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152601d60205260409020610aad828483614867565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae77698383604051610ae0929190614982565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c0810191909152604080516101408101825260155463ffffffff7401000000000000000000000000000000000000000082041682526bffffffffffffffffffffffff90811660208301526019549282019290925260125490911660608281019190915290819060009060808101610c266002612feb565b8152601554780100000000000000000000000000000000000000000000000080820463ffffffff9081166020808601919091527c01000000000000000000000000000000000000000000000000000000008404821660408087019190915260115460608088019190915260125474010000000000000000000000000000000000000000810485166080808a01919091527e01000000000000000000000000000000000000000000000000000000000000820460ff16151560a0998a015283516101e0810185526c0100000000000000000000000080840488168252700100000000000000000000000000000000808504891697830197909752808a0488169582019590955296820462ffffff16928701929092527b01000000000000000000000000000000000000000000000000000000900461ffff16908501526014546bffffffffffffffffffffffff8116968501969096529304811660c083015260165480821660e08401526401000000008104821661010084015268010000000000000000900416610120820152601754610140820152601854610160820152910473ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a08101610df36009613008565b81526016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16602091820152601254600d80546040805182860281018601909152818152949850899489949293600e937d01000000000000000000000000000000000000000000000000000000000090910460ff16928591830182828015610eb657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e8b575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610f1f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ef4575b50505050509150945094509450945094509091929394565b610f3f613015565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601a6020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115610f9f57610f9f61444a565b02179055505050565b6000818152601d60205260409020805460609190610fc5906147c5565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff1906147c5565b801561103e5780601f106110135761010080835404028352916020019161103e565b820191906000526020600020905b81548152906001019060200180831161102157829003601f168201915b50505050509050919050565b61105382613098565b3373ffffffffffffffffffffffffffffffffffffffff8216036110a2576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff82811691161461114c5760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b6000818152601b60205260409020805460609190610fc5906147c5565b611175613015565b600e5481146111b0576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e54811015611382576000600e82815481106111d2576111d261475e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600f9092526040832054919350169085858581811061121c5761121c61475e565b9050602002016020810190611231919061442d565b905073ffffffffffffffffffffffffffffffffffffffff811615806112c4575073ffffffffffffffffffffffffffffffffffffffff8216158015906112a257508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b80156112c4575073ffffffffffffffffffffffffffffffffffffffff81811614155b156112fb576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181161461136c5773ffffffffffffffffffffffffffffffffffffffff8381166000908152600f6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b505050808061137a9061478d565b9150506111b3565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516113b7939291906149cf565b60405180910390a15050565b6113cb613015565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015282918291829182919082906114ef5760608201516012546000916114db916bffffffffffffffffffffffff16614a81565b600e549091506114eb9082614ad5565b9150505b815160208301516040840151611506908490614b00565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b166000908152600f6020526040902054929b919a9499509750921694509092505050565b6000610a2d8261314c565b61155c81613098565b600081815260046020908152604091829020825160e081018452815460ff8116151580835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201529061165b576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905561169a6002836131f7565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b60408051610140810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e0100000000000000000000000000000000000000000000000000000000000083048116151560e08301527f0100000000000000000000000000000000000000000000000000000000000000909204821615156101008201526013549091161515610120820152600090818061182f83613203565b91509150611858838787601460020160049054906101000a900463ffffffff16868660006133e1565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e60205260409020805460609190610fc5906147c5565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633146118f7576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601e60205260409020611927828483614867565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d28383604051610ae0929190614982565b6012547f0100000000000000000000000000000000000000000000000000000000000000900460ff16156119d0576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff8116611a66576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481168387015265010000000000820481168386015273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909204821660608401526001909301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c082015286855260059093529220549091163314611b6d576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7561342c565b816040015163ffffffff161115611bb8576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600460205260409020600101546019546c010000000000000000000000009091046bffffffffffffffffffffffff1690611bf890829061471c565b60195560008481526004602081905260409182902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff16905590517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116928201929092526bffffffffffffffffffffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cff9190614b25565b50604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611e11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611e95613015565b6015546019546bffffffffffffffffffffffff90911690611eb790829061471c565b601955601580547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690556040516bffffffffffffffffffffffff821681527f1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f19060200160405180910390a16040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526bffffffffffffffffffffffff821660248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044015b6020604051808303816000875af1158015611fc4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114c9190614b25565b611ff0613015565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200161141f565b61207281613098565b600081815260046020908152604091829020825160e081018452815460ff8116158015835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015290612171576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556121b36002836134e1565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b6121ec83613098565b6000838152601c60205260409020612205828483614867565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508383604051610ae0929190614982565b73ffffffffffffffffffffffffffffffffffffffff8116612285576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f60205260409020541633146122e5576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546000916123089185916bffffffffffffffffffffffff16906134ed565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff169055601954909150612372906bffffffffffffffffffffffff83169061471c565b6019556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526bffffffffffffffffffffffff831660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612417573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243b9190614b25565b5060405133815273ffffffffffffffffffffffffffffffffffffffff808416916bffffffffffffffffffffffff8416918616907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a4505050565b6108fc8163ffffffff1610806124d5575060155463ffffffff7001000000000000000000000000000000009091048116908216115b1561250c576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61251582613098565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c910160405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601060205260409020541633146125f5576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600f602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556010909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c0820152911461278a576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146127e7576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b6000610a2d6128898361314c565b600084815260046020526040902054610100900463ffffffff166116ca565b6128b0613015565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561293d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129619190614b47565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33601954846129ae919061471c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401611fa5565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606083018190526001909101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c0820152919015612b9c57816060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b979190614b60565b612b9f565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836020015163ffffffff168152602001600760008781526020019081526020016000208054612bf7906147c5565b80601f0160208091040260200160405190810160405280929190818152602001828054612c23906147c5565b8015612c705780601f10612c4557610100808354040283529160200191612c70565b820191906000526020600020905b815481529060010190602001808311612c5357829003601f168201915b505050505081526020018360a001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff1667ffffffffffffffff1681526020018360c0015163ffffffff16815260200183608001516bffffffffffffffffffffffff168152602001836000015115158152602001601c60008781526020019081526020016000208054612d4d906147c5565b80601f0160208091040260200160405190810160405280929190818152602001828054612d79906147c5565b8015612dc65780601f10612d9b57610100808354040283529160200191612dc6565b820191906000526020600020905b815481529060010190602001808311612da957829003601f168201915b505050505081525092505050919050565b612de083613098565b60165463ffffffff16811115612e22576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260409020612e3b828483614867565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8383604051610ae0929190614982565b6000610a2d8261287b565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054163314612ed9576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f28576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526010602052604090205481169082161461114c5773ffffffffffffffffffffffffffffffffffffffff82811660008181526010602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45050565b612fdf613015565b612fe8816136f5565b50565b6000610a2d825490565b600061300183836137ea565b9392505050565b6060600061300183613814565b60005473ffffffffffffffffffffffffffffffffffffffff163314613096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611e08565b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146130f5576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff90811614612fe8576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f8110156131d9577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106131915761319161475e565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146131c757506000949350505050565b806131d18161478d565b915050613153565b5081600f1a60018111156131ef576131ef61444a565b949350505050565b6000613001838361386f565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561328f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b39190614b97565b50945090925050506000811315806132ca57508142105b806132eb57508280156132eb57506132e2824261471c565b8463ffffffff16105b156132fa5760175495506132fe565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338d9190614b97565b50945090925050506000811315806133a457508142105b806133c557508280156133c557506133bc824261471c565b8463ffffffff16105b156133d45760185494506133d8565b8094505b50505050915091565b6000806133f388878b60c001516138be565b905060008061340e8b8a63ffffffff16858a8a60018b613980565b909250905061341d8183614b00565b9b9a5050505050505050505050565b600060017f000000000000000000000000000000000000000000000000000000000000000060028111156134625761346261444a565b036134dc57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190614b47565b905090565b504390565b60006130018383613dd9565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906136e95760008160600151856135859190614a81565b905060006135938583614ad5565b905080836040018181516135a79190614b00565b6bffffffffffffffffffffffff169052506135c28582614be7565b836060018181516135d39190614b00565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613774576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611e08565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008260000182815481106138015761380161475e565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561103e57602002820191906000526020600020905b8154815260200190600101908083116138505750505050509050919050565b60008181526001830160205260408120546138b657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a2d565b506000610a2d565b600080808560018111156138d4576138d461444a565b036138e3575062015f90613938565b60018560018111156138f7576138f761444a565b0361390657506201adb0613938565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61394963ffffffff85166014614c17565b613954846001614c2e565b6139639060ff16611d4c614c17565b61396d9083614709565b6139779190614709565b95945050505050565b60008060008960a0015161ffff16876139999190614c17565b90508380156139a75750803a105b156139af57503a5b600060027f000000000000000000000000000000000000000000000000000000000000000060028111156139e5576139e561444a565b03613b44576040805160008152602081019091528515613a4357600036604051806080016040528060488152602001614d1c60489139604051602001613a2d93929190614c47565b6040516020818303038152906040529050613aab565b601654613a5f90640100000000900463ffffffff166004614c6e565b63ffffffff1667ffffffffffffffff811115613a7d57613a7d61472f565b6040519080825280601f01601f191660200182016040528015613aa7576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e90613afb908490600401614380565b602060405180830381865afa158015613b18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b3c9190614b47565b915050613c9e565b60017f00000000000000000000000000000000000000000000000000000000000000006002811115613b7857613b7861444a565b03613c9e578415613bfa57606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613bcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bf39190614b47565b9050613c9e565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa158015613c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c6c9190614c8e565b5050601654929450613c8f93505050640100000000900463ffffffff1682614c17565b613c9a906010614c17565b9150505b84613cba57808b60a0015161ffff16613cb79190614c17565b90505b613cc861ffff871682614cd8565b905060008782613cd88c8e614709565b613ce29086614c17565b613cec9190614709565b613cfe90670de0b6b3a7640000614c17565b613d089190614cd8565b905060008c6040015163ffffffff1664e8d4a51000613d279190614c17565b898e6020015163ffffffff16858f88613d409190614c17565b613d4a9190614709565b613d5890633b9aca00614c17565b613d629190614c17565b613d6c9190614cd8565b613d769190614709565b90506b033b2e3c9fd0803ce8000000613d8f8284614709565b1115613dc7576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b60008181526001830160205260408120548015613ec2576000613dfd60018361471c565b8554909150600090613e119060019061471c565b9050818114613e76576000866000018281548110613e3157613e3161475e565b9060005260206000200154905080876000018481548110613e5457613e5461475e565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613e8757613e87614cec565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a2d565b6000915050610a2d565b5092915050565b60008060408385031215613ee657600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613f2d57835183529284019291840191600101613f11565b50909695505050505050565b60008083601f840112613f4b57600080fd5b50813567ffffffffffffffff811115613f6357600080fd5b602083019150836020828501011115613f7b57600080fd5b9250929050565b600080600060408486031215613f9757600080fd5b83359250602084013567ffffffffffffffff811115613fb557600080fd5b613fc186828701613f39565b9497909650939450505050565b600081518084526020808501945080840160005b8381101561401457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613fe2565b509495945050505050565b805163ffffffff16825260006101e06020830151614045602086018263ffffffff169052565b50604083015161405d604086018263ffffffff169052565b506060830151614074606086018262ffffff169052565b50608083015161408a608086018261ffff169052565b5060a08301516140aa60a08601826bffffffffffffffffffffffff169052565b5060c08301516140c260c086018263ffffffff169052565b5060e08301516140da60e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a08084015181860183905261414f83870182613fce565b925050506101c08084015161417b8287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c060208801516141b360208501826bffffffffffffffffffffffff169052565b506040880151604084015260608801516141dd60608501826bffffffffffffffffffffffff169052565b506080880151608084015260a08801516141ff60a085018263ffffffff169052565b5060c088015161421760c085018263ffffffff169052565b5060e088015160e08401526101008089015161423a8286018263ffffffff169052565b505061012088810151151590840152610140830181905261425d8184018861401f565b90508281036101608401526142728187613fce565b90508281036101808401526142878186613fce565b9150506118586101a083018460ff169052565b73ffffffffffffffffffffffffffffffffffffffff81168114612fe857600080fd5b600080604083850312156142cf57600080fd5b82356142da8161429a565b91506020830135600481106142ee57600080fd5b809150509250929050565b60006020828403121561430b57600080fd5b5035919050565b60005b8381101561432d578181015183820152602001614315565b50506000910152565b6000815180845261434e816020860160208601614312565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006130016020830184614336565b600080604083850312156143a657600080fd5b8235915060208301356142ee8161429a565b600080602083850312156143cb57600080fd5b823567ffffffffffffffff808211156143e357600080fd5b818501915085601f8301126143f757600080fd5b81358181111561440657600080fd5b8660208260051b850101111561441b57600080fd5b60209290920196919550909350505050565b60006020828403121561443f57600080fd5b81356130018161429a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612fe857612fe861444a565b6020810161449683614479565b91905290565b60208101600283106144965761449661444a565b803563ffffffff811681146144c457600080fd5b919050565b600080604083850312156144dc57600080fd5b8235600281106144eb57600080fd5b91506144f9602084016144b0565b90509250929050565b60008060006040848603121561451757600080fd5b83356145228161429a565b9250602084013567ffffffffffffffff811115613fb557600080fd5b6000806040838503121561455157600080fd5b823561455c8161429a565b915060208301356142ee8161429a565b6000806040838503121561457f57600080fd5b823591506144f9602084016144b0565b602081526145b660208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516145cf604084018263ffffffff169052565b5060408301516101408060608501526145ec610160850183614336565b9150606085015161460d60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614679818701836bffffffffffffffffffffffff169052565b860151905061012061468e8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018387015290506118588382614336565b60208101600483106144965761449661444a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a2d57610a2d6146da565b81810381811115610a2d57610a2d6146da565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036147be576147be6146da565b5060010190565b600181811c908216806147d957607f821691505b602082108103614812577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561486257600081815260208120601f850160051c8101602086101561483f5750805b601f850160051c820191505b8181101561485e5782815560010161484b565b5050505b505050565b67ffffffffffffffff83111561487f5761487f61472f565b6148938361488d83546147c5565b83614818565b6000601f8411600181146148e557600085156148af5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561497b565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156149345786850135825560209485019460019092019101614914565b508682101561496f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b82811015614a2657815473ffffffffffffffffffffffffffffffffffffffff16845292840192600191820191016149f4565b505050838103828501528481528590820160005b86811015614a75578235614a4d8161429a565b73ffffffffffffffffffffffffffffffffffffffff1682529183019190830190600101614a3a565b50979650505050505050565b6bffffffffffffffffffffffff828116828216039080821115613ecc57613ecc6146da565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff80841680614af457614af4614aa6565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115613ecc57613ecc6146da565b600060208284031215614b3757600080fd5b8151801515811461300157600080fd5b600060208284031215614b5957600080fd5b5051919050565b600060208284031215614b7257600080fd5b81516130018161429a565b805169ffffffffffffffffffff811681146144c457600080fd5b600080600080600060a08688031215614baf57600080fd5b614bb886614b7d565b9450602086015193506040860151925060608601519150614bdb60808701614b7d565b90509295509295909350565b6bffffffffffffffffffffffff818116838216028082169190828114614c0f57614c0f6146da565b505092915050565b8082028115828204841417610a2d57610a2d6146da565b60ff8181168382160190811115610a2d57610a2d6146da565b828482376000838201600081528351614c64818360208801614312565b0195945050505050565b63ffffffff818116838216028082169190828114614c0f57614c0f6146da565b60008060008060008060c08789031215614ca757600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600082614ce757614ce7614aa6565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"automationForwarderLogic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowedReadOnlyAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"contractIAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIChainModule\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"setChainSpecificModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"enumUpkeepFormat\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162004dfb38038062004dfb8339810160408190526200003591620001bf565b84848484843380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c481620000f7565b5050506001600160a01b0394851660805292841660a05290831660c052821660e0521661010052506200022f9350505050565b336001600160a01b03821603620001515760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ba57600080fd5b919050565b600080600080600060a08688031215620001d857600080fd5b620001e386620001a2565b9450620001f360208701620001a2565b93506200020360408701620001a2565b92506200021360608701620001a2565b91506200022360808701620001a2565b90509295509295909350565b60805160a05160c05160e05161010051614b56620002a56000396000610716015260006105880152600081816106080152613379015260008181610779015261345301526000818161080701528181611de3015281816120b80152818161252101528181612a340152612ab80152614b566000f3fe608060405234801561001057600080fd5b50600436106103575760003560e01c806379ba5097116101c8578063b10b673c11610104578063ca30e603116100a2578063eb5dcd6c1161007c578063eb5dcd6c14610851578063ed56b3e114610864578063f2fde38b146108d7578063faa3e996146108ea57600080fd5b8063ca30e60314610805578063cd7f71b51461082b578063d76326481461083e57600080fd5b8063b6511a2a116100de578063b6511a2a146107c3578063b657bc9c146107ca578063b79550be146107dd578063c7c3a19a146107e557600080fd5b8063b10b673c14610777578063b121e1471461079d578063b148ab6b146107b057600080fd5b80638dcf0fe711610171578063a710b2211161014b578063a710b2211461073a578063a72aa27e1461074d578063aab9edd614610760578063abc76ae01461076f57600080fd5b80638dcf0fe7146106de5780638ed02bab146106f1578063a08714c01461071457600080fd5b80638456cb59116101a25780638456cb59146106a55780638765ecbe146106ad5780638da5cb5b146106c057600080fd5b806379ba50971461065257806379ea99431461065a5780637d9b97e01461069d57600080fd5b806343cc055c116102975780635425d8ac116102405780636209e1e91161021a5780636209e1e9146105f35780636709d0e514610606578063671d36ed1461062c578063744bfe611461063f57600080fd5b80635425d8ac146105865780635b6aa71c146105cd5780635b7edd6e146105e057600080fd5b80634ca16c52116102715780634ca16c521461054a5780635147cd59146105535780635165f2f51461057357600080fd5b806343cc055c1461050157806344cb70b81461051857806348013d7b1461053b57600080fd5b80631a2af01111610304578063232c1cc5116102de578063232c1cc5146104795780633b9cce59146104805780633f4ba83a14610493578063421d183b1461049b57600080fd5b80631a2af011146103f55780631e01043914610408578063207b65161461046657600080fd5b80631865c57d116103355780631865c57d146103a9578063187256e8146103c257806319d97a94146103d557600080fd5b8063050ee65d1461035c57806306e3b632146103745780630b7d33e614610394575b600080fd5b6201af405b6040519081526020015b60405180910390f35b610387610382366004613da5565b610930565b60405161036b9190613dc7565b6103a76103a2366004613e54565b610a4d565b005b6103b1610b07565b60405161036b959493929190614057565b6103a76103d036600461418e565b610f51565b6103e86103e33660046141cb565b610fc2565b60405161036b9190614248565b6103a761040336600461425b565b611064565b6104496104163660046141cb565b6000908152600460205260409020600101546c0100000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff909116815260200161036b565b6103e86104743660046141cb565b61116a565b6014610361565b6103a761048e366004614280565b611187565b6103a76113dd565b6104ae6104a93660046142f5565b611443565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00161036b565b60135460ff165b604051901515815260200161036b565b6105086105263660046141cb565b60009081526008602052604090205460ff1690565b600060405161036b9190614341565b62015f90610361565b6105666105613660046141cb565b611562565b60405161036b919061435b565b6103a76105813660046141cb565b61156d565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161036b565b6104496105db366004614388565b6116e4565b6103a76105ee3660046142f5565b6118a1565b6103e86106013660046142f5565b611929565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a761063a3660046143c1565b61195d565b6103a761064d36600461425b565b611a37565b6103a7611ede565b6105a86106683660046141cb565b6000908152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6103a7611fe0565b6103a761213b565b6103a76106bb3660046141cb565b6121bc565b60005473ffffffffffffffffffffffffffffffffffffffff166105a8565b6103a76106ec366004613e54565b612336565b601354610100900473ffffffffffffffffffffffffffffffffffffffff166105a8565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a76107483660046143fd565b61238b565b6103a761075b36600461442b565b6125f3565b6040516003815260200161036b565b611d4c610361565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a76107ab3660046142f5565b6126e8565b6103a76107be3660046141cb565b6127e0565b6032610361565b6104496107d83660046141cb565b6129ce565b6103a76129fb565b6107f86107f33660046141cb565b612b57565b60405161036b919061444e565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a7610839366004613e54565b612f2a565b61044961084c3660046141cb565b612fc1565b6103a761085f3660046143fd565b612fcc565b6108be6108723660046142f5565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff90911660208301520161036b565b6103a76108e53660046142f5565b61312a565b6109236108f83660046142f5565b73ffffffffffffffffffffffffffffffffffffffff166000908152601a602052604090205460ff1690565b60405161036b9190614585565b6060600061093e600261313e565b9050808410610979576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061098584866145c8565b905081811180610993575083155b61099d578061099f565b815b905060006109ad86836145db565b67ffffffffffffffff8111156109c5576109c56145ee565b6040519080825280602002602001820160405280156109ee578160200160208202803683370190505b50905060005b8151811015610a4157610a12610a0a88836145c8565b600290613148565b828281518110610a2457610a2461461d565b602090810291909101015280610a398161464c565b9150506109f4565b50925050505b92915050565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610aae576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152601d60205260409020610ac7828483614726565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae77698383604051610afa929190614841565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c0810191909152604080516101408101825260155463ffffffff7401000000000000000000000000000000000000000082041682526bffffffffffffffffffffffff90811660208301526019549282019290925260125490911660608281019190915290819060009060808101610c40600261313e565b8152601554780100000000000000000000000000000000000000000000000080820463ffffffff9081166020808601919091527c01000000000000000000000000000000000000000000000000000000008404821660408087019190915260115460608088019190915260125474010000000000000000000000000000000000000000810485166080808a01919091527e01000000000000000000000000000000000000000000000000000000000000820460ff16151560a0998a015283516101e0810185526c0100000000000000000000000080840488168252700100000000000000000000000000000000808504891697830197909752808a0488169582019590955296820462ffffff16928701929092527b01000000000000000000000000000000000000000000000000000000900461ffff16908501526014546bffffffffffffffffffffffff8116968501969096529304811660c083015260165480821660e08401526401000000008104821661010084015268010000000000000000900416610120820152601754610140820152601854610160820152910473ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a08101610e0d600961315b565b81526016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16602091820152601254600d80546040805182860281018601909152818152949850899489949293600e937d01000000000000000000000000000000000000000000000000000000000090910460ff16928591830182828015610ed057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ea5575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610f3957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610f0e575b50505050509150945094509450945094509091929394565b610f59613168565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601a6020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115610fb957610fb9614312565b02179055505050565b6000818152601d60205260409020805460609190610fdf90614684565b80601f016020809104026020016040519081016040528092919081815260200182805461100b90614684565b80156110585780601f1061102d57610100808354040283529160200191611058565b820191906000526020600020905b81548152906001019060200180831161103b57829003601f168201915b50505050509050919050565b61106d826131eb565b3373ffffffffffffffffffffffffffffffffffffffff8216036110bc576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146111665760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b6000818152601b60205260409020805460609190610fdf90614684565b61118f613168565b600e5481146111ca576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e5481101561139c576000600e82815481106111ec576111ec61461d565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600f909252604083205491935016908585858181106112365761123661461d565b905060200201602081019061124b91906142f5565b905073ffffffffffffffffffffffffffffffffffffffff811615806112de575073ffffffffffffffffffffffffffffffffffffffff8216158015906112bc57508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b80156112de575073ffffffffffffffffffffffffffffffffffffffff81811614155b15611315576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116146113865773ffffffffffffffffffffffffffffffffffffffff8381166000908152600f6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b50505080806113949061464c565b9150506111cd565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516113d19392919061488e565b60405180910390a15050565b6113e5613168565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015282918291829182919082906115095760608201516012546000916114f5916bffffffffffffffffffffffff16614940565b600e549091506115059082614994565b9150505b8151602083015160408401516115209084906149bf565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b166000908152600f6020526040902054929b919a9499509750921694509092505050565b6000610a478261329f565b611576816131eb565b600081815260046020908152604091829020825160e081018452815460ff8116151580835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015290611675576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556116b460028361334a565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e0100000000000000000000000000000000000000000000000000000000000083048116151560e08301527f01000000000000000000000000000000000000000000000000000000000000009092048216151561010080830191909152601354928316151561012083015273ffffffffffffffffffffffffffffffffffffffff920491909116610140820152600090818061186e83613356565b91509150611897838787601460020160049054906101000a900463ffffffff1686866000613534565b9695505050505050565b6118a9613168565b601380547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527fdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad79060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e60205260409020805460609190610fdf90614684565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633146119be576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601e602052604090206119ee828483614726565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d28383604051610afa929190614841565b6012547f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611a97576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff8116611b2d576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481168387015265010000000000820481168386015273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909204821660608401526001909301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c082015286855260059093529220549091163314611c34576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc891906149e4565b816040015163ffffffff161115611d0b576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600460205260409020600101546019546c010000000000000000000000009091046bffffffffffffffffffffffff1690611d4b9082906145db565b60195560008481526004602081905260409182902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff16905590517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116928201929092526bffffffffffffffffffffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5291906149fd565b50604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611fe8613168565b6015546019546bffffffffffffffffffffffff9091169061200a9082906145db565b601955601580547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690556040516bffffffffffffffffffffffff821681527f1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f19060200160405180910390a16040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526bffffffffffffffffffffffff821660248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044015b6020604051808303816000875af1158015612117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116691906149fd565b612143613168565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001611439565b6121c5816131eb565b600081815260046020908152604091829020825160e081018452815460ff8116158015835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c0820152906122c4576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561230660028361357f565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b61233f836131eb565b6000838152601c60205260409020612358828483614726565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508383604051610afa929190614841565b73ffffffffffffffffffffffffffffffffffffffff81166123d8576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054163314612438576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e5460009161245b9185916bffffffffffffffffffffffff169061358b565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff1690556019549091506124c5906bffffffffffffffffffffffff8316906145db565b6019556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526bffffffffffffffffffffffff831660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af115801561256a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258e91906149fd565b5060405133815273ffffffffffffffffffffffffffffffffffffffff808416916bffffffffffffffffffffffff8416918616907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a4505050565b6108fc8163ffffffff161080612628575060155463ffffffff7001000000000000000000000000000000009091048116908216115b1561265f576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612668826131eb565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c910160405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260106020526040902054163314612748576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600f602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556010909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c082015291146128dd576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff16331461293a576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b6000610a476129dc8361329f565b600084815260046020526040902054610100900463ffffffff166116e4565b612a03613168565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab491906149e4565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3360195484612b0191906145db565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff909216600483015260248201526044016120f8565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606083018190526001909101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c0820152919015612cef57816060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cea9190614a1f565b612cf2565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836020015163ffffffff168152602001600760008781526020019081526020016000208054612d4a90614684565b80601f0160208091040260200160405190810160405280929190818152602001828054612d7690614684565b8015612dc35780601f10612d9857610100808354040283529160200191612dc3565b820191906000526020600020905b815481529060010190602001808311612da657829003601f168201915b505050505081526020018360a001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff1667ffffffffffffffff1681526020018360c0015163ffffffff16815260200183608001516bffffffffffffffffffffffff168152602001836000015115158152602001601c60008781526020019081526020016000208054612ea090614684565b80601f0160208091040260200160405190810160405280929190818152602001828054612ecc90614684565b8015612f195780601f10612eee57610100808354040283529160200191612f19565b820191906000526020600020905b815481529060010190602001808311612efc57829003601f168201915b505050505081525092505050919050565b612f33836131eb565b60165463ffffffff16811115612f75576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260409020612f8e828483614726565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8383604051610afa929190614841565b6000610a47826129ce565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f602052604090205416331461302c576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82160361307b576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601060205260409020548116908216146111665773ffffffffffffffffffffffffffffffffffffffff82811660008181526010602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45050565b613132613168565b61313b81613793565b50565b6000610a47825490565b60006131548383613888565b9392505050565b60606000613154836138b2565b60005473ffffffffffffffffffffffffffffffffffffffff1633146131e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611f5b565b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314613248576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161461313b576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f81101561332c577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106132e4576132e461461d565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461331a57506000949350505050565b806133248161464c565b9150506132a6565b5081600f1a600181111561334257613342614312565b949350505050565b6000613154838361390d565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156133e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134069190614a56565b509450909250505060008113158061341d57508142105b8061343e575082801561343e575061343582426145db565b8463ffffffff16105b1561344d576017549550613451565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156134bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134e09190614a56565b50945090925050506000811315806134f757508142105b806135185750828015613518575061350f82426145db565b8463ffffffff16105b1561352757601854945061352b565b8094505b50505050915091565b60008061354688878b60c0015161395c565b90506000806135618b8a63ffffffff16858a8a60018b613a1e565b909250905061357081836149bf565b9b9a5050505050505050505050565b60006131548383613cab565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906137875760008160600151856136239190614940565b905060006136318583614994565b9050808360400181815161364591906149bf565b6bffffffffffffffffffffffff169052506136608582614aa6565b8360600181815161367191906149bf565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611f5b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600082600001828154811061389f5761389f61461d565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561105857602002820191906000526020600020905b8154815260200190600101908083116138ee5750505050509050919050565b600081815260018301602052604081205461395457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a47565b506000610a47565b6000808085600181111561397257613972614312565b03613981575062015f906139d6565b600185600181111561399557613995614312565b036139a457506201af406139d6565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6139e763ffffffff85166014614ad6565b6139f2846001614aed565b613a019060ff16611d4c614ad6565b613a0b90836145c8565b613a1591906145c8565b95945050505050565b60008060008960a0015161ffff1687613a379190614ad6565b9050838015613a455750803a105b15613a4d57503a5b60008415613ad0578a610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015613aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac991906149e4565b9050613b8c565b6101408b01516016546040517f1254414000000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff90911690631254414090602401602060405180830381865afa158015613b52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b7691906149e4565b8b60a0015161ffff16613b899190614ad6565b90505b613b9a61ffff871682614b06565b905060008782613baa8c8e6145c8565b613bb49086614ad6565b613bbe91906145c8565b613bd090670de0b6b3a7640000614ad6565b613bda9190614b06565b905060008c6040015163ffffffff1664e8d4a51000613bf99190614ad6565b898e6020015163ffffffff16858f88613c129190614ad6565b613c1c91906145c8565b613c2a90633b9aca00614ad6565b613c349190614ad6565b613c3e9190614b06565b613c4891906145c8565b90506b033b2e3c9fd0803ce8000000613c6182846145c8565b1115613c99576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b60008181526001830160205260408120548015613d94576000613ccf6001836145db565b8554909150600090613ce3906001906145db565b9050818114613d48576000866000018281548110613d0357613d0361461d565b9060005260206000200154905080876000018481548110613d2657613d2661461d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d5957613d59614b1a565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a47565b6000915050610a47565b5092915050565b60008060408385031215613db857600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613dff57835183529284019291840191600101613de3565b50909695505050505050565b60008083601f840112613e1d57600080fd5b50813567ffffffffffffffff811115613e3557600080fd5b602083019150836020828501011115613e4d57600080fd5b9250929050565b600080600060408486031215613e6957600080fd5b83359250602084013567ffffffffffffffff811115613e8757600080fd5b613e9386828701613e0b565b9497909650939450505050565b600081518084526020808501945080840160005b83811015613ee657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613eb4565b509495945050505050565b805163ffffffff16825260006101e06020830151613f17602086018263ffffffff169052565b506040830151613f2f604086018263ffffffff169052565b506060830151613f46606086018262ffffff169052565b506080830151613f5c608086018261ffff169052565b5060a0830151613f7c60a08601826bffffffffffffffffffffffff169052565b5060c0830151613f9460c086018263ffffffff169052565b5060e0830151613fac60e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a08084015181860183905261402183870182613ea0565b925050506101c08084015161404d8287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c0602088015161408560208501826bffffffffffffffffffffffff169052565b506040880151604084015260608801516140af60608501826bffffffffffffffffffffffff169052565b506080880151608084015260a08801516140d160a085018263ffffffff169052565b5060c08801516140e960c085018263ffffffff169052565b5060e088015160e08401526101008089015161410c8286018263ffffffff169052565b505061012088810151151590840152610140830181905261412f81840188613ef1565b90508281036101608401526141448187613ea0565b90508281036101808401526141598186613ea0565b9150506118976101a083018460ff169052565b73ffffffffffffffffffffffffffffffffffffffff8116811461313b57600080fd5b600080604083850312156141a157600080fd5b82356141ac8161416c565b91506020830135600481106141c057600080fd5b809150509250929050565b6000602082840312156141dd57600080fd5b5035919050565b6000815180845260005b8181101561420a576020818501810151868301820152016141ee565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061315460208301846141e4565b6000806040838503121561426e57600080fd5b8235915060208301356141c08161416c565b6000806020838503121561429357600080fd5b823567ffffffffffffffff808211156142ab57600080fd5b818501915085601f8301126142bf57600080fd5b8135818111156142ce57600080fd5b8660208260051b85010111156142e357600080fd5b60209290920196919550909350505050565b60006020828403121561430757600080fd5b81356131548161416c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061435557614355614312565b91905290565b602081016002831061435557614355614312565b803563ffffffff8116811461438357600080fd5b919050565b6000806040838503121561439b57600080fd5b8235600281106143aa57600080fd5b91506143b86020840161436f565b90509250929050565b6000806000604084860312156143d657600080fd5b83356143e18161416c565b9250602084013567ffffffffffffffff811115613e8757600080fd5b6000806040838503121561441057600080fd5b823561441b8161416c565b915060208301356141c08161416c565b6000806040838503121561443e57600080fd5b823591506143b86020840161436f565b6020815261447560208201835173ffffffffffffffffffffffffffffffffffffffff169052565b6000602083015161448e604084018263ffffffff169052565b5060408301516101408060608501526144ab6101608501836141e4565b915060608501516144cc60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614538818701836bffffffffffffffffffffffff169052565b860151905061012061454d8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183870152905061189783826141e4565b602081016004831061435557614355614312565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4757610a47614599565b81810381811115610a4757610a47614599565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361467d5761467d614599565b5060010190565b600181811c9082168061469857607f821691505b6020821081036146d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561472157600081815260208120601f850160051c810160208610156146fe5750805b601f850160051c820191505b8181101561471d5782815560010161470a565b5050505b505050565b67ffffffffffffffff83111561473e5761473e6145ee565b6147528361474c8354614684565b836146d7565b6000601f8411600181146147a4576000851561476e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561483a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156147f357868501358255602094850194600190920191016147d3565b508682101561482e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b828110156148e557815473ffffffffffffffffffffffffffffffffffffffff16845292840192600191820191016148b3565b505050838103828501528481528590820160005b8681101561493457823561490c8161416c565b73ffffffffffffffffffffffffffffffffffffffff16825291830191908301906001016148f9565b50979650505050505050565b6bffffffffffffffffffffffff828116828216039080821115613d9e57613d9e614599565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff808416806149b3576149b3614965565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115613d9e57613d9e614599565b6000602082840312156149f657600080fd5b5051919050565b600060208284031215614a0f57600080fd5b8151801515811461315457600080fd5b600060208284031215614a3157600080fd5b81516131548161416c565b805169ffffffffffffffffffff8116811461438357600080fd5b600080600080600060a08688031215614a6e57600080fd5b614a7786614a3c565b9450602086015193506040860151925060608601519150614a9a60808701614a3c565b90509295509295909350565b6bffffffffffffffffffffffff818116838216028082169190828114614ace57614ace614599565b505092915050565b8082028115828204841417610a4757610a47614599565b60ff8181168382160190811115610a4757610a47614599565b600082614b1557614b15614965565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var AutomationRegistryLogicBABI = AutomationRegistryLogicBMetaData.ABI var AutomationRegistryLogicBBin = AutomationRegistryLogicBMetaData.Bin -func DeployAutomationRegistryLogicB(auth *bind.TransactOpts, backend bind.ContractBackend, mode uint8, link common.Address, linkNativeFeed common.Address, fastGasFeed common.Address, automationForwarderLogic common.Address, allowedReadOnlyAddress common.Address) (common.Address, *types.Transaction, *AutomationRegistryLogicB, error) { +func DeployAutomationRegistryLogicB(auth *bind.TransactOpts, backend bind.ContractBackend, link common.Address, linkNativeFeed common.Address, fastGasFeed common.Address, automationForwarderLogic common.Address, allowedReadOnlyAddress common.Address) (common.Address, *types.Transaction, *AutomationRegistryLogicB, error) { parsed, err := AutomationRegistryLogicBMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -92,7 +92,7 @@ func DeployAutomationRegistryLogicB(auth *bind.TransactOpts, backend bind.Contra return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AutomationRegistryLogicBBin), backend, mode, link, linkNativeFeed, fastGasFeed, automationForwarderLogic, allowedReadOnlyAddress) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AutomationRegistryLogicBBin), backend, link, linkNativeFeed, fastGasFeed, automationForwarderLogic, allowedReadOnlyAddress) if err != nil { return common.Address{}, nil, nil, err } @@ -347,6 +347,28 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetCance return _AutomationRegistryLogicB.Contract.GetCancellationDelay(&_AutomationRegistryLogicB.CallOpts) } +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetChainModule(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getChainModule") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetChainModule() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetChainModule(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetChainModule() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetChainModule(&_AutomationRegistryLogicB.CallOpts) +} + func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getConditionalGasOverhead") @@ -545,28 +567,6 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetMinBa return _AutomationRegistryLogicB.Contract.GetMinBalanceForUpkeep(&_AutomationRegistryLogicB.CallOpts, id) } -func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetMode(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getMode") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) - - return out0, err - -} - -func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetMode() (uint8, error) { - return _AutomationRegistryLogicB.Contract.GetMode(&_AutomationRegistryLogicB.CallOpts) -} - -func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetMode() (uint8, error) { - return _AutomationRegistryLogicB.Contract.GetMode(&_AutomationRegistryLogicB.CallOpts) -} - func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) { var out []interface{} err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getPeerRegistryMigrationPermission", peer) @@ -1011,6 +1011,18 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetA return _AutomationRegistryLogicB.Contract.SetAdminPrivilegeConfig(&_AutomationRegistryLogicB.TransactOpts, admin, newPrivilegeConfig) } +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setChainSpecificModule", newModule) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetChainSpecificModule(&_AutomationRegistryLogicB.TransactOpts, newModule) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetChainSpecificModule(&_AutomationRegistryLogicB.TransactOpts, newModule) +} + func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) { return _AutomationRegistryLogicB.contract.Transact(opts, "setPayees", payees) } @@ -1435,6 +1447,123 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseCancelle return event, nil } +type AutomationRegistryLogicBChainSpecificModuleUpdatedIterator struct { + Event *AutomationRegistryLogicBChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicBChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBChainSpecificModuleUpdatedIterator{contract: _AutomationRegistryLogicB.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicBChainSpecificModuleUpdated, error) { + event := new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type AutomationRegistryLogicBDedupKeyAddedIterator struct { Event *AutomationRegistryLogicBDedupKeyAdded @@ -5261,6 +5390,8 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicB) ParseLog(log types.Lo return _AutomationRegistryLogicB.ParseAdminPrivilegeConfigSet(log) case _AutomationRegistryLogicB.abi.Events["CancelledUpkeepReport"].ID: return _AutomationRegistryLogicB.ParseCancelledUpkeepReport(log) + case _AutomationRegistryLogicB.abi.Events["ChainSpecificModuleUpdated"].ID: + return _AutomationRegistryLogicB.ParseChainSpecificModuleUpdated(log) case _AutomationRegistryLogicB.abi.Events["DedupKeyAdded"].ID: return _AutomationRegistryLogicB.ParseDedupKeyAdded(log) case _AutomationRegistryLogicB.abi.Events["FundsAdded"].ID: @@ -5333,6 +5464,10 @@ func (AutomationRegistryLogicBCancelledUpkeepReport) Topic() common.Hash { return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") } +func (AutomationRegistryLogicBChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + func (AutomationRegistryLogicBDedupKeyAdded) Topic() common.Hash { return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") } @@ -5466,6 +5601,8 @@ type AutomationRegistryLogicBInterface interface { GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) + GetChainModule(opts *bind.CallOpts) (common.Address, error) + GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) @@ -5484,8 +5621,6 @@ type AutomationRegistryLogicBInterface interface { GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) - GetMode(opts *bind.CallOpts) (uint8, error) - GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) GetPerPerformByteGasOverhead(opts *bind.CallOpts) (*big.Int, error) @@ -5536,6 +5671,8 @@ type AutomationRegistryLogicBInterface interface { SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) + SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) + SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) SetPeerRegistryMigrationPermission(opts *bind.TransactOpts, peer common.Address, permission uint8) (*types.Transaction, error) @@ -5576,6 +5713,12 @@ type AutomationRegistryLogicBInterface interface { ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryLogicBCancelledUpkeepReport, error) + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicBChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicBChainSpecificModuleUpdated, error) + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryLogicBDedupKeyAddedIterator, error) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) diff --git a/core/gethwrappers/generated/keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go b/core/gethwrappers/generated/keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go index 46da37b6886..0e0ec33fe81 100644 --- a/core/gethwrappers/generated/keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go +++ b/core/gethwrappers/generated/keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go @@ -46,12 +46,13 @@ type AutomationRegistryBase22OnchainConfig struct { Transcoder common.Address Registrars []common.Address UpkeepPrivilegeManager common.Address + ChainModule common.Address ReorgProtectionEnabled bool } var AutomationRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101606040523480156200001257600080fd5b506040516200563e3803806200563e83398101604081905262000035916200044b565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000472565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200044b565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200044b565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200044b565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200044b565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200044b565b3380600081620002eb5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200031e576200031e8162000387565b50505085600281111562000336576200033662000495565b60e08160028111156200034d576200034d62000495565b9052506001600160a01b0394851660805292841660a05290831660c052821661010052811661012052919091166101405250620004ab9050565b336001600160a01b03821603620003e15760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620002e2565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200044857600080fd5b50565b6000602082840312156200045e57600080fd5b81516200046b8162000432565b9392505050565b6000602082840312156200048557600080fd5b8151600381106200046b57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e051610100516101205161014051615126620005186000396000818160d6015261016f01526000611e2401526000505060008181611c4c0152818161346e015281816136010152613b1e01526000505060005050600061134a01526151266000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063a4c0ed3611610081578063b1dc65a41161005b578063b1dc65a4146102e0578063e3d0e712146102f3578063f2fde38b14610306576100d4565b8063a4c0ed3614610262578063aed2e92914610275578063afcb95d71461029f576100d4565b806379ba5097116100b257806379ba5097146101c757806381ff7048146101cf5780638da5cb5b14610244576100d4565b8063181f5a771461011b578063349e8cca1461016d5780636cad5469146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e322e30000000000000000081525081565b6040516101649190613d9d565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b6101196101c23660046141cc565b610319565b610119611230565b61022160155460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b6101196102703660046142e2565b611332565b61028861028336600461433e565b61154e565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527401000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102ee3660046143cf565b6116c6565b610119610301366004614486565b61197e565b610119610314366004614515565b6119a7565b6103216119bb565b601f8651111561035d576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff1660000361039a576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845186511415806103b957506103b1846003614561565b60ff16865111155b156103f0576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546bffffffffffffffffffffffff9091169060005b816bffffffffffffffffffffffff168110156104725761045f600e82815481106104365761043661457d565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484611a3e565b508061046a816145ac565b91505061040a565b5060008060005b836bffffffffffffffffffffffff1681101561057b57600d81815481106104a2576104a261457d565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff909216945090829081106104dd576104dd61457d565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055915080610573816145ac565b915050610479565b50610588600d6000613c72565b610594600e6000613c72565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c518110156109fd57600c60008e83815181106105d9576105d961457d565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615610644576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d828151811061066e5761066e61457d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036106c3576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f84815181106106f4576106f461457d565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c908290811061079c5761079c61457d565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361080c576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506108c7576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806109f5816145ac565b9150506105ba565b50508a51610a139150600d9060208d0190613c90565b508851610a2790600e9060208c0190613c90565b50604051806101400160405280856bffffffffffffffffffffffff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001600063ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020018960ff1681526020016012600001601e9054906101000a900460ff16151581526020016012600001601f9054906101000a900460ff1615158152602001886101e001511515815250601260008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160186101000a81548162ffffff021916908362ffffff16021790555060a082015181600001601b6101000a81548161ffff021916908361ffff16021790555060c082015181600001601d6101000a81548160ff021916908360ff16021790555060e082015181600001601e6101000a81548160ff02191690831515021790555061010082015181600001601f6101000a81548160ff0219169083151502179055506101208201518160010160006101000a81548160ff0219169083151502179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601460010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601460010160149054906101000a900463ffffffff1663ffffffff168152602001601460010160189054906101000a900463ffffffff1663ffffffff1681526020016014600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160178190555086610160015160188190555060006014600101601c9054906101000a900463ffffffff169050611017611c46565b601580547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff938416021780825560019260189161109291859178010000000000000000000000000000000000000000000000009004166145e4565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000886040516020016110c39190614652565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905260155490915061112c90469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f611cfb565b60115560005b61113c6009611da5565b81101561116c57611159611151600983611db5565b600990611dc8565b5080611164816145ac565b915050611132565b5060005b896101a00151518110156111c3576111b08a6101a0015182815181106111985761119861457d565b60200260200101516009611dea90919063ffffffff16565b50806111bb816145ac565b915050611170565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601460010160189054906101000a900463ffffffff168f8f8f878f8f60405161121a999897969594939291906147cd565b60405180910390a1505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146112b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146113a1576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146113db576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006113e982840184614863565b60008181526004602052604090205490915065010000000000900463ffffffff90811614611443576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461147e9085906c0100000000000000000000000090046bffffffffffffffffffffffff1661487c565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556019546114e99085906148a1565b6019556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b600080611559611e0c565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff16156115b8576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f890185900485028101850190955287855290936116b7938990899081908401838280828437600092019190915250611e7b92505050565b9093509150505b935093915050565b60005a60408051610140810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e010000000000000000000000000000000000000000000000000000000000008304811615801560e08401527f010000000000000000000000000000000000000000000000000000000000000090930481161515610100830152601354161515610120820152919250611858576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff166118a1576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a35146118dd576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08101516118ed9060016148b4565b60ff16861415806118fe5750858414155b15611935576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119458a8a8a8a8a8a8a8a6120a4565b60006119518a8a61230d565b905060208b0135600881901c63ffffffff1661196f848487846123c6565b50505050505050505050505050565b61199f868686868060200190518101906119989190614973565b8686610319565b505050505050565b6119af6119bb565b6119b881612ca7565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016112ad565b565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290611c3a576000816060015185611ad69190614ae1565b90506000611ae48583614b35565b90508083604001818151611af8919061487c565b6bffffffffffffffffffffffff16905250611b138582614b60565b83606001818151611b24919061487c565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115611c7c57611c7c614b90565b03611cf657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ccd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf19190614bbf565b905090565b504390565b6000808a8a8a8a8a8a8a8a8a604051602001611d1f99989796959493929190614bd8565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000611daf825490565b92915050565b6000611dc18383612d9c565b9392505050565b6000611dc18373ffffffffffffffffffffffffffffffffffffffff8416612dc6565b6000611dc18373ffffffffffffffffffffffffffffffffffffffff8416612ec0565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611a3c576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60125460009081907f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611ee0576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090611f5c908590602401613d9d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d169061202f9087908790600401614c6d565b60408051808303816000875af115801561204d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120719190614c86565b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b600087876040516120b6929190614cb4565b6040519081900381206120cd918b90602001614cc4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b888110156122a4576001858783602081106121395761213961457d565b61214691901a601b6148b4565b8c8c858181106121585761215861457d565b905060200201358b8b868181106121715761217161457d565b90506020020135604051600081526020016040526040516121ae949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156121d0573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff808216151580855261010090920416938301939093529095509350905061227e576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061229c906145ac565b91505061211c565b50827e010101010101010101010101010101010101010101010101010101010101018416146122ff576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6123466040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061235483850185614db5565b604081015151606082015151919250908114158061237757508082608001515114155b806123875750808260a001515114155b156123be576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600083604001515167ffffffffffffffff8111156123e6576123e6613db0565b6040519080825280602002602001820160405280156124aa57816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816124045790505b5090506000805b8560400151518110156128f45760046000876040015183815181106124d8576124d861457d565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015283518490839081106125bd576125bd61457d565b6020026020010151600001819052506125f2866040015182815181106125e5576125e561457d565b6020026020010151612f0f565b8382815181106126045761260461457d565b602002602001015160800190600181111561262157612621614b90565b9081600181111561263457612634614b90565b815250506126a88784838151811061264e5761264e61457d565b602002602001015160800151886060015184815181106126705761267061457d565b60200260200101518960a00151858151811061268e5761268e61457d565b6020026020010151518a600001518b602001516001612fba565b8382815181106126ba576126ba61457d565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff1681525050612747866040015182815181106127015761270161457d565b60200260200101518760800151838151811061271f5761271f61457d565b60200260200101518584815181106127395761273961457d565b60200260200101518a613005565b8483815181106127595761275961457d565b60200260200101516020018584815181106127765761277661457d565b602002602001015160e00182815250821515151581525050508281815181106127a1576127a161457d565b602002602001015160200151156127c4576127bd600183614ea2565b91506127c9565b6128e2565b61282f8382815181106127de576127de61457d565b60200260200101516000015160600151876060015183815181106128045761280461457d565b60200260200101518860a0015184815181106128225761282261457d565b6020026020010151611e7b565b8483815181106128415761284161457d565b602002602001015160600185848151811061285e5761285e61457d565b602002602001015160a00182815250821515151581525050508281815181106128895761288961457d565b602002602001015160a00151856128a09190614ebd565b94506128e2866040015182815181106128bb576128bb61457d565b60200260200101518483815181106128d5576128d561457d565b6020026020010151613188565b806128ec816145ac565b9150506124b1565b508061ffff16600003612908575050612ca1565b60c08601516129189060016148b4565b6129279060ff1661044c614ed0565b616b6c612935366010614ed0565b5a6129409088614ebd565b61294a91906148a1565b61295491906148a1565b61295e91906148a1565b9350611b5861297161ffff831686614ee7565b61297b91906148a1565b935060008060008060005b896040015151811015612b7c578681815181106129a5576129a561457d565b60200260200101516020015115612b6a57612a01898883815181106129cc576129cc61457d565b6020026020010151608001518c60a0015184815181106129ee576129ee61457d565b6020026020010151518e60c0015161329a565b878281518110612a1357612a1361457d565b602002602001015160c0018181525050612a6f8b8b604001518381518110612a3d57612a3d61457d565b6020026020010151898481518110612a5757612a5761457d565b60200260200101518d600001518e602001518b6132ba565b9093509150612a7e828561487c565b9350612a8a838661487c565b9450868181518110612a9e57612a9e61457d565b60200260200101516060015115158a604001518281518110612ac257612ac261457d565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b8486612af7919061487c565b8a8581518110612b0957612b0961457d565b602002602001015160a001518b8681518110612b2757612b2761457d565b602002602001015160c001518f608001518781518110612b4957612b4961457d565b6020026020010151604051612b619493929190614efb565b60405180910390a35b80612b74816145ac565b915050612986565b5050336000908152600b602052604090208054849250600290612bb49084906201000090046bffffffffffffffffffffffff1661487c565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160008282829054906101000a90046bffffffffffffffffffffffff16612c0e919061487c565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550876060015163ffffffff168563ffffffff161115612c9c57601280547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8816021790555b505050505b50505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612d26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016112ad565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110612db357612db361457d565b9060005260206000200154905092915050565b60008181526001830160205260408120548015612eaf576000612dea600183614ebd565b8554909150600090612dfe90600190614ebd565b9050818114612e63576000866000018281548110612e1e57612e1e61457d565b9060005260206000200154905080876000018481548110612e4157612e4161457d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e7457612e74614f38565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611daf565b6000915050611daf565b5092915050565b6000818152600183016020526040812054612f0757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611daf565b506000611daf565b6000818160045b600f811015612f9c577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612f5457612f5461457d565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612f8a57506000949350505050565b80612f94816145ac565b915050612f16565b5081600f1a6001811115612fb257612fb2614b90565b949350505050565b600080612fcc88878b60c001516133ad565b9050600080612fe78b8a63ffffffff16858a8a60018b613439565b9092509050612ff6818361487c565b9b9a5050505050505050505050565b60008080808560800151600181111561302057613020614b90565b036130455761303187878787613892565b6130405760009250905061317f565b6130bc565b60018560800151600181111561305d5761305d614b90565b0361308a57600061306f888887613994565b9250905080613084575060009250905061317f565b506130bc565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130c4611c46565b85516040015163ffffffff161161311857867fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516131059190613d9d565b60405180910390a260009250905061317f565b84604001516bffffffffffffffffffffffff16856000015160a001516bffffffffffffffffffffffff16101561317857867f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02876040516131059190613d9d565b6001925090505b94509492505050565b6000816080015160018111156131a0576131a0614b90565b03613212576131ad611c46565b6000838152600460205260409020600101805463ffffffff929092167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555050565b60018160800151600181111561322a5761322a614b90565b036132965760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b5050565b60006132a78484846133ad565b905080851015612fb25750929392505050565b6000806132d5888760a001518860c001518888886001613439565b909250905060006132e6828461487c565b600089815260046020526040902060010180549192508291600c9061332a9084906c0100000000000000000000000090046bffffffffffffffffffffffff16614ae1565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a8152600460205260408120600101805485945090926133739185911661487c565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b600080808560018111156133c3576133c3614b90565b036133d2575062015f906133f1565b60018560018111156133e6576133e6614b90565b0361308a57506201adb05b61340263ffffffff85166014614ed0565b61340d8460016148b4565b61341c9060ff16611d4c614ed0565b61342690836148a1565b61343091906148a1565b95945050505050565b60008060008960a0015161ffff16876134529190614ed0565b90508380156134605750803a105b1561346857503a5b600060027f0000000000000000000000000000000000000000000000000000000000000000600281111561349e5761349e614b90565b036135fd5760408051600081526020810190915285156134fc576000366040518060800160405280604881526020016150d2604891396040516020016134e693929190614f67565b6040516020818303038152906040529050613564565b60165461351890640100000000900463ffffffff166004614f8e565b63ffffffff1667ffffffffffffffff81111561353657613536613db0565b6040519080825280601f01601f191660200182016040528015613560576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e906135b4908490600401613d9d565b602060405180830381865afa1580156135d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135f59190614bbf565b915050613757565b60017f0000000000000000000000000000000000000000000000000000000000000000600281111561363157613631614b90565b036137575784156136b357606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ac9190614bbf565b9050613757565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa158015613701573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137259190614fae565b505060165492945061374893505050640100000000900463ffffffff1682614ed0565b613753906010614ed0565b9150505b8461377357808b60a0015161ffff166137709190614ed0565b90505b61378161ffff871682614ee7565b9050600087826137918c8e6148a1565b61379b9086614ed0565b6137a591906148a1565b6137b790670de0b6b3a7640000614ed0565b6137c19190614ee7565b905060008c6040015163ffffffff1664e8d4a510006137e09190614ed0565b898e6020015163ffffffff16858f886137f99190614ed0565b61380391906148a1565b61381190633b9aca00614ed0565b61381b9190614ed0565b6138259190614ee7565b61382f91906148a1565b90506b033b2e3c9fd0803ce800000061384882846148a1565b1115613880576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b600080848060200190518101906138a99190614ff8565b845160c00151815191925063ffffffff9081169116101561390657857f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516138f49190613d9d565b60405180910390a26000915050612fb2565b826101200151801561393a575060208101511580159061393a5750602081015181516139379063ffffffff16613b18565b14155b806139535750613948611c46565b815163ffffffff1610155b1561398857857f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516138f49190613d9d565b50600195945050505050565b6000806000848060200190518101906139ad9190615050565b9050600086826000015183602001518460400151604051602001613a0f94939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508461012001518015613a5d5750608082015115801590613a5d57508160800151613a5a836060015163ffffffff16613b18565b14155b80613a795750613a6b611c46565b826060015163ffffffff1610155b15613ac357867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc30187604051613aae9190613d9d565b60405180910390a26000935091506116be9050565b60008181526008602052604090205460ff1615613b0a57867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e887604051613aae9190613d9d565b600197909650945050505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115613b4e57613b4e614b90565b03613c68576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bc59190614bbf565b90508083101580613be05750610100613bde8483614ebd565b115b15613bee5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015613c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc19190614bbf565b504090565b919050565b50805460008255906000526020600020908101906119b89190613d1a565b828054828255906000526020600020908101928215613d0a579160200282015b82811115613d0a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613cb0565b50613d16929150613d1a565b5090565b5b80821115613d165760008155600101613d1b565b60005b83811015613d4a578181015183820152602001613d32565b50506000910152565b60008151808452613d6b816020860160208601613d2f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611dc16020830184613d53565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff81118282101715613e0357613e03613db0565b60405290565b60405160c0810167ffffffffffffffff81118282101715613e0357613e03613db0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e7357613e73613db0565b604052919050565b600067ffffffffffffffff821115613e9557613e95613db0565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146119b857600080fd5b8035613c6d81613e9f565b600082601f830112613edd57600080fd5b81356020613ef2613eed83613e7b565b613e2c565b82815260059290921b84018101918181019086841115613f1157600080fd5b8286015b84811015613f35578035613f2881613e9f565b8352918301918301613f15565b509695505050505050565b803560ff81168114613c6d57600080fd5b63ffffffff811681146119b857600080fd5b8035613c6d81613f51565b62ffffff811681146119b857600080fd5b8035613c6d81613f6e565b61ffff811681146119b857600080fd5b8035613c6d81613f8a565b6bffffffffffffffffffffffff811681146119b857600080fd5b8035613c6d81613fa5565b80151581146119b857600080fd5b8035613c6d81613fca565b60006102008284031215613ff657600080fd5b613ffe613ddf565b905061400982613f63565b815261401760208301613f63565b602082015261402860408301613f63565b604082015261403960608301613f7f565b606082015261404a60808301613f9a565b608082015261405b60a08301613fbf565b60a082015261406c60c08301613f63565b60c082015261407d60e08301613f63565b60e0820152610100614090818401613f63565b908201526101206140a2838201613f63565b90820152610140828101359082015261016080830135908201526101806140ca818401613ec1565b908201526101a08281013567ffffffffffffffff8111156140ea57600080fd5b6140f685828601613ecc565b8284015250506101c061410a818401613ec1565b908201526101e061411c838201613fd8565b9082015292915050565b803567ffffffffffffffff81168114613c6d57600080fd5b600082601f83011261414f57600080fd5b813567ffffffffffffffff81111561416957614169613db0565b61419a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613e2c565b8181528460208386010111156141af57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156141e557600080fd5b863567ffffffffffffffff808211156141fd57600080fd5b6142098a838b01613ecc565b9750602089013591508082111561421f57600080fd5b61422b8a838b01613ecc565b965061423960408a01613f40565b9550606089013591508082111561424f57600080fd5b61425b8a838b01613fe3565b945061426960808a01614126565b935060a089013591508082111561427f57600080fd5b5061428c89828a0161413e565b9150509295509295509295565b60008083601f8401126142ab57600080fd5b50813567ffffffffffffffff8111156142c357600080fd5b6020830191508360208285010111156142db57600080fd5b9250929050565b600080600080606085870312156142f857600080fd5b843561430381613e9f565b935060208501359250604085013567ffffffffffffffff81111561432657600080fd5b61433287828801614299565b95989497509550505050565b60008060006040848603121561435357600080fd5b83359250602084013567ffffffffffffffff81111561437157600080fd5b61437d86828701614299565b9497909650939450505050565b60008083601f84011261439c57600080fd5b50813567ffffffffffffffff8111156143b457600080fd5b6020830191508360208260051b85010111156142db57600080fd5b60008060008060008060008060e0898b0312156143eb57600080fd5b606089018a8111156143fc57600080fd5b8998503567ffffffffffffffff8082111561441657600080fd5b6144228c838d01614299565b909950975060808b013591508082111561443b57600080fd5b6144478c838d0161438a565b909750955060a08b013591508082111561446057600080fd5b5061446d8b828c0161438a565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c0878903121561449f57600080fd5b863567ffffffffffffffff808211156144b757600080fd5b6144c38a838b01613ecc565b975060208901359150808211156144d957600080fd5b6144e58a838b01613ecc565b96506144f360408a01613f40565b9550606089013591508082111561450957600080fd5b61425b8a838b0161413e565b60006020828403121561452757600080fd5b8135611dc181613e9f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160290811690818114612eb957612eb9614532565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145dd576145dd614532565b5060010190565b63ffffffff818116838216019080821115612eb957612eb9614532565b600081518084526020808501945080840160005b8381101561464757815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614615565b509495945050505050565b6020815261466960208201835163ffffffff169052565b60006020830151614682604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006146fb8185018363ffffffff169052565b84015190506101206147148482018363ffffffff169052565b840151905061014061472d8482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147708185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506102006101c08181860152614790610220860184614601565b908601519092506101e06147bb8682018373ffffffffffffffffffffffffffffffffffffffff169052565b90950151151593019290925250919050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526147fd8184018a614601565b905082810360808401526148118189614601565b905060ff871660a084015282810360c084015261482e8187613d53565b905067ffffffffffffffff851660e08401528281036101008401526148538185613d53565b9c9b505050505050505050505050565b60006020828403121561487557600080fd5b5035919050565b6bffffffffffffffffffffffff818116838216019080821115612eb957612eb9614532565b80820180821115611daf57611daf614532565b60ff8181168382160190811115611daf57611daf614532565b8051613c6d81613f51565b8051613c6d81613f6e565b8051613c6d81613f8a565b8051613c6d81613fa5565b8051613c6d81613e9f565b600082601f83011261491557600080fd5b81516020614925613eed83613e7b565b82815260059290921b8401810191818101908684111561494457600080fd5b8286015b84811015613f3557805161495b81613e9f565b8352918301918301614948565b8051613c6d81613fca565b60006020828403121561498557600080fd5b815167ffffffffffffffff8082111561499d57600080fd5b9083019061020082860312156149b257600080fd5b6149ba613ddf565b6149c3836148cd565b81526149d1602084016148cd565b60208201526149e2604084016148cd565b60408201526149f3606084016148d8565b6060820152614a04608084016148e3565b6080820152614a1560a084016148ee565b60a0820152614a2660c084016148cd565b60c0820152614a3760e084016148cd565b60e0820152610100614a4a8185016148cd565b90820152610120614a5c8482016148cd565b9082015261014083810151908201526101608084015190820152610180614a848185016148f9565b908201526101a08381015183811115614a9c57600080fd5b614aa888828701614904565b8284015250506101c09150614abe8284016148f9565b828201526101e09150614ad2828401614968565b91810191909152949350505050565b6bffffffffffffffffffffffff828116828216039080821115612eb957612eb9614532565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff80841680614b5457614b54614b06565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114614b8857614b88614532565b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215614bd157600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614c1f8285018b614601565b91508382036080850152614c33828a614601565b915060ff881660a085015283820360c0850152614c508288613d53565b90861660e085015283810361010085015290506148538185613d53565b828152604060208201526000612fb26040830184613d53565b60008060408385031215614c9957600080fd5b8251614ca481613fca565b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614ceb57600080fd5b81356020614cfb613eed83613e7b565b82815260059290921b84018101918181019086841115614d1a57600080fd5b8286015b84811015613f355780358352918301918301614d1e565b600082601f830112614d4657600080fd5b81356020614d56613eed83613e7b565b82815260059290921b84018101918181019086841115614d7557600080fd5b8286015b84811015613f3557803567ffffffffffffffff811115614d995760008081fd5b614da78986838b010161413e565b845250918301918301614d79565b600060208284031215614dc757600080fd5b813567ffffffffffffffff80821115614ddf57600080fd5b9083019060c08286031215614df357600080fd5b614dfb613e09565b8235815260208301356020820152604083013582811115614e1b57600080fd5b614e2787828601614cda565b604083015250606083013582811115614e3f57600080fd5b614e4b87828601614cda565b606083015250608083013582811115614e6357600080fd5b614e6f87828601614d35565b60808301525060a083013582811115614e8757600080fd5b614e9387828601614d35565b60a08301525095945050505050565b61ffff818116838216019080821115612eb957612eb9614532565b81810381811115611daf57611daf614532565b8082028115828204841417611daf57611daf614532565b600082614ef657614ef6614b06565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000614f2e6080830184613d53565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b828482376000838201600081528351614f84818360208801613d2f565b0195945050505050565b63ffffffff818116838216028082169190828114614b8857614b88614532565b60008060008060008060c08789031215614fc757600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b60006040828403121561500a57600080fd5b6040516040810181811067ffffffffffffffff8211171561502d5761502d613db0565b604052825161503b81613f51565b81526020928301519281019290925250919050565b600060a0828403121561506257600080fd5b60405160a0810181811067ffffffffffffffff8211171561508557615085613db0565b8060405250825181526020830151602082015260408301516150a681613f51565b604082015260608301516150b981613f51565b6060820152608092830151928101929092525091905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b506040516200534d3803806200534d8339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051614f28620004256000396000818160d6015261016f01526000611b29015260005050600050506000505060006104330152614f286000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e3d0e7121161005b578063e3d0e712146102e0578063f2fde38b146102f3578063f75f6b1114610306576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102cd576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e322e30000000000000000081525081565b6040516101649190613c24565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610319565b61020e60155460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613cb2565b61041b565b610275610270366004613d0e565b610637565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527401000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102db366004613d9f565b6107ad565b6101196102ee366004614070565b610ae8565b61011961030136600461413d565b610b11565b610119610314366004614341565b610b25565b60015473ffffffffffffffffffffffffffffffffffffffff16331461039f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461048a576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104c4576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104d2828401846143d0565b60008181526004602052604090205490915065010000000000900463ffffffff9081161461052c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600101546105679085906c0100000000000000000000000090046bffffffffffffffffffffffff16614418565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556019546105d290859061443d565b6019556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b600080610642611b11565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff16156106a1576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f890185900485028101850190955287855290936107a0938990899081908401838280828437600092019190915250611b8292505050565b9097909650945050505050565b60005a60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e010000000000000000000000000000000000000000000000000000000000008304811615801560e08401527f01000000000000000000000000000000000000000000000000000000000000009093048116151561010080840191909152601354918216151561012084015273ffffffffffffffffffffffffffffffffffffffff910416610140820152919250610963576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff166109ac576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a35146109e8576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08101516109f890600161447f565b60ff1686141580610a095750858414155b15610a40576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a508a8a8a8a8a8a8a8a611dab565b6000610a5c8a8a612014565b905060208b0135600881901c63ffffffff16610a798484876120cf565b836060015163ffffffff168163ffffffff161115610ad957601280547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b610b0986868686806020019051810190610b02919061453e565b8686610b25565b505050505050565b610b196129ca565b610b2281612a4b565b50565b610b2d6129ca565b601f86511115610b69576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff16600003610ba6576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518651141580610bc55750610bbd8460036146c0565b60ff16865111155b15610bfc576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546bffffffffffffffffffffffff9091169060005b816bffffffffffffffffffffffff16811015610c7e57610c6b600e8281548110610c4257610c42614450565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612b40565b5080610c76816146dc565b915050610c16565b5060008060005b836bffffffffffffffffffffffff16811015610d8757600d8181548110610cae57610cae614450565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff90921694509082908110610ce957610ce9614450565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055915080610d7f816146dc565b915050610c85565b50610d94600d6000613b03565b610da0600e6000613b03565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c5181101561120957600c60008e8381518110610de557610de5614450565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615610e50576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110610e7a57610e7a614450565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610ecf576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f8481518110610f0057610f00614450565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110610fa857610fa8614450565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611018576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506110d3576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905580611201816146dc565b915050610dc6565b50508a5161121f9150600d9060208d0190613b21565b50885161123390600e9060208c0190613b21565b50604051806101600160405280856bffffffffffffffffffffffff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001600063ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020018960ff1681526020016012600001601e9054906101000a900460ff16151581526020016012600001601f9054906101000a900460ff161515815260200188610200015115158152602001886101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601260008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160186101000a81548162ffffff021916908362ffffff16021790555060a082015181600001601b6101000a81548161ffff021916908361ffff16021790555060c082015181600001601d6101000a81548160ff021916908360ff16021790555060e082015181600001601e6101000a81548160ff02191690831515021790555061010082015181600001601f6101000a81548160ff0219169083151502179055506101208201518160010160006101000a81548160ff0219169083151502179055506101408201518160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601460010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601460010160149054906101000a900463ffffffff1663ffffffff168152602001601460010160189054906101000a900463ffffffff1663ffffffff1681526020016014600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160178190555086610160015160188190555060006014600101601c9054906101000a900463ffffffff169050876101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f89190614714565b601580547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891611973918591780100000000000000000000000000000000000000000000000090041661472d565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000886040516020016119a4919061479b565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601554909150611a0d90469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612d48565b60115560005b611a1d6009612df2565b811015611a4d57611a3a611a32600983612dfc565b600990612e0f565b5080611a45816146dc565b915050611a13565b5060005b896101a0015151811015611aa457611a918a6101a001518281518110611a7957611a79614450565b60200260200101516009612e3190919063ffffffff16565b5080611a9c816146dc565b915050611a51565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601460010160189054906101000a900463ffffffff168f8f8f878f8f604051611afb9998979695949392919061493f565b60405180910390a1505050505050505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611b80576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081907f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611be7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090611c63908590602401613c24565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d1690611d3690879087906004016149d5565b60408051808303816000875af1158015611d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7891906149ee565b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60008787604051611dbd929190614a1c565b604051908190038120611dd4918b90602001614a2c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015611fab57600185878360208110611e4057611e40614450565b611e4d91901a601b61447f565b8c8c85818110611e5f57611e5f614450565b905060200201358b8b86818110611e7857611e78614450565b9050602002013560405160008152602001604052604051611eb5949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611ed7573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050611f85576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080611fa3906146dc565b915050611e23565b50827e01010101010101010101010101010101010101010101010101010101010101841614612006576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61204d6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061205b83850185614b1d565b604081015151606082015151919250908114158061207e57508082608001515114155b8061208e5750808260a001515114155b156120c5576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b600082604001515167ffffffffffffffff8111156120ef576120ef613e56565b6040519080825280602002602001820160405280156121b357816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161210d5790505b50905060008085610140015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222d9190614714565b905060005b85604001515181101561267757600460008760400151838151811061225957612259614450565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c0820152845185908390811061233e5761233e614450565b6020026020010151600001819052506123738660400151828151811061236657612366614450565b6020026020010151612e53565b84828151811061238557612385614450565b60200260200101516080019060018111156123a2576123a2614c0a565b908160018111156123b5576123b5614c0a565b81525050612429878583815181106123cf576123cf614450565b602002602001015160800151886060015184815181106123f1576123f1614450565b60200260200101518960a00151858151811061240f5761240f614450565b6020026020010151518a600001518b602001516001612efe565b84828151811061243b5761243b614450565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250506124c98660400151828151811061248257612482614450565b602002602001015183886080015184815181106124a1576124a1614450565b60200260200101518785815181106124bb576124bb614450565b60200260200101518b612f49565b8583815181106124db576124db614450565b60200260200101516020018684815181106124f8576124f8614450565b602002602001015160e001828152508215151515815250505083818151811061252357612523614450565b602002602001015160200151156125465761253f600184614c39565b925061254b565b612665565b6125b184828151811061256057612560614450565b602002602001015160000151606001518760600151838151811061258657612586614450565b60200260200101518860a0015184815181106125a4576125a4614450565b6020026020010151611b82565b8583815181106125c3576125c3614450565b60200260200101516060018684815181106125e0576125e0614450565b602002602001015160a001828152508215151515815250505083818151811061260b5761260b614450565b602002602001015160a00151856126229190614c54565b94506126658660400151828151811061263d5761263d614450565b60200260200101518386848151811061265857612658614450565b60200260200101516130c8565b8061266f816146dc565b915050612232565b508161ffff1660000361268c57505050505050565b60c086015161269c90600161447f565b6126ab9060ff1661044c614c67565b616dc46126b9366010614c67565b5a6126c49088614c54565b6126ce919061443d565b6126d8919061443d565b6126e2919061443d565b9350611c206126f561ffff841686614cad565b6126ff919061443d565b935060008060008060005b8960400151518110156129005787818151811061272957612729614450565b602002602001015160200151156128ee576127858989838151811061275057612750614450565b6020026020010151608001518c60a00151848151811061277257612772614450565b6020026020010151518e60c001516131cd565b88828151811061279757612797614450565b602002602001015160c00181815250506127f38b8b6040015183815181106127c1576127c1614450565b60200260200101518a84815181106127db576127db614450565b60200260200101518d600001518e602001518c6131ed565b90935091506128028285614418565b935061280e8386614418565b945087818151811061282257612822614450565b60200260200101516060015115158a60400151828151811061284657612846614450565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b848661287b9190614418565b8b858151811061288d5761288d614450565b602002602001015160a001518c86815181106128ab576128ab614450565b602002602001015160c001518f6080015187815181106128cd576128cd614450565b60200260200101516040516128e59493929190614cc1565b60405180910390a35b806128f8816146dc565b91505061270a565b5050336000908152600b6020526040902080548492506002906129389084906201000090046bffffffffffffffffffffffff16614418565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160008282829054906101000a90046bffffffffffffffffffffffff166129929190614418565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610396565b3373ffffffffffffffffffffffffffffffffffffffff821603612aca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610396565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612d3c576000816060015185612bd89190614cfe565b90506000612be68583614d23565b90508083604001818151612bfa9190614418565b6bffffffffffffffffffffffff16905250612c158582614d4e565b83606001818151612c269190614418565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000808a8a8a8a8a8a8a8a8a604051602001612d6c99989796959493929190614d7e565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b60006120c9825490565b6000612e0883836132e0565b9392505050565b6000612e088373ffffffffffffffffffffffffffffffffffffffff841661330a565b6000612e088373ffffffffffffffffffffffffffffffffffffffff8416613404565b6000818160045b600f811015612ee0577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612e9857612e98614450565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612ece57506000949350505050565b80612ed8816146dc565b915050612e5a565b5081600f1a6001811115612ef657612ef6614c0a565b949350505050565b600080612f1088878b60c00151613453565b9050600080612f2b8b8a63ffffffff16858a8a60018b6134df565b9092509050612f3a8183614418565b9b9a5050505050505050505050565b600080808085608001516001811115612f6457612f64614c0a565b03612f8a57612f76888888888861376c565b612f85576000925090506130be565b613002565b600185608001516001811115612fa257612fa2614c0a565b03612fd0576000612fb5898989886138f5565b9250905080612fca57506000925090506130be565b50613002565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516040015163ffffffff16871061305757877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516130449190613c24565b60405180910390a26000925090506130be565b84604001516bffffffffffffffffffffffff16856000015160a001516bffffffffffffffffffffffff1610156130b757877f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02876040516130449190613c24565b6001925090505b9550959350505050565b6000816080015160018111156130e0576130e0614c0a565b0361314457600083815260046020526040902060010180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff851602179055505050565b60018160800151600181111561315c5761315c614c0a565b036131c85760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60006131da848484613453565b905080851015612ef65750929392505050565b600080613208888760a001518860c0015188888860016134df565b909250905060006132198284614418565b600089815260046020526040902060010180549192508291600c9061325d9084906c0100000000000000000000000090046bffffffffffffffffffffffff16614cfe565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a8152600460205260408120600101805485945090926132a691859116614418565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b60008260000182815481106132f7576132f7614450565b9060005260206000200154905092915050565b600081815260018301602052604081205480156133f357600061332e600183614c54565b855490915060009061334290600190614c54565b90508181146133a757600086600001828154811061336257613362614450565b906000526020600020015490508087600001848154811061338557613385614450565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806133b8576133b8614e13565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506120c9565b60009150506120c9565b5092915050565b600081815260018301602052604081205461344b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556120c9565b5060006120c9565b6000808085600181111561346957613469614c0a565b03613478575062015f90613497565b600185600181111561348c5761348c614c0a565b03612fd057506201af405b6134a863ffffffff85166014614c67565b6134b384600161447f565b6134c29060ff16611d4c614c67565b6134cc908361443d565b6134d6919061443d565b95945050505050565b60008060008960a0015161ffff16876134f89190614c67565b90508380156135065750803a105b1561350e57503a5b60008415613591578a610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015613566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358a9190614714565b905061364d565b6101408b01516016546040517f1254414000000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff90911690631254414090602401602060405180830381865afa158015613613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136379190614714565b8b60a0015161ffff1661364a9190614c67565b90505b61365b61ffff871682614cad565b90506000878261366b8c8e61443d565b6136759086614c67565b61367f919061443d565b61369190670de0b6b3a7640000614c67565b61369b9190614cad565b905060008c6040015163ffffffff1664e8d4a510006136ba9190614c67565b898e6020015163ffffffff16858f886136d39190614c67565b6136dd919061443d565b6136eb90633b9aca00614c67565b6136f59190614c67565b6136ff9190614cad565b613709919061443d565b90506b033b2e3c9fd0803ce8000000613722828461443d565b111561375a576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b600080848060200190518101906137839190614e42565b845160c00151815191925063ffffffff908116911610156137e057867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516137ce9190613c24565b60405180910390a260009150506134d6565b82610120015180156138a157506020810151158015906138a15750602081015161014084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561387a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389e9190614714565b14155b806138b35750805163ffffffff168611155b156138e857867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516137ce9190613c24565b5060019695505050505050565b60008060008480602001905181019061390e9190614e9a565b905060008782600001518360200151846040015160405160200161397094939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508461012001518015613a4c5750608082015115801590613a4c5750608082015161014086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a499190614714565b14155b80613a61575086826060015163ffffffff1610155b15613aab57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc30187604051613a969190613c24565b60405180910390a2600093509150613afa9050565b60008181526008602052604090205460ff1615613af257877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e887604051613a969190613c24565b600193509150505b94509492505050565b5080546000825590600052602060002090810190610b229190613bab565b828054828255906000526020600020908101928215613b9b579160200282015b82811115613b9b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613b41565b50613ba7929150613bab565b5090565b5b80821115613ba75760008155600101613bac565b6000815180845260005b81811015613be657602081850181015186830182015201613bca565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612e086020830184613bc0565b73ffffffffffffffffffffffffffffffffffffffff81168114610b2257600080fd5b8035613c6481613c37565b919050565b60008083601f840112613c7b57600080fd5b50813567ffffffffffffffff811115613c9357600080fd5b602083019150836020828501011115613cab57600080fd5b9250929050565b60008060008060608587031215613cc857600080fd5b8435613cd381613c37565b935060208501359250604085013567ffffffffffffffff811115613cf657600080fd5b613d0287828801613c69565b95989497509550505050565b600080600060408486031215613d2357600080fd5b83359250602084013567ffffffffffffffff811115613d4157600080fd5b613d4d86828701613c69565b9497909650939450505050565b60008083601f840112613d6c57600080fd5b50813567ffffffffffffffff811115613d8457600080fd5b6020830191508360208260051b8501011115613cab57600080fd5b60008060008060008060008060e0898b031215613dbb57600080fd5b606089018a811115613dcc57600080fd5b8998503567ffffffffffffffff80821115613de657600080fd5b613df28c838d01613c69565b909950975060808b0135915080821115613e0b57600080fd5b613e178c838d01613d5a565b909750955060a08b0135915080821115613e3057600080fd5b50613e3d8b828c01613d5a565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610220810167ffffffffffffffff81118282101715613ea957613ea9613e56565b60405290565b60405160c0810167ffffffffffffffff81118282101715613ea957613ea9613e56565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f1957613f19613e56565b604052919050565b600067ffffffffffffffff821115613f3b57613f3b613e56565b5060051b60200190565b600082601f830112613f5657600080fd5b81356020613f6b613f6683613f21565b613ed2565b82815260059290921b84018101918181019086841115613f8a57600080fd5b8286015b84811015613fae578035613fa181613c37565b8352918301918301613f8e565b509695505050505050565b803560ff81168114613c6457600080fd5b600082601f830112613fdb57600080fd5b813567ffffffffffffffff811115613ff557613ff5613e56565b61402660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613ed2565b81815284602083860101111561403b57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613c6457600080fd5b60008060008060008060c0878903121561408957600080fd5b863567ffffffffffffffff808211156140a157600080fd5b6140ad8a838b01613f45565b975060208901359150808211156140c357600080fd5b6140cf8a838b01613f45565b96506140dd60408a01613fb9565b955060608901359150808211156140f357600080fd5b6140ff8a838b01613fca565b945061410d60808a01614058565b935060a089013591508082111561412357600080fd5b5061413089828a01613fca565b9150509295509295509295565b60006020828403121561414f57600080fd5b8135612e0881613c37565b63ffffffff81168114610b2257600080fd5b8035613c648161415a565b62ffffff81168114610b2257600080fd5b8035613c6481614177565b61ffff81168114610b2257600080fd5b8035613c6481614193565b6bffffffffffffffffffffffff81168114610b2257600080fd5b8035613c64816141ae565b8015158114610b2257600080fd5b8035613c64816141d3565b600061022082840312156141ff57600080fd5b614207613e85565b90506142128261416c565b81526142206020830161416c565b60208201526142316040830161416c565b604082015261424260608301614188565b6060820152614253608083016141a3565b608082015261426460a083016141c8565b60a082015261427560c0830161416c565b60c082015261428660e0830161416c565b60e082015261010061429981840161416c565b908201526101206142ab83820161416c565b90820152610140828101359082015261016080830135908201526101806142d3818401613c59565b908201526101a08281013567ffffffffffffffff8111156142f357600080fd5b6142ff85828601613f45565b8284015250506101c0614313818401613c59565b908201526101e0614325838201613c59565b908201526102006143378382016141e1565b9082015292915050565b60008060008060008060c0878903121561435a57600080fd5b863567ffffffffffffffff8082111561437257600080fd5b61437e8a838b01613f45565b9750602089013591508082111561439457600080fd5b6143a08a838b01613f45565b96506143ae60408a01613fb9565b955060608901359150808211156143c457600080fd5b6140ff8a838b016141ec565b6000602082840312156143e257600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156133fd576133fd6143e9565b808201808211156120c9576120c96143e9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff81811683821601908111156120c9576120c96143e9565b8051613c648161415a565b8051613c6481614177565b8051613c6481614193565b8051613c64816141ae565b8051613c6481613c37565b600082601f8301126144e057600080fd5b815160206144f0613f6683613f21565b82815260059290921b8401810191818101908684111561450f57600080fd5b8286015b84811015613fae57805161452681613c37565b8352918301918301614513565b8051613c64816141d3565b60006020828403121561455057600080fd5b815167ffffffffffffffff8082111561456857600080fd5b90830190610220828603121561457d57600080fd5b614585613e85565b61458e83614498565b815261459c60208401614498565b60208201526145ad60408401614498565b60408201526145be606084016144a3565b60608201526145cf608084016144ae565b60808201526145e060a084016144b9565b60a08201526145f160c08401614498565b60c082015261460260e08401614498565b60e0820152610100614615818501614498565b90820152610120614627848201614498565b908201526101408381015190820152610160808401519082015261018061464f8185016144c4565b908201526101a0838101518381111561466757600080fd5b614673888287016144cf565b8284015250506101c091506146898284016144c4565b828201526101e0915061469d8284016144c4565b8282015261020091506146b1828401614533565b91810191909152949350505050565b60ff81811683821602908116908181146133fd576133fd6143e9565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361470d5761470d6143e9565b5060010190565b60006020828403121561472657600080fd5b5051919050565b63ffffffff8181168382160190808211156133fd576133fd6143e9565b600081518084526020808501945080840160005b8381101561479057815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161475e565b509495945050505050565b602081526147b260208201835163ffffffff169052565b600060208301516147cb604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006148448185018363ffffffff169052565b840151905061012061485d8482018363ffffffff169052565b84015190506101406148768482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06148b98185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506102206101c081818601526148d961024086018461474a565b908601519092506101e06149048682018373ffffffffffffffffffffffffffffffffffffffff169052565b860151905061020061492d8682018373ffffffffffffffffffffffffffffffffffffffff169052565b90950151151593019290925250919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261496f8184018a61474a565b90508281036080840152614983818961474a565b905060ff871660a084015282810360c08401526149a08187613bc0565b905067ffffffffffffffff851660e08401528281036101008401526149c58185613bc0565b9c9b505050505050505050505050565b828152604060208201526000612ef66040830184613bc0565b60008060408385031215614a0157600080fd5b8251614a0c816141d3565b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614a5357600080fd5b81356020614a63613f6683613f21565b82815260059290921b84018101918181019086841115614a8257600080fd5b8286015b84811015613fae5780358352918301918301614a86565b600082601f830112614aae57600080fd5b81356020614abe613f6683613f21565b82815260059290921b84018101918181019086841115614add57600080fd5b8286015b84811015613fae57803567ffffffffffffffff811115614b015760008081fd5b614b0f8986838b0101613fca565b845250918301918301614ae1565b600060208284031215614b2f57600080fd5b813567ffffffffffffffff80821115614b4757600080fd5b9083019060c08286031215614b5b57600080fd5b614b63613eaf565b8235815260208301356020820152604083013582811115614b8357600080fd5b614b8f87828601614a42565b604083015250606083013582811115614ba757600080fd5b614bb387828601614a42565b606083015250608083013582811115614bcb57600080fd5b614bd787828601614a9d565b60808301525060a083013582811115614bef57600080fd5b614bfb87828601614a9d565b60a08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156133fd576133fd6143e9565b818103818111156120c9576120c96143e9565b80820281158282048414176120c9576120c96143e9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614cbc57614cbc614c7e565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000614cf46080830184613bc0565b9695505050505050565b6bffffffffffffffffffffffff8281168282160390808211156133fd576133fd6143e9565b60006bffffffffffffffffffffffff80841680614d4257614d42614c7e565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114614d7657614d766143e9565b505092915050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614dc58285018b61474a565b91508382036080850152614dd9828a61474a565b915060ff881660a085015283820360c0850152614df68288613bc0565b90861660e085015283810361010085015290506149c58185613bc0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215614e5457600080fd5b6040516040810181811067ffffffffffffffff82111715614e7757614e77613e56565b6040528251614e858161415a565b81526020928301519281019290925250919050565b600060a08284031215614eac57600080fd5b60405160a0810181811067ffffffffffffffff82111715614ecf57614ecf613e56565b806040525082518152602083015160208201526040830151614ef08161415a565b60408201526060830151614f038161415a565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", } var AutomationRegistryABI = AutomationRegistryMetaData.ABI @@ -670,6 +671,123 @@ func (_AutomationRegistry *AutomationRegistryFilterer) ParseCancelledUpkeepRepor return event, nil } +type AutomationRegistryChainSpecificModuleUpdatedIterator struct { + Event *AutomationRegistryChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryChainSpecificModuleUpdatedIterator{contract: _AutomationRegistry.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryChainSpecificModuleUpdated) + if err := _AutomationRegistry.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryChainSpecificModuleUpdated, error) { + event := new(AutomationRegistryChainSpecificModuleUpdated) + if err := _AutomationRegistry.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type AutomationRegistryConfigSetIterator struct { Event *AutomationRegistryConfigSet @@ -4731,6 +4849,8 @@ func (_AutomationRegistry *AutomationRegistry) ParseLog(log types.Log) (generate return _AutomationRegistry.ParseAdminPrivilegeConfigSet(log) case _AutomationRegistry.abi.Events["CancelledUpkeepReport"].ID: return _AutomationRegistry.ParseCancelledUpkeepReport(log) + case _AutomationRegistry.abi.Events["ChainSpecificModuleUpdated"].ID: + return _AutomationRegistry.ParseChainSpecificModuleUpdated(log) case _AutomationRegistry.abi.Events["ConfigSet"].ID: return _AutomationRegistry.ParseConfigSet(log) case _AutomationRegistry.abi.Events["DedupKeyAdded"].ID: @@ -4807,6 +4927,10 @@ func (AutomationRegistryCancelledUpkeepReport) Topic() common.Hash { return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") } +func (AutomationRegistryChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + func (AutomationRegistryConfigSet) Topic() common.Hash { return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") } @@ -4978,6 +5102,12 @@ type AutomationRegistryInterface interface { ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryCancelledUpkeepReport, error) + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryChainSpecificModuleUpdated, error) + FilterConfigSet(opts *bind.FilterOpts) (*AutomationRegistryConfigSetIterator, error) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryConfigSet) (event.Subscription, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 0e7743a661a..a94cf5a462c 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -8,7 +8,7 @@ automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogi automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 automation_registrar_wrapper2_2: ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin 7c61908c1bb1bfd05a4da22bb73d62c0e2c05240f3f8fb5e06331603ff2246a9 automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 331bfa79685aee6ddf63b64c0747abee556c454cae3fb8175edff425b615d8aa -automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 02fa485ffa8dbe75cb8812302709ecf155e0466cd2bd532565fba84ae7e7e8b7 +automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 6fe2e41b1d3b74bee4013a48c10d84da25e559f28e22749aa13efabbf2cc2ee8 batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore/BatchBlockhashStore.bin 14356c48ef70f66ef74f22f644450dbf3b2a147c1b68deaa7e7d1eb8ffab15db batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.bin d0a54963260d8c1f1bbd984b758285e6027cfb5a7e42701bcb562ab123219332 batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin 73cb626b5cb2c3464655b61b8ac42fe7a1963fe25e6a5eea40b8e4d5bff3de36 @@ -24,7 +24,7 @@ flux_aggregator_wrapper: ../../contracts/solc/v0.6/FluxAggregator/FluxAggregator gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723 gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8 i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin 6501bb9bcf5048bab2737b00685c6984a24867e234ddf5b60a65904eee9a4ebc -i_keeper_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 999cc12517ddaa09daacbfc00ed01c5b69904943c87e076d8344e810cdc873d8 +i_keeper_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 0ce3cb008ba9681b8d08aa4e8b0b1f5b5b96852abf7c388e48166a9aeacc72f0 i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin 296beccb6af655d6fc3a6e676b244831cce2da6688d3afc4f21f8738ae59e03e keeper_consumer_performance_wrapper: ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.abi ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.bin eeda39f5d3e1c8ffa0fb6cd1803731b98a4bc262d41833458e3fe8b40933ae90 keeper_consumer_wrapper: ../../contracts/solc/v0.8.16/KeeperConsumer/KeeperConsumer.abi ../../contracts/solc/v0.8.16/KeeperConsumer/KeeperConsumer.bin 2c6163b145082fbab74b7343577a9cec8fda8b0da9daccf2a82581b1f5a84b83 @@ -34,16 +34,16 @@ keeper_registrar_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistrar2_0/Keep keeper_registry_logic1_3: ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3/KeeperRegistryLogic1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3/KeeperRegistryLogic1_3.bin 903f8b9c8e25425ca6d0b81b89e339d695a83630bfbfa24a6f3b38869676bc5a keeper_registry_logic2_0: ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0/KeeperRegistryLogic2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0/KeeperRegistryLogic2_0.bin d69d2bc8e4844293dbc2d45abcddc50b84c88554ecccfa4fa77c0ca45ec80871 keeper_registry_logic_a_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1/KeeperRegistryLogicA2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1/KeeperRegistryLogicA2_1.bin 77481ab75c9aa86a62a7b2a708599b5ea1a6346ed1c0def6d4826e7ae523f1ee -keeper_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 89a18aa7b49178520a7195cef1c2f1069a600c17a62c0efc92a4ee365b39eca1 +keeper_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 6bcf855e020256092a9d02be38d143006d3261c7531d2c98fb42f19296f08d6b keeper_registry_logic_b_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.bin 467d10741a04601b136553a2b1c6ab37f2a65d809366faf03180a22ff26be215 -keeper_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin d91a47becd506a548341a423f9c77ae151b922db7dfb733c6056e7b991989517 +keeper_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin 12f4fd408e4bed3ce5312c7f89a83e6a39ad95009c8f598d50f705fdc9463fdf keeper_registry_wrapper1_1: ../../contracts/solc/v0.7/KeeperRegistry1_1/KeeperRegistry1_1.abi ../../contracts/solc/v0.7/KeeperRegistry1_1/KeeperRegistry1_1.bin 6ce079f2738f015f7374673a2816e8e9787143d00b780ea7652c8aa9ad9e1e20 keeper_registry_wrapper1_1_mock: ../../contracts/solc/v0.7/KeeperRegistry1_1Mock/KeeperRegistry1_1Mock.abi ../../contracts/solc/v0.7/KeeperRegistry1_1Mock/KeeperRegistry1_1Mock.bin 98ddb3680e86359de3b5d17e648253ba29a84703f087a1b52237824003a8c6df keeper_registry_wrapper1_2: ../../contracts/solc/v0.8.6/KeeperRegistry1_2/KeeperRegistry1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_2/KeeperRegistry1_2.bin a40ff877dd7c280f984cbbb2b428e160662b0c295e881d5f778f941c0088ca22 keeper_registry_wrapper1_3: ../../contracts/solc/v0.8.6/KeeperRegistry1_3/KeeperRegistry1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_3/KeeperRegistry1_3.bin d4dc760b767ae274ee25c4a604ea371e1fa603a7b6421b69efb2088ad9e8abb3 keeper_registry_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistry2_0/KeeperRegistry2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistry2_0/KeeperRegistry2_0.bin c32dea7d5ef66b7c58ddc84ddf69aa44df1b3ae8601fbc271c95be4ff5853056 keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1/KeeperRegistry2_1.bin 604e4a0cd980c713929b523b999462a3aa0ed06f96ff563a4c8566cf59c8445b -keeper_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin 80bfb32b386fe45730ffe122266f0c80c8a963f0fd2d6d9afd37077b524c0bfa +keeper_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin 0defe584ccaab499a584eecd742442ec06f8aacd80fbacb85a25c42b227ef6d2 keepers_vrf_consumer: ../../contracts/solc/v0.8.6/KeepersVRFConsumer/KeepersVRFConsumer.abi ../../contracts/solc/v0.8.6/KeepersVRFConsumer/KeepersVRFConsumer.bin fa75572e689c9e84705c63e8dbe1b7b8aa1a8fe82d66356c4873d024bb9166e8 log_emitter: ../../contracts/solc/v0.8.19/LogEmitter/LogEmitter.abi ../../contracts/solc/v0.8.19/LogEmitter/LogEmitter.bin 4b129ab93432c95ff9143f0631323e189887668889e0b36ccccf18a571e41ccf log_triggered_streams_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.bin f8da43a927c1a66238a9f4fd5d5dd7e280e361daa0444da1f7f79498ace901e1 From 1e6b42ef184f6edc901d2858269966fb28743117 Mon Sep 17 00:00:00 2001 From: Ryan Tinianov Date: Wed, 14 Feb 2024 11:48:13 -0500 Subject: [PATCH 27/98] Add bytes type to abi_type (#12029) --- core/services/relay/evm/types/abi_types.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/services/relay/evm/types/abi_types.go b/core/services/relay/evm/types/abi_types.go index 34b12d885b4..4d1328bcc12 100644 --- a/core/services/relay/evm/types/abi_types.go +++ b/core/services/relay/evm/types/abi_types.go @@ -53,6 +53,10 @@ var typeMap = map[string]*ABIEncodingType{ native: reflect.TypeOf(common.Address{}), checked: reflect.TypeOf(common.Address{}), }, + "bytes": { + native: reflect.TypeOf([]byte{}), + checked: reflect.TypeOf([]byte{}), + }, } type ABIEncodingType struct { From f185128e739dcf6562e9ba96075062193e96cc7a Mon Sep 17 00:00:00 2001 From: Vyzaldy Sanchez Date: Wed, 14 Feb 2024 15:10:47 -0400 Subject: [PATCH 28/98] Adds timeout on fuzz script execution (#12024) --- tools/bin/go_core_fuzz | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/bin/go_core_fuzz b/tools/bin/go_core_fuzz index 2ee251b5ec5..c3119f4beb4 100755 --- a/tools/bin/go_core_fuzz +++ b/tools/bin/go_core_fuzz @@ -18,7 +18,8 @@ use_tee() { # the amount of --seconds here is subject to change based on how long the CI job takes in the future # as we add more fuzz tests, we should take into consideration increasing this timelapse, so we can have enough coverage. -cd ./fuzz && ./fuzz_all_native.py --ci --seconds 420 | use_tee $OUTPUT_FILE +# We are timing out after ~10mins in case the tests hang. (Current CI duration is ~8m, modify if needed) +cd ./fuzz && timeout 10m ./fuzz_all_native.py --ci --seconds 420 | use_tee $OUTPUT_FILE EXITCODE=${PIPESTATUS[0]} # Assert no known sensitive strings present in test logger output From da8b9a5504339746d955cd745440ed3a012431de Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 14 Feb 2024 14:28:41 -0600 Subject: [PATCH 29/98] bump go-plugin (#12033) --- charts/chainlink-cluster/go.mod | 2 +- core/scripts/go.mod | 6 +++--- core/scripts/go.sum | 8 ++++---- go.mod | 6 +++--- go.sum | 8 ++++---- integration-tests/go.mod | 6 +++--- integration-tests/go.sum | 8 ++++---- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/charts/chainlink-cluster/go.mod b/charts/chainlink-cluster/go.mod index ae67574aa06..14471683b2a 100644 --- a/charts/chainlink-cluster/go.mod +++ b/charts/chainlink-cluster/go.mod @@ -176,7 +176,7 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 511e02c5554..230cdb06a23 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -170,10 +170,10 @@ require ( github.com/hashicorp/go-envparse v0.1.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-plugin v1.5.2 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.4 // indirect @@ -330,7 +330,7 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e9c9c00d668..8f652ebf15b 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -730,8 +730,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce h1:7UnVY3T/ZnHUrfviiAgIUjg2PXxsQfs5bphsG8F7Keo= -github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= @@ -1183,8 +1183,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202402 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= -github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= -github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= +github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 h1:3y9WsXkZ5lxFrmfH7DQHs/q308lylKId5l/3VC0QAdM= diff --git a/go.mod b/go.mod index ddb45496be3..846e49e575d 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/consul/sdk v0.14.1 github.com/hashicorp/go-envparse v0.1.0 - github.com/hashicorp/go-plugin v1.5.2 + github.com/hashicorp/go-plugin v1.6.0 github.com/hdevalence/ed25519consensus v0.1.0 github.com/jackc/pgconn v1.14.1 github.com/jackc/pgtype v1.14.0 @@ -219,7 +219,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.4 // indirect @@ -334,7 +334,7 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f diff --git a/go.sum b/go.sum index d06090b588c..2ca0ca1087b 100644 --- a/go.sum +++ b/go.sum @@ -721,8 +721,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce h1:7UnVY3T/ZnHUrfviiAgIUjg2PXxsQfs5bphsG8F7Keo= -github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= @@ -1178,8 +1178,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202402 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= -github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= -github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= +github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 h1:3y9WsXkZ5lxFrmfH7DQHs/q308lylKId5l/3VC0QAdM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 226572aee98..0b88b69a05a 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -256,14 +256,14 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.5.2 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect github.com/hashicorp/serf v0.10.1 // indirect - github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.4 // indirect @@ -484,7 +484,7 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f diff --git a/integration-tests/go.sum b/integration-tests/go.sum index a012eca8fca..cc2d11d5885 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -960,8 +960,8 @@ github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e/go.mod h1:O23q github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce h1:7UnVY3T/ZnHUrfviiAgIUjg2PXxsQfs5bphsG8F7Keo= -github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs= @@ -1517,8 +1517,8 @@ github.com/smartcontractkit/chainlink-testing-framework v1.23.2 h1:haXPd9Pg++Zs5 github.com/smartcontractkit/chainlink-testing-framework v1.23.2/go.mod h1:StIOdxvwd8AMO6xuBtmD6FQfJXktEn/mJJEr7728BTc= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= -github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= -github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= +github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 h1:3y9WsXkZ5lxFrmfH7DQHs/q308lylKId5l/3VC0QAdM= From 4ad5eb95178c3e3ca195bb07af7b10b8664bef35 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 14 Feb 2024 17:14:32 -0600 Subject: [PATCH 30/98] plugins/cmd/chainlink-mercury: (re)move to chainlink-data-streams repo (#11994) --- .github/workflows/ci-core.yml | 4 +- GNUmakefile | 5 -- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.md | 2 + go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- plugins/chainlink.Dockerfile | 10 ++- plugins/cmd/chainlink-mercury/README.md | 19 ------ plugins/cmd/chainlink-mercury/main.go | 39 ----------- plugins/cmd/chainlink-mercury/plugin.go | 89 ------------------------- 13 files changed, 21 insertions(+), 165 deletions(-) delete mode 100644 plugins/cmd/chainlink-mercury/README.md delete mode 100644 plugins/cmd/chainlink-mercury/main.go delete mode 100644 plugins/cmd/chainlink-mercury/plugin.go diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 25fbc62e268..78d655d4cd8 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -76,13 +76,15 @@ jobs: pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds) go install ./cmd/chainlink-feeds popd + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-data-streams) + go install ./mercury/cmd/chainlink-mercury + popd pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-solana) go install ./pkg/solana/cmd/chainlink-solana popd pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-starknet/relayer) go install ./pkg/chainlink/cmd/chainlink-starknet popd - make install-mercury-loop - name: Increase Race Timeout if: github.event.schedule != '' run: | diff --git a/GNUmakefile b/GNUmakefile index 5d804a75a5c..eab8a73b954 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -62,11 +62,6 @@ chainlink-local-start: install-medianpoc: ## Build & install the chainlink-medianpoc binary. go install $(GOFLAGS) ./plugins/cmd/chainlink-medianpoc -.PHONY: install-mercury-loop -install-mercury-loop: ## Build & install the chainlink-medianpoc binary. - go install $(GOFLAGS) ./plugins/cmd/chainlink-mercury - - .PHONY: docker ## Build the chainlink docker image docker: docker buildx build \ diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 230cdb06a23..86aca87b5fa 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -247,7 +247,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 8f652ebf15b..6f960e78681 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1173,8 +1173,8 @@ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1/go.mod h1:GuPvyXryvbiUZIHmPeLBz4L+yJKeyGUjrDfd1KNne+o= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= diff --git a/go.md b/go.md index 2a893c2a55e..97330440a54 100644 --- a/go.md +++ b/go.md @@ -51,6 +51,8 @@ flowchart LR chainlink-common --> libocr chainlink-cosmos --> chainlink-common chainlink-cosmos --> libocr + chainlink-data-streams --> chain-selectors + click chain-selectors href "https://github.com/smartcontractkit/chain-selectors" chainlink-data-streams --> chainlink-common chainlink-data-streams --> libocr chainlink-feeds --> chainlink-common diff --git a/go.mod b/go.mod index 846e49e575d..0dfe6060adf 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 diff --git a/go.sum b/go.sum index 2ca0ca1087b..9098236cfa1 100644 --- a/go.sum +++ b/go.sum @@ -1168,8 +1168,8 @@ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1/go.mod h1:GuPvyXryvbiUZIHmPeLBz4L+yJKeyGUjrDfd1KNne+o= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0b88b69a05a..cf6b702b496 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -369,7 +369,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index cc2d11d5885..265a3061202 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1505,8 +1505,8 @@ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1 h1:xYqRgZO0nMSO8CBCMR0r3WA+LZ4kNL8a6bnbyk/oBtQ= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20231204152908-a6e3fe8ff2a1/go.mod h1:GuPvyXryvbiUZIHmPeLBz4L+yJKeyGUjrDfd1KNne+o= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= diff --git a/plugins/chainlink.Dockerfile b/plugins/chainlink.Dockerfile index cdaa2876d79..a518b37a9e1 100644 --- a/plugins/chainlink.Dockerfile +++ b/plugins/chainlink.Dockerfile @@ -20,11 +20,9 @@ RUN make install-chainlink # Install medianpoc binary RUN make install-medianpoc -# Install the mercury binary -RUN make install-mercury-loop - # Link LOOP Plugin source dirs with simple names RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds | xargs -I % ln -s % /chainlink-feeds +RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-data-streams | xargs -I % ln -s % /chainlink-data-streams RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-solana | xargs -I % ln -s % /chainlink-solana RUN mkdir /chainlink-starknet RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-starknet/relayer | xargs -I % ln -s % /chainlink-starknet/relayer @@ -37,6 +35,10 @@ WORKDIR /chainlink-feeds COPY --from=buildgo /chainlink-feeds . RUN go install ./cmd/chainlink-feeds +WORKDIR /chainlink-data-streams +COPY --from=buildgo /chainlink-data-streams . +RUN go install ./cmd/chainlink-data-streams/mercury/cmd/chainlink-mercury + WORKDIR /chainlink-solana COPY --from=buildgo /chainlink-solana . RUN go install ./pkg/solana/cmd/chainlink-solana @@ -63,6 +65,8 @@ COPY --from=buildgo /go/bin/chainlink-medianpoc /usr/local/bin/ COPY --from=buildplugins /go/bin/chainlink-feeds /usr/local/bin/ ENV CL_MEDIAN_CMD chainlink-feeds +COPY --from=buildplugins /go/bin/chainlink-mercury /usr/local/bin/ +ENV CL_MERCURY_CMD chainlink-mercury COPY --from=buildplugins /go/bin/chainlink-solana /usr/local/bin/ ENV CL_SOLANA_CMD chainlink-solana COPY --from=buildplugins /go/bin/chainlink-starknet /usr/local/bin/ diff --git a/plugins/cmd/chainlink-mercury/README.md b/plugins/cmd/chainlink-mercury/README.md deleted file mode 100644 index 89775cfe911..00000000000 --- a/plugins/cmd/chainlink-mercury/README.md +++ /dev/null @@ -1,19 +0,0 @@ -This directory houses the Mercury LOOPP - -# Running Integration Tests Locally - -Running the tests is as simple as -- building this binary -- setting the CL_MERCURY_CMD env var to the *fully resolved* binary path -- running the test(s) - - -The interesting tests are `TestIntegration_MercuryV*` in ` github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury` - -In detail: -``` -sh - -make install-mercury-loop # builds `mercury` binary in this dir -CL_MERCURY_CMD=/plugins/cmd/mercury/mercury go test -v -timeout 120s -run ^TestIntegration_MercuryV github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury 2>&1 | tee /tmp/mercury_loop.log -``` \ No newline at end of file diff --git a/plugins/cmd/chainlink-mercury/main.go b/plugins/cmd/chainlink-mercury/main.go deleted file mode 100644 index d80aa8ef41c..00000000000 --- a/plugins/cmd/chainlink-mercury/main.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "github.com/hashicorp/go-plugin" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" -) - -const ( - loggerName = "PluginMercury" -) - -func main() { - s := loop.MustNewStartedServer(loggerName) - defer s.Stop() - - p := NewPlugin(s.Logger) - defer s.Logger.ErrorIfFn(p.Close, "Failed to close") - - s.MustRegister(p) - - stop := make(chan struct{}) - defer close(stop) - - plugin.Serve(&plugin.ServeConfig{ - HandshakeConfig: loop.PluginMercuryHandshakeConfig(), - Plugins: map[string]plugin.Plugin{ - loop.PluginMercuryName: &loop.GRPCPluginMercury{ - PluginServer: p, - BrokerConfig: loop.BrokerConfig{ - StopCh: stop, - Logger: s.Logger, - GRPCOpts: s.GRPCOpts, - }, - }, - }, - GRPCServer: s.GRPCOpts.NewServer, - }) -} diff --git a/plugins/cmd/chainlink-mercury/plugin.go b/plugins/cmd/chainlink-mercury/plugin.go deleted file mode 100644 index 07531662ba9..00000000000 --- a/plugins/cmd/chainlink-mercury/plugin.go +++ /dev/null @@ -1,89 +0,0 @@ -package main - -import ( - "context" - - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink-common/pkg/types" - v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" - v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" - v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" - ds_v1 "github.com/smartcontractkit/chainlink-data-streams/mercury/v1" - ds_v2 "github.com/smartcontractkit/chainlink-data-streams/mercury/v2" - ds_v3 "github.com/smartcontractkit/chainlink-data-streams/mercury/v3" -) - -type Plugin struct { - loop.Plugin - stop services.StopChan -} - -func NewPlugin(lggr logger.Logger) *Plugin { - return &Plugin{Plugin: loop.Plugin{Logger: lggr}, stop: make(services.StopChan)} -} - -func (p *Plugin) NewMercuryV1Factory(ctx context.Context, provider types.MercuryProvider, dataSource v1.DataSource) (types.MercuryPluginFactory, error) { - var ctxVals loop.ContextValues - ctxVals.SetValues(ctx) - lggr := logger.With(p.Logger, ctxVals.Args()...) - - factory := ds_v1.NewFactory(dataSource, lggr, provider.OnchainConfigCodec(), provider.ReportCodecV1()) - - s := &mercuryPluginFactoryService{lggr: logger.Named(lggr, "MercuryV1PluginFactory"), MercuryPluginFactory: factory} - - p.SubService(s) - - return s, nil -} - -func (p *Plugin) NewMercuryV2Factory(ctx context.Context, provider types.MercuryProvider, dataSource v2.DataSource) (types.MercuryPluginFactory, error) { - var ctxVals loop.ContextValues - ctxVals.SetValues(ctx) - lggr := logger.With(p.Logger, ctxVals.Args()...) - - factory := ds_v2.NewFactory(dataSource, lggr, provider.OnchainConfigCodec(), provider.ReportCodecV2()) - - s := &mercuryPluginFactoryService{lggr: logger.Named(lggr, "MercuryV2PluginFactory"), MercuryPluginFactory: factory} - - p.SubService(s) - - return s, nil -} - -func (p *Plugin) NewMercuryV3Factory(ctx context.Context, provider types.MercuryProvider, dataSource v3.DataSource) (types.MercuryPluginFactory, error) { - var ctxVals loop.ContextValues - ctxVals.SetValues(ctx) - lggr := logger.With(p.Logger, ctxVals.Args()...) - - factory := ds_v3.NewFactory(dataSource, lggr, provider.OnchainConfigCodec(), provider.ReportCodecV3()) - - s := &mercuryPluginFactoryService{lggr: logger.Named(lggr, "MercuryV3PluginFactory"), MercuryPluginFactory: factory} - - p.SubService(s) - - return s, nil -} - -type mercuryPluginFactoryService struct { - services.StateMachine - lggr logger.Logger - ocr3types.MercuryPluginFactory -} - -func (r *mercuryPluginFactoryService) Name() string { return r.lggr.Name() } - -func (r *mercuryPluginFactoryService) Start(ctx context.Context) error { - return r.StartOnce("ReportingPluginFactory", func() error { return nil }) -} - -func (r *mercuryPluginFactoryService) Close() error { - return r.StopOnce("ReportingPluginFactory", func() error { return nil }) -} - -func (r *mercuryPluginFactoryService) HealthReport() map[string]error { - return map[string]error{r.Name(): r.Healthy()} -} From f8cdac1020d012478395571eb480bc9f9987d280 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Thu, 15 Feb 2024 12:30:59 +0100 Subject: [PATCH 31/98] Update style guide (#12041) --- contracts/STYLE_GUIDE.md | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/contracts/STYLE_GUIDE.md b/contracts/STYLE_GUIDE.md index 3868117d4b9..903832cf099 100644 --- a/contracts/STYLE_GUIDE.md +++ b/contracts/STYLE_GUIDE.md @@ -239,12 +239,10 @@ Here are some examples of what this should look like: ```solidity contract AccessControlledFoo is Foo { - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "AccessControlledFoo 1.0.0"; } contract OffchainAggregator is ITypeAndVersion { - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "OffchainAggregator 1.0.0"; function getData() public returns(uint256) { @@ -256,8 +254,6 @@ contract OffchainAggregator is ITypeAndVersion { contract SuperDuperAggregator is ITypeAndVersion { /// This is a new contract that has not been released yet, so we /// add a `-dev` suffix to the typeAndVersion. - - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "SuperDuperAggregator 1.1.0-dev"; function getData() public returns(uint256) { @@ -388,4 +384,27 @@ rule: `custom-errors` Interfaces should be named `IFoo` instead of `FooInterface`. This follows the patterns of popular [libraries like OpenZeppelin’s](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol#L9). -rule: `tbd` \ No newline at end of file +rule: `tbd` + +## Structs + +Structs should be constructed with named arguments. This prevents accidental assignment to the wrong field and makes the code more readable. + +```solidity +// Good +function setConfig(uint64 _foo, uint64 _bar, uint64 _baz) external { + config = Config({ + foo: _foo, + bar: _bar, + baz: _baz + }); +} + +// Bad +function setConfig(uint64 _foo, uint64 _bar, uint64 _baz) external { + config = Config(_foo, _bar, _baz); +} +``` + +rule: `tbd` + From 203ed2d64defe72404f1f33c55c248f92d61b84a Mon Sep 17 00:00:00 2001 From: Cedric Date: Thu, 15 Feb 2024 13:59:22 +0000 Subject: [PATCH 32/98] [chore] Replace clock with specialized lib (#12031) Co-authored-by: Jordan Krage --- .../gateway/connector/run_connector.go | 4 +-- core/scripts/go.mod | 1 + core/services/gateway/connectionmanager.go | 6 ++-- .../gateway/connectionmanager_test.go | 15 +++++----- core/services/gateway/connector/connector.go | 5 ++-- .../gateway/connector/connector_test.go | 6 ++-- core/services/gateway/gateway.go | 4 +-- .../gateway_integration_test.go | 4 +-- .../services/ocr2/plugins/functions/plugin.go | 6 ++-- core/services/s4/storage.go | 7 +++-- core/services/s4/storage_test.go | 5 ++-- core/utils/clock.go | 29 ------------------ core/utils/clock_test.go | 30 ------------------- go.mod | 1 + integration-tests/go.mod | 1 + integration-tests/go.sum | 2 ++ 16 files changed, 37 insertions(+), 89 deletions(-) delete mode 100644 core/utils/clock.go delete mode 100644 core/utils/clock_test.go diff --git a/core/scripts/gateway/connector/run_connector.go b/core/scripts/gateway/connector/run_connector.go index c6ad187461c..8d74bb88aec 100644 --- a/core/scripts/gateway/connector/run_connector.go +++ b/core/scripts/gateway/connector/run_connector.go @@ -9,13 +9,13 @@ import ( "os/signal" "github.com/ethereum/go-ethereum/crypto" + "github.com/jonboulle/clockwork" "github.com/pelletier/go-toml/v2" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/common" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) // Script to run Connector outside of the core node. @@ -69,7 +69,7 @@ func main() { sampleKey, _ := crypto.HexToECDSA("cd47d3fafdbd652dd2b66c6104fa79b372c13cb01f4a4fbfc36107cce913ac1d") lggr, _ := logger.NewLogger() client := &client{privateKey: sampleKey, lggr: lggr} - connector, _ := connector.NewGatewayConnector(&cfg, client, client, utils.NewRealClock(), lggr) + connector, _ := connector.NewGatewayConnector(&cfg, client, client, clockwork.NewRealClock(), lggr) client.connector = connector ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 86aca87b5fa..9269a161965 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -13,6 +13,7 @@ require ( github.com/google/uuid v1.4.0 github.com/jmoiron/sqlx v1.3.5 github.com/joho/godotenv v1.4.0 + github.com/jonboulle/clockwork v0.4.0 github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f github.com/montanaflynn/stats v0.7.1 github.com/olekukonko/tablewriter v0.0.5 diff --git a/core/services/gateway/connectionmanager.go b/core/services/gateway/connectionmanager.go index a3c39211c6e..7438b0042d2 100644 --- a/core/services/gateway/connectionmanager.go +++ b/core/services/gateway/connectionmanager.go @@ -11,6 +11,7 @@ import ( "time" "github.com/gorilla/websocket" + "github.com/jonboulle/clockwork" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "go.uber.org/multierr" @@ -24,7 +25,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/network" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) var promKeepalivesSent = promauto.NewGaugeVec(prometheus.GaugeOpts{ @@ -47,7 +47,7 @@ type connectionManager struct { config *config.ConnectionManagerConfig dons map[string]*donConnectionManager wsServer network.WebSocketServer - clock utils.Clock + clock clockwork.Clock connAttempts map[string]*connAttempt connAttemptCounter uint64 connAttemptsMu sync.Mutex @@ -89,7 +89,7 @@ type connAttempt struct { timestamp uint32 } -func NewConnectionManager(gwConfig *config.GatewayConfig, clock utils.Clock, lggr logger.Logger) (ConnectionManager, error) { +func NewConnectionManager(gwConfig *config.GatewayConfig, clock clockwork.Clock, lggr logger.Logger) (ConnectionManager, error) { codec := &api.JsonRPCCodec{} dons := make(map[string]*donConnectionManager) for _, donConfig := range gwConfig.Dons { diff --git a/core/services/gateway/connectionmanager_test.go b/core/services/gateway/connectionmanager_test.go index b176837d9ca..1750e975889 100644 --- a/core/services/gateway/connectionmanager_test.go +++ b/core/services/gateway/connectionmanager_test.go @@ -4,8 +4,8 @@ import ( "crypto/ecdsa" "fmt" "testing" - "time" + "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -15,7 +15,6 @@ import ( gc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/common" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/config" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/network" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) const defaultConfig = ` @@ -44,7 +43,7 @@ func TestConnectionManager_NewConnectionManager_ValidConfig(t *testing.T) { tomlConfig := parseTOMLConfig(t, defaultConfig) - _, err := gateway.NewConnectionManager(tomlConfig, utils.NewFixedClock(time.Now()), logger.TestLogger(t)) + _, err := gateway.NewConnectionManager(tomlConfig, clockwork.NewFakeClock(), logger.TestLogger(t)) require.NoError(t, err) } @@ -86,7 +85,7 @@ Address = "0x68902D681c28119f9b2531473a417088bf008E59" fullConfig := ` [nodeServerConfig] Path = "/node"` + config - _, err := gateway.NewConnectionManager(parseTOMLConfig(t, fullConfig), utils.NewFixedClock(time.Now()), logger.TestLogger(t)) + _, err := gateway.NewConnectionManager(parseTOMLConfig(t, fullConfig), clockwork.NewFakeClock(), logger.TestLogger(t)) require.Error(t, err) }) } @@ -128,7 +127,7 @@ func TestConnectionManager_StartHandshake(t *testing.T) { config, nodes := newTestConfig(t, 4) unrelatedNode := gc.NewTestNodes(t, 1)[0] - clock := utils.NewFixedClock(time.Now()) + clock := clockwork.NewFakeClock() mgr, err := gateway.NewConnectionManager(config, clock, logger.TestLogger(t)) require.NoError(t, err) @@ -181,7 +180,7 @@ func TestConnectionManager_FinalizeHandshake(t *testing.T) { t.Parallel() config, nodes := newTestConfig(t, 4) - clock := utils.NewFixedClock(time.Now()) + clock := clockwork.NewFakeClock() mgr, err := gateway.NewConnectionManager(config, clock, logger.TestLogger(t)) require.NoError(t, err) @@ -215,7 +214,7 @@ func TestConnectionManager_SendToNode_Failures(t *testing.T) { t.Parallel() config, nodes := newTestConfig(t, 2) - clock := utils.NewFixedClock(time.Now()) + clock := clockwork.NewFakeClock() mgr, err := gateway.NewConnectionManager(config, clock, logger.TestLogger(t)) require.NoError(t, err) @@ -233,7 +232,7 @@ func TestConnectionManager_CleanStartClose(t *testing.T) { config, _ := newTestConfig(t, 2) config.ConnectionManagerConfig.HeartbeatIntervalSec = 1 - clock := utils.NewFixedClock(time.Now()) + clock := clockwork.NewFakeClock() mgr, err := gateway.NewConnectionManager(config, clock, logger.TestLogger(t)) require.NoError(t, err) diff --git a/core/services/gateway/connector/connector.go b/core/services/gateway/connector/connector.go index a05652607ba..4e9de2df40e 100644 --- a/core/services/gateway/connector/connector.go +++ b/core/services/gateway/connector/connector.go @@ -9,6 +9,7 @@ import ( "time" "github.com/gorilla/websocket" + "github.com/jonboulle/clockwork" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/utils/hex" @@ -51,7 +52,7 @@ type gatewayConnector struct { config *ConnectorConfig codec api.Codec - clock utils.Clock + clock clockwork.Clock nodeAddress []byte signer Signer handler GatewayConnectorHandler @@ -79,7 +80,7 @@ type gatewayState struct { wsClient network.WebSocketClient } -func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler GatewayConnectorHandler, clock utils.Clock, lggr logger.Logger) (GatewayConnector, error) { +func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler GatewayConnectorHandler, clock clockwork.Clock, lggr logger.Logger) (GatewayConnector, error) { if config == nil || signer == nil || handler == nil || clock == nil || lggr == nil { return nil, errors.New("nil dependency") } diff --git a/core/services/gateway/connector/connector_test.go b/core/services/gateway/connector/connector_test.go index 1c2c6d26b10..3dd782c626a 100644 --- a/core/services/gateway/connector/connector_test.go +++ b/core/services/gateway/connector/connector_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/jonboulle/clockwork" "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -15,7 +16,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/network" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) const defaultConfig = ` @@ -43,7 +43,7 @@ func parseTOMLConfig(t *testing.T, tomlConfig string) *connector.ConnectorConfig func newTestConnector(t *testing.T, config *connector.ConnectorConfig, now time.Time) (connector.GatewayConnector, *mocks.Signer, *mocks.GatewayConnectorHandler) { signer := mocks.NewSigner(t) handler := mocks.NewGatewayConnectorHandler(t) - clock := utils.NewFixedClock(now) + clock := clockwork.NewFakeClock() connector, err := connector.NewGatewayConnector(config, signer, handler, clock, logger.TestLogger(t)) require.NoError(t, err) return connector, signer, handler @@ -104,7 +104,7 @@ URL = "ws://localhost:8081/node" signer := mocks.NewSigner(t) handler := mocks.NewGatewayConnectorHandler(t) - clock := utils.NewFixedClock(time.Now()) + clock := clockwork.NewFakeClock() for name, config := range invalidCases { config := config t.Run(name, func(t *testing.T) { diff --git a/core/services/gateway/gateway.go b/core/services/gateway/gateway.go index 79ddf0a5c69..93ecc474bec 100644 --- a/core/services/gateway/gateway.go +++ b/core/services/gateway/gateway.go @@ -9,6 +9,7 @@ import ( "go.uber.org/multierr" "github.com/ethereum/go-ethereum/common" + "github.com/jonboulle/clockwork" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -20,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers" gw_net "github.com/smartcontractkit/chainlink/v2/core/services/gateway/network" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) var promRequest = promauto.NewCounterVec(prometheus.CounterOpts{ @@ -55,7 +55,7 @@ type gateway struct { func NewGatewayFromConfig(config *config.GatewayConfig, handlerFactory HandlerFactory, lggr logger.Logger) (Gateway, error) { codec := &api.JsonRPCCodec{} httpServer := gw_net.NewHttpServer(&config.UserServerConfig, lggr) - connMgr, err := NewConnectionManager(config, utils.NewRealClock(), lggr) + connMgr, err := NewConnectionManager(config, clockwork.NewRealClock(), lggr) if err != nil { return nil, err } diff --git a/core/services/gateway/integration_tests/gateway_integration_test.go b/core/services/gateway/integration_tests/gateway_integration_test.go index a2064b7a591..7f4a2ab58fa 100644 --- a/core/services/gateway/integration_tests/gateway_integration_test.go +++ b/core/services/gateway/integration_tests/gateway_integration_test.go @@ -11,6 +11,7 @@ import ( "sync/atomic" "testing" + "github.com/jonboulle/clockwork" "github.com/onsi/gomega" "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/require" @@ -23,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/common" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/config" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) const gatewayConfigTemplate = ` @@ -152,7 +152,7 @@ func TestIntegration_Gateway_NoFullNodes_BasicConnectionAndMessage(t *testing.T) // Launch Connector client := &client{privateKey: nodeKeys.PrivateKey} - connector, err := connector.NewGatewayConnector(parseConnectorConfig(t, nodeConfigTemplate, nodeKeys.Address, nodeUrl), client, client, utils.NewRealClock(), lggr) + connector, err := connector.NewGatewayConnector(parseConnectorConfig(t, nodeConfigTemplate, nodeKeys.Address, nodeUrl), client, client, clockwork.NewRealClock(), lggr) require.NoError(t, err) client.connector = connector servicetest.Run(t, connector) diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go index 15e36f07b09..a49ce4be90a 100644 --- a/core/services/ocr2/plugins/functions/plugin.go +++ b/core/services/ocr2/plugins/functions/plugin.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/jmoiron/sqlx" + "github.com/jonboulle/clockwork" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/commontypes" @@ -32,7 +33,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pg" evmrelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/services/s4" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) type FunctionsServicesConfig struct { @@ -100,7 +100,7 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs var s4Storage s4.Storage if pluginConfig.S4Constraints != nil { - s4Storage = s4.NewStorage(conf.Logger, *pluginConfig.S4Constraints, s4ORM, utils.NewRealClock()) + s4Storage = s4.NewStorage(conf.Logger, *pluginConfig.S4Constraints, s4ORM, clockwork.NewRealClock()) } offchainTransmitter := functions.NewOffchainTransmitter(DefaultOffchainTransmitterChannelSize) @@ -202,7 +202,7 @@ func NewConnector(pluginConfig *config.PluginConfig, ethKeystore keystore.Eth, c if err != nil { return nil, err } - connector, err := connector.NewGatewayConnector(pluginConfig.GatewayConnectorConfig, handler, handler, utils.NewRealClock(), lggr) + connector, err := connector.NewGatewayConnector(pluginConfig.GatewayConnectorConfig, handler, handler, clockwork.NewRealClock(), lggr) if err != nil { return nil, err } diff --git a/core/services/s4/storage.go b/core/services/s4/storage.go index 7c9a92d1f68..02ba9c7bd50 100644 --- a/core/services/s4/storage.go +++ b/core/services/s4/storage.go @@ -3,10 +3,11 @@ package s4 import ( "context" + "github.com/jonboulle/clockwork" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pg" - "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/ethereum/go-ethereum/common" ) @@ -70,12 +71,12 @@ type storage struct { lggr logger.Logger contraints Constraints orm ORM - clock utils.Clock + clock clockwork.Clock } var _ Storage = (*storage)(nil) -func NewStorage(lggr logger.Logger, contraints Constraints, orm ORM, clock utils.Clock) Storage { +func NewStorage(lggr logger.Logger, contraints Constraints, orm ORM, clock clockwork.Clock) Storage { return &storage{ lggr: lggr.Named("S4Storage"), contraints: contraints, diff --git a/core/services/s4/storage_test.go b/core/services/s4/storage_test.go index 199e3e6924b..b643609f449 100644 --- a/core/services/s4/storage_test.go +++ b/core/services/s4/storage_test.go @@ -4,12 +4,13 @@ import ( "testing" "time" + "github.com/jonboulle/clockwork" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/s4" "github.com/smartcontractkit/chainlink/v2/core/services/s4/mocks" - "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -27,7 +28,7 @@ var ( func setupTestStorage(t *testing.T, now time.Time) (*mocks.ORM, s4.Storage) { logger := logger.TestLogger(t) orm := mocks.NewORM(t) - clock := utils.NewFixedClock(now) + clock := clockwork.NewFakeClock() storage := s4.NewStorage(logger, constraints, orm, clock) return orm, storage } diff --git a/core/utils/clock.go b/core/utils/clock.go deleted file mode 100644 index 0734c8a6a84..00000000000 --- a/core/utils/clock.go +++ /dev/null @@ -1,29 +0,0 @@ -package utils - -import "time" - -type Clock interface { - Now() time.Time -} - -type realClock struct{} - -func NewRealClock() Clock { - return &realClock{} -} - -func (realClock) Now() time.Time { - return time.Now() -} - -type fixedClock struct { - now time.Time -} - -func NewFixedClock(now time.Time) Clock { - return &fixedClock{now: now} -} - -func (fc fixedClock) Now() time.Time { - return fc.now -} diff --git a/core/utils/clock_test.go b/core/utils/clock_test.go deleted file mode 100644 index 9c4e7645dee..00000000000 --- a/core/utils/clock_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package utils_test - -import ( - "testing" - "time" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/utils" - - "github.com/stretchr/testify/assert" -) - -func TestNewRealClock(t *testing.T) { - t.Parallel() - - clock := utils.NewRealClock() - now := clock.Now() - time.Sleep(testutils.TestInterval) - interval := time.Since(now) - assert.GreaterOrEqual(t, interval, testutils.TestInterval) -} - -func TestNewFixedClock(t *testing.T) { - t.Parallel() - - now := time.Now() - clock := utils.NewFixedClock(now) - time.Sleep(testutils.TestInterval) - assert.Equal(t, now, clock.Now()) -} diff --git a/go.mod b/go.mod index 0dfe6060adf..eef8ad15001 100644 --- a/go.mod +++ b/go.mod @@ -40,6 +40,7 @@ require ( github.com/jackc/pgtype v1.14.0 github.com/jackc/pgx/v4 v4.18.1 github.com/jmoiron/sqlx v1.3.5 + github.com/jonboulle/clockwork v0.4.0 github.com/jpillora/backoff v1.0.0 github.com/kylelemons/godebug v1.1.0 github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a diff --git a/integration-tests/go.mod b/integration-tests/go.mod index cf6b702b496..0e522159352 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -283,6 +283,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 265a3061202..7952b3c09af 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1070,6 +1070,8 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= From ceb836dc0d402355c74c1d3c097705c7567d8562 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Thu, 15 Feb 2024 08:03:35 -0600 Subject: [PATCH 33/98] bump golang.org/x/... (#12042) --- core/scripts/go.mod | 16 ++++++++-------- core/scripts/go.sum | 36 ++++++++++++++++++------------------ go.mod | 17 +++++++++-------- go.sum | 36 ++++++++++++++++++------------------ integration-tests/go.mod | 18 +++++++++--------- integration-tests/go.sum | 36 ++++++++++++++++++------------------ 6 files changed, 80 insertions(+), 79 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 9269a161965..b09e87a7624 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -298,17 +298,17 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/arch v0.6.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.16.0 // indirect + golang.org/x/tools v0.18.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 6f960e78681..68043ed7056 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1417,8 +1417,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc= -golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1446,8 +1446,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1458,8 +1458,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1487,8 +1487,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1546,8 +1546,8 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1558,8 +1558,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1662,8 +1662,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1671,8 +1671,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1759,8 +1759,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index eef8ad15001..a7d52bfbcbc 100644 --- a/go.mod +++ b/go.mod @@ -92,13 +92,13 @@ require ( go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.46.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.18.0 - golang.org/x/exp v0.0.0-20231127185646-65229373498e + golang.org/x/crypto v0.19.0 + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a golang.org/x/sync v0.6.0 - golang.org/x/term v0.16.0 + golang.org/x/term v0.17.0 golang.org/x/text v0.14.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.16.0 + golang.org/x/tools v0.18.0 gonum.org/v1/gonum v0.14.0 google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.32.0 @@ -312,10 +312,11 @@ require ( go.opentelemetry.io/otel/trace v1.21.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect - golang.org/x/arch v0.6.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/api v0.149.0 // indirect google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect diff --git a/go.sum b/go.sum index 9098236cfa1..2df7a8d7c46 100644 --- a/go.sum +++ b/go.sum @@ -1412,8 +1412,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc= -golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1441,8 +1441,8 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1453,8 +1453,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1482,8 +1482,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1540,8 +1540,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1552,8 +1552,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1655,8 +1655,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1665,8 +1665,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1754,8 +1754,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0e522159352..366594098ec 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -433,16 +433,16 @@ require ( go.uber.org/goleak v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.6.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.16.0 // indirect + golang.org/x/tools v0.18.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 7952b3c09af..df94da9318d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1791,8 +1791,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc= -golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1825,8 +1825,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1837,8 +1837,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1866,8 +1866,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1933,8 +1933,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1946,8 +1946,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2066,8 +2066,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2077,8 +2077,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2172,8 +2172,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 009c99876c4cc2f0d3df42477a3c9f1742284d89 Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 15 Feb 2024 08:18:06 -0700 Subject: [PATCH 34/98] add toml configs to paths that can cause e2e tests to run in ci (#12001) --- .github/workflows/integration-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 6bec0a0422b..1edb3f003db 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -68,6 +68,7 @@ jobs: - '.github/workflows/integration-tests.yml' - '**/*Dockerfile' - 'core/**/config/**/*.toml' + - 'integration-tests/**/*.toml' - name: Collect Metrics if: always() id: collect-gha-metrics From b3f8719838f0d3fdb6b68d5882ec7aaffa56b243 Mon Sep 17 00:00:00 2001 From: jinhoonbang Date: Thu, 15 Feb 2024 10:25:44 -0800 Subject: [PATCH 35/98] VRF zero confirmation delay (#11947) * allow 0 confirmation delays in VRF; use pending block for simulation in VRF * fix script build error * fix failing automation test * fix more tests * integraiton test wip * add integration tests for pending simulation block and zero confirmation delay (only v2 plus) and add simulation block option to superscript * Update core/chains/evm/client/simulated_backend_client.go Co-authored-by: Chris Cushman <104409744+vreff@users.noreply.github.com> * use pendingContractCall instead of low-level call contract * fix eth_call_test.go * handle nil gas and gasPrice in backend test client for estimateGas --------- Co-authored-by: Ilja Pavlovs Co-authored-by: Chris Cushman <104409744+vreff@users.noreply.github.com> --- common/client/mock_rpc_test.go | 30 ++++++ common/client/multi_node.go | 11 +++ common/client/types.go | 4 + core/chains/evm/client/chain_client.go | 4 + core/chains/evm/client/client.go | 5 + core/chains/evm/client/erroring_node.go | 4 + core/chains/evm/client/mocks/client.go | 30 ++++++ core/chains/evm/client/node.go | 28 ++++++ core/chains/evm/client/null_client.go | 5 + core/chains/evm/client/pool.go | 4 + core/chains/evm/client/rpc_client.go | 28 ++++++ .../evm/client/simulated_backend_client.go | 95 ++++++++++++++++++- core/chains/evm/mocks/node.go | 30 ++++++ core/scripts/common/vrf/jobs/jobs.go | 12 ++- core/scripts/common/vrf/setup-envs/main.go | 10 ++ .../vrfv2/testnet/v2scripts/super_scripts.go | 11 +++ .../testnet/v2plusscripts/super_scripts.go | 29 +++++- .../vrfv2plus/testnet/v2plusscripts/util.go | 10 +- core/services/pipeline/common.go | 11 +++ core/services/pipeline/task.estimategas.go | 30 ++++-- core/services/pipeline/task.eth_call.go | 15 ++- core/services/pipeline/task.eth_call_test.go | 54 +++++++++++ core/services/pipeline/task.vrfv2plus.go | 1 + core/services/vrf/vrfcommon/validate.go | 3 - core/testdata/testspecs/v2_specs.go | 2 + .../actions/vrf/common/models.go | 1 + .../actions/vrf/vrfv2/vrfv2_steps.go | 2 + .../actions/vrf/vrfv2plus/vrfv2plus_steps.go | 2 + integration-tests/client/chainlink_models.go | 41 ++++++-- integration-tests/smoke/vrfv2plus_test.go | 89 +++++++++++++++++ integration-tests/testconfig/vrfv2/config.go | 5 + 31 files changed, 575 insertions(+), 31 deletions(-) diff --git a/common/client/mock_rpc_test.go b/common/client/mock_rpc_test.go index d87a02d47c1..72c6eb19029 100644 --- a/common/client/mock_rpc_test.go +++ b/common/client/mock_rpc_test.go @@ -426,6 +426,36 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS return r0, r1 } +// PendingCallContract provides a mock function with given fields: ctx, msg +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) PendingCallContract(ctx context.Context, msg interface{}) ([]byte, error) { + ret := _m.Called(ctx, msg) + + if len(ret) == 0 { + panic("no return value specified for PendingCallContract") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, interface{}) ([]byte, error)); ok { + return rf(ctx, msg) + } + if rf, ok := ret.Get(0).(func(context.Context, interface{}) []byte); ok { + r0 = rf(ctx, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, interface{}) error); ok { + r1 = rf(ctx, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // PendingSequenceAt provides a mock function with given fields: ctx, addr func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) PendingSequenceAt(ctx context.Context, addr ADDR) (SEQ, error) { ret := _m.Called(ctx, addr) diff --git a/common/client/multi_node.go b/common/client/multi_node.go index ed1a2700c71..ae9b3afd0d4 100644 --- a/common/client/multi_node.go +++ b/common/client/multi_node.go @@ -465,6 +465,17 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().CallContract(ctx, attempt, blockNumber) } +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) PendingCallContract( + ctx context.Context, + attempt interface{}, +) (rpcErr []byte, extractErr error) { + n, err := c.selectNode() + if err != nil { + return rpcErr, err + } + return n.RPC().PendingCallContract(ctx, attempt) +} + // ChainID makes a direct RPC call. In most cases it should be better to use the configured chain id instead by // calling ConfiguredChainID. func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) ChainID(ctx context.Context) (id CHAIN_ID, err error) { diff --git a/common/client/types.go b/common/client/types.go index 32d4da98b50..fe9e4d7d482 100644 --- a/common/client/types.go +++ b/common/client/types.go @@ -124,6 +124,10 @@ type clientAPI[ msg interface{}, blockNumber *big.Int, ) (rpcErr []byte, extractErr error) + PendingCallContract( + ctx context.Context, + msg interface{}, + ) (rpcErr []byte, extractErr error) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error CodeAt(ctx context.Context, account ADDR, blockNumber *big.Int) ([]byte, error) } diff --git a/core/chains/evm/client/chain_client.go b/core/chains/evm/client/chain_client.go index 2a5a37da47c..b16054b69a8 100644 --- a/core/chains/evm/client/chain_client.go +++ b/core/chains/evm/client/chain_client.go @@ -130,6 +130,10 @@ func (c *chainClient) CallContract(ctx context.Context, msg ethereum.CallMsg, bl return c.multiNode.CallContract(ctx, msg, blockNumber) } +func (c *chainClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + return c.multiNode.PendingCallContract(ctx, msg) +} + // TODO-1663: change this to actual ChainID() call once client.go is deprecated. func (c *chainClient) ChainID() (*big.Int, error) { //return c.multiNode.ChainID(ctx), nil diff --git a/core/chains/evm/client/client.go b/core/chains/evm/client/client.go index 61635c59c6b..e2ae8c26403 100644 --- a/core/chains/evm/client/client.go +++ b/core/chains/evm/client/client.go @@ -91,6 +91,7 @@ type Client interface { HeaderByHash(ctx context.Context, h common.Hash) (*types.Header, error) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) + PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) IsL2() bool } @@ -260,6 +261,10 @@ func (client *client) CallContract(ctx context.Context, msg ethereum.CallMsg, bl return client.pool.CallContract(ctx, msg, blockNumber) } +func (client *client) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + return client.pool.PendingCallContract(ctx, msg) +} + func (client *client) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { return client.pool.CodeAt(ctx, account, blockNumber) } diff --git a/core/chains/evm/client/erroring_node.go b/core/chains/evm/client/erroring_node.go index c33891728a7..059f76d608a 100644 --- a/core/chains/evm/client/erroring_node.go +++ b/core/chains/evm/client/erroring_node.go @@ -103,6 +103,10 @@ func (e *erroringNode) CallContract(ctx context.Context, msg ethereum.CallMsg, b return nil, errors.New(e.errMsg) } +func (e *erroringNode) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + return nil, errors.New(e.errMsg) +} + func (e *erroringNode) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { return nil, errors.New(e.errMsg) } diff --git a/core/chains/evm/client/mocks/client.go b/core/chains/evm/client/mocks/client.go index 0b45894cf28..bbaaafd7615 100644 --- a/core/chains/evm/client/mocks/client.go +++ b/core/chains/evm/client/mocks/client.go @@ -585,6 +585,36 @@ func (_m *Client) NodeStates() map[string]string { return r0 } +// PendingCallContract provides a mock function with given fields: ctx, msg +func (_m *Client) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + ret := _m.Called(ctx, msg) + + if len(ret) == 0 { + panic("no return value specified for PendingCallContract") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg) ([]byte, error)); ok { + return rf(ctx, msg) + } + if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg) []byte); ok { + r0 = rf(ctx, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg) error); ok { + r1 = rf(ctx, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // PendingCodeAt provides a mock function with given fields: ctx, account func (_m *Client) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { ret := _m.Called(ctx, account) diff --git a/core/chains/evm/client/node.go b/core/chains/evm/client/node.go index a27321535ed..aa472d605a6 100644 --- a/core/chains/evm/client/node.go +++ b/core/chains/evm/client/node.go @@ -117,6 +117,7 @@ type Node interface { EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) SuggestGasPrice(ctx context.Context) (*big.Int, error) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) + PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) HeaderByNumber(context.Context, *big.Int) (*types.Header, error) HeaderByHash(context.Context, common.Hash) (*types.Header, error) @@ -830,6 +831,33 @@ func (n *node) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumb } +func (n *node) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) (val []byte, err error) { + ctx, cancel, ws, http, err := n.makeLiveQueryCtxAndSafeGetClients(ctx) + if err != nil { + return nil, err + } + defer cancel() + lggr := n.newRqLggr().With("callMsg", msg) + + lggr.Debug("RPC call: evmclient.Client#PendingCallContract") + start := time.Now() + if http != nil { + val, err = http.geth.PendingCallContract(ctx, msg) + err = n.wrapHTTP(err) + } else { + val, err = ws.geth.PendingCallContract(ctx, msg) + err = n.wrapWS(err) + } + duration := time.Since(start) + + n.logResult(lggr, err, duration, n.getRPCDomain(), "PendingCallContract", + "val", val, + ) + + return + +} + func (n *node) BlockByNumber(ctx context.Context, number *big.Int) (b *types.Block, err error) { ctx, cancel, ws, http, err := n.makeLiveQueryCtxAndSafeGetClients(ctx) if err != nil { diff --git a/core/chains/evm/client/null_client.go b/core/chains/evm/client/null_client.go index e3bb1defd0d..3cbae9e9dde 100644 --- a/core/chains/evm/client/null_client.go +++ b/core/chains/evm/client/null_client.go @@ -196,6 +196,11 @@ func (nc *NullClient) CallContract(ctx context.Context, msg ethereum.CallMsg, bl return nil, nil } +func (nc *NullClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + nc.lggr.Debug("PendingCallContract") + return nil, nil +} + func (nc *NullClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { nc.lggr.Debug("CodeAt") return nil, nil diff --git a/core/chains/evm/client/pool.go b/core/chains/evm/client/pool.go index b2d5a4847a5..3c33b3dbd0a 100644 --- a/core/chains/evm/client/pool.go +++ b/core/chains/evm/client/pool.go @@ -477,6 +477,10 @@ func (p *Pool) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumb return p.selectNode().CallContract(ctx, msg, blockNumber) } +func (p *Pool) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + return p.selectNode().PendingCallContract(ctx, msg) +} + func (p *Pool) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { return p.selectNode().CodeAt(ctx, account, blockNumber) } diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index ce3a67162ed..54656cf1d3e 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -792,6 +792,34 @@ func (r *rpcClient) CallContract(ctx context.Context, msg interface{}, blockNumb } +func (r *rpcClient) PendingCallContract(ctx context.Context, msg interface{}) (val []byte, err error) { + ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) + if err != nil { + return nil, err + } + defer cancel() + lggr := r.newRqLggr().With("callMsg", msg) + message := msg.(ethereum.CallMsg) + + lggr.Debug("RPC call: evmclient.Client#PendingCallContract") + start := time.Now() + if http != nil { + val, err = http.geth.PendingCallContract(ctx, message) + err = r.wrapHTTP(err) + } else { + val, err = ws.geth.PendingCallContract(ctx, message) + err = r.wrapWS(err) + } + duration := time.Since(start) + + r.logResult(lggr, err, duration, r.getRPCDomain(), "PendingCallContract", + "val", val, + ) + + return + +} + func (r *rpcClient) LatestBlockHeight(ctx context.Context) (*big.Int, error) { var height big.Int h, err := r.BlockNumber(ctx) diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go index bd2e959d9bc..c49637e7890 100644 --- a/core/chains/evm/client/simulated_backend_client.go +++ b/core/chains/evm/client/simulated_backend_client.go @@ -102,6 +102,8 @@ func (c *SimulatedBackendClient) CallContext(ctx context.Context, result interfa return c.ethCall(ctx, result, args...) case "eth_getHeaderByNumber": return c.ethGetHeaderByNumber(ctx, result, args...) + case "eth_estimateGas": + return c.ethEstimateGas(ctx, result, args...) default: return fmt.Errorf("second arg to SimulatedBackendClient.Call is an RPC API method which has not yet been implemented: %s. Add processing for it here", method) } @@ -401,6 +403,25 @@ func (c *SimulatedBackendClient) CallContract(ctx context.Context, msg ethereum. return res, nil } +func (c *SimulatedBackendClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + // Expected error is + // type JsonError struct { + // Code int `json:"code"` + // Message string `json:"message"` + // Data interface{} `json:"data,omitempty"` + //} + res, err := c.b.PendingCallContract(ctx, msg) + if err != nil { + dataErr := revertError{} + if errors.Is(err, &dataErr) { + return nil, &JsonError{Data: dataErr.ErrorData(), Message: dataErr.Error(), Code: 3} + } + // Generic revert, no data + return nil, &JsonError{Data: []byte{}, Message: err.Error(), Code: 3} + } + return res, nil +} + // CodeAt gets the code associated with an account as of a specified block. func (c *SimulatedBackendClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { return c.b.CodeAt(ctx, account, blockNumber) @@ -443,6 +464,8 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B b[i].Error = c.ethCall(ctx, b[i].Result, b[i].Args...) case "eth_getHeaderByNumber": b[i].Error = c.ethGetHeaderByNumber(ctx, b[i].Result, b[i].Args...) + case "eth_estimateGas": + b[i].Error = c.ethEstimateGas(ctx, b[i].Result, b[i].Args...) default: return fmt.Errorf("SimulatedBackendClient got unsupported method %s", elem.Method) } @@ -562,6 +585,37 @@ func (c *SimulatedBackendClient) ethGetBlockByNumber(ctx context.Context, result return nil } +func (c *SimulatedBackendClient) ethEstimateGas(ctx context.Context, result interface{}, args ...interface{}) error { + if len(args) != 2 { + return fmt.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_estimateGas", len(args)) + } + + params, ok := args[0].(map[string]interface{}) + if !ok { + return fmt.Errorf("SimulatedBackendClient expected first arg to be map[string]interface{} for eth_call, got: %T", args[0]) + } + + _, err := c.blockNumber(args[1]) + if err != nil { + return fmt.Errorf("SimulatedBackendClient expected second arg to be the string 'latest' or a *big.Int for eth_call, got: %T", args[1]) + } + + resp, err := c.b.EstimateGas(ctx, toCallMsg(params)) + if err != nil { + return err + } + + switch typedResult := result.(type) { + case *uint64: + *typedResult = resp + case *hexutil.Uint64: + *typedResult = hexutil.Uint64(resp) + default: + return fmt.Errorf("SimulatedBackendClient unexpected type %T", result) + } + + return nil +} func (c *SimulatedBackendClient) ethCall(ctx context.Context, result interface{}, args ...interface{}) error { if len(args) != 2 { @@ -625,7 +679,6 @@ func (c *SimulatedBackendClient) ethGetHeaderByNumber(ctx context.Context, resul func toCallMsg(params map[string]interface{}) ethereum.CallMsg { var callMsg ethereum.CallMsg - toAddr, err := interfaceToAddress(params["to"]) if err != nil { panic(fmt.Errorf("unexpected 'to' parameter: %s", err)) @@ -645,6 +698,10 @@ func toCallMsg(params map[string]interface{}) ethereum.CallMsg { callMsg.From = common.HexToAddress("0x") } + if params["data"] != nil && params["input"] != nil { + panic("cannot have both 'data' and 'input' parameters") + } + switch data := params["data"].(type) { case nil: // This parameter is not required so nil is acceptable @@ -656,16 +713,41 @@ func toCallMsg(params map[string]interface{}) ethereum.CallMsg { panic("unexpected type of 'data' parameter; try hexutil.Bytes, []byte, or nil") } + switch input := params["input"].(type) { + case nil: + // This parameter is not required so nil is acceptable + case hexutil.Bytes: + callMsg.Data = input + case []byte: + callMsg.Data = input + default: + panic("unexpected type of 'input' parameter; try hexutil.Bytes, []byte, or nil") + } + if value, ok := params["value"].(*big.Int); ok { callMsg.Value = value } - if gas, ok := params["gas"].(uint64); ok { + switch gas := params["gas"].(type) { + case nil: + // This parameter is not required so nil is acceptable + case uint64: callMsg.Gas = gas + case hexutil.Uint64: + callMsg.Gas = uint64(gas) + default: + panic("unexpected type of 'gas' parameter; try hexutil.Uint64, or uint64") } - if gasPrice, ok := params["gasPrice"].(*big.Int); ok { + switch gasPrice := params["gasPrice"].(type) { + case nil: + // This parameter is not required so nil is acceptable + case *big.Int: callMsg.GasPrice = gasPrice + case *hexutil.Big: + callMsg.GasPrice = gasPrice.ToInt() + default: + panic("unexpected type of 'gasPrice' parameter; try *big.Int, or *hexutil.Big") } return callMsg @@ -675,6 +757,11 @@ func interfaceToAddress(value interface{}) (common.Address, error) { switch v := value.(type) { case common.Address: return v, nil + case *common.Address: + if v == nil { + return common.Address{}, nil + } + return *v, nil case string: if ok := common.IsHexAddress(v); !ok { return common.Address{}, fmt.Errorf("string not formatted as a hex encoded evm address") @@ -688,6 +775,6 @@ func interfaceToAddress(value interface{}) (common.Address, error) { return common.BigToAddress(v), nil default: - return common.Address{}, fmt.Errorf("unrecognized value type for converting value to common.Address; use hex encoded string, *big.Int, or common.Address") + return common.Address{}, fmt.Errorf("unrecognized value type: %T for converting value to common.Address; use hex encoded string, *big.Int, or common.Address", v) } } diff --git a/core/chains/evm/mocks/node.go b/core/chains/evm/mocks/node.go index 8f27218aec7..25944cfcf42 100644 --- a/core/chains/evm/mocks/node.go +++ b/core/chains/evm/mocks/node.go @@ -496,6 +496,36 @@ func (_m *Node) Order() int32 { return r0 } +// PendingCallContract provides a mock function with given fields: ctx, msg +func (_m *Node) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + ret := _m.Called(ctx, msg) + + if len(ret) == 0 { + panic("no return value specified for PendingCallContract") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg) ([]byte, error)); ok { + return rf(ctx, msg) + } + if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg) []byte); ok { + r0 = rf(ctx, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg) error); ok { + r1 = rf(ctx, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // PendingCodeAt provides a mock function with given fields: ctx, account func (_m *Node) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { ret := _m.Called(ctx, account) diff --git a/core/scripts/common/vrf/jobs/jobs.go b/core/scripts/common/vrf/jobs/jobs.go index 7e304f431be..66bdf712e5c 100644 --- a/core/scripts/common/vrf/jobs/jobs.go +++ b/core/scripts/common/vrf/jobs/jobs.go @@ -27,7 +27,8 @@ vrf [type=vrfv2 estimate_gas [type=estimategaslimit to="%s" multiplier="%f" - data="$(vrf.output)"] + data="$(vrf.output)" + block="%s"] simulate [type=ethcall from="%s" to="%s" @@ -35,7 +36,8 @@ simulate [type=ethcall gasPrice="$(jobSpec.maxGasPrice)" extractRevertReason=true contract="%s" - data="$(vrf.output)"] + data="$(vrf.output)" + block="%s"] decode_log->vrf->estimate_gas->simulate """` @@ -66,7 +68,8 @@ generate_proof [type=vrfv2plus estimate_gas [type=estimategaslimit to="%s" multiplier="%f" - data="$(generate_proof.output)"] + data="$(generate_proof.output)" + block="%s"] simulate_fulfillment [type=ethcall from="%s" to="%s" @@ -74,7 +77,8 @@ simulate_fulfillment [type=ethcall gasPrice="$(jobSpec.maxGasPrice)" extractRevertReason=true contract="%s" - data="$(generate_proof.output)"] + data="$(generate_proof.output)" + block="%s"] decode_log->generate_proof->estimate_gas->simulate_fulfillment """ ` diff --git a/core/scripts/common/vrf/setup-envs/main.go b/core/scripts/common/vrf/setup-envs/main.go index cd23328b3d5..6d0f73c0f18 100644 --- a/core/scripts/common/vrf/setup-envs/main.go +++ b/core/scripts/common/vrf/setup-envs/main.go @@ -83,6 +83,7 @@ func main() { subscriptionBalanceNativeWeiString := flag.String("subscription-balance-native", constants.SubscriptionBalanceNativeWei, "amount to fund subscription with native token (Wei)") minConfs := flag.Int("min-confs", constants.MinConfs, "minimum confirmations") + nativeOnly := flag.Bool("native-only", false, "if true, link and link feed are not set up. Only used in v2 plus") linkAddress := flag.String("link-address", "", "address of link token") linkEthAddress := flag.String("link-eth-feed", "", "address of link eth feed") bhsContractAddressString := flag.String("bhs-address", "", "address of BHS contract") @@ -93,6 +94,7 @@ func main() { "from this address you can perform `coordinator.oracleWithdraw` to withdraw earned funds from rand request fulfilments") deployVRFOwner := flag.Bool("deploy-vrfv2-owner", true, "whether to deploy VRF owner contracts") useTestCoordinator := flag.Bool("use-test-coordinator", true, "whether to use test coordinator contract or use the normal one") + simulationBlock := flag.String("simulation-block", "pending", "simulation block can be 'pending' or 'latest'") e := helpers.SetupEnv(false) flag.Parse() @@ -103,6 +105,10 @@ func main() { } fmt.Println("Using VRF Version:", *vrfVersion) + if *simulationBlock != "pending" && *simulationBlock != "latest" { + helpers.PanicErr(fmt.Errorf("simulation block must be 'pending' or 'latest'")) + } + fundingAmount := decimal.RequireFromString(*nodeSendingKeyFundingAmount).BigInt() subscriptionBalanceJuels := decimal.RequireFromString(*subscriptionBalanceJuelsString).BigInt() subscriptionBalanceNativeWei := decimal.RequireFromString(*subscriptionBalanceNativeWeiString).BigInt() @@ -228,6 +234,7 @@ func main() { *deployVRFOwner, coordinatorJobSpecConfig, *useTestCoordinator, + *simulationBlock, ) case "v2plus": coordinatorConfigV2Plus := v2plusscripts.CoordinatorConfigV2Plus{ @@ -257,9 +264,12 @@ func main() { vrfKeyRegistrationConfig, contractAddresses, coordinatorConfigV2Plus, + *batchFulfillmentEnabled, + *nativeOnly, nodesMap, uint64(*maxGasPriceGwei), coordinatorJobSpecConfig, + *simulationBlock, ) } diff --git a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go index 1397274656c..5cfc3f81ce1 100644 --- a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go +++ b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go @@ -60,6 +60,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { deployVRFOwner := deployCmd.Bool("deploy-vrf-owner", true, "whether to deploy VRF owner contracts") useTestCoordinator := deployCmd.Bool("use-test-coordinator", true, "whether to use test coordinator") + simulationBlock := deployCmd.String("simulation-block", "pending", "simulation block can be 'pending' or 'latest'") // optional flags fallbackWeiPerUnitLinkString := deployCmd.String("fallback-wei-per-unit-link", constants.FallbackWeiPerUnitLink.String(), "fallback wei/link ratio") @@ -83,6 +84,10 @@ func DeployUniverseViaCLI(e helpers.Environment) { reqsForTier4 := deployCmd.Int64("reqs-for-tier-4", constants.ReqsForTier4, "requests for tier 4") reqsForTier5 := deployCmd.Int64("reqs-for-tier-5", constants.ReqsForTier5, "requests for tier 5") + if *simulationBlock != "pending" && *simulationBlock != "latest" { + helpers.PanicErr(fmt.Errorf("simulation block must be 'pending' or 'latest'")) + } + helpers.ParseArgs( deployCmd, os.Args[2:], ) @@ -162,6 +167,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { *deployVRFOwner, coordinatorJobSpecConfig, *useTestCoordinator, + *simulationBlock, ) vrfPrimaryNode := nodesMap[model.VRFPrimaryNodeName] @@ -181,6 +187,7 @@ func VRFV2DeployUniverse( deployVRFOwner bool, coordinatorJobSpecConfig model.CoordinatorJobSpecConfig, useTestCoordinator bool, + simulationBlock string, ) model.JobSpecs { var compressedPkHex string var keyHash common.Hash @@ -347,6 +354,7 @@ func VRFV2DeployUniverse( coordinatorJobSpecConfig.RequestTimeout, //requestTimeout contractAddresses.CoordinatorAddress, coordinatorJobSpecConfig.EstimateGasMultiplier, //estimateGasMultiplier + simulationBlock, func() string { if keys := nodesMap[model.VRFPrimaryNodeName].SendingKeys; len(keys) > 0 { return keys[0].Address @@ -355,6 +363,7 @@ func VRFV2DeployUniverse( }(), contractAddresses.CoordinatorAddress, contractAddresses.CoordinatorAddress, + simulationBlock, ) if deployVRFOwner { formattedVrfPrimaryJobSpec = strings.Replace(formattedVrfPrimaryJobSpec, @@ -378,6 +387,7 @@ func VRFV2DeployUniverse( coordinatorJobSpecConfig.RequestTimeout, //requestTimeout contractAddresses.CoordinatorAddress, coordinatorJobSpecConfig.EstimateGasMultiplier, //estimateGasMultiplier + simulationBlock, func() string { if keys := nodesMap[model.VRFPrimaryNodeName].SendingKeys; len(keys) > 0 { return keys[0].Address @@ -386,6 +396,7 @@ func VRFV2DeployUniverse( }(), contractAddresses.CoordinatorAddress, contractAddresses.CoordinatorAddress, + simulationBlock, ) if deployVRFOwner { formattedVrfBackupJobSpec = strings.Replace(formattedVrfBackupJobSpec, diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go index 9c1ddd840d4..fcea01b71c8 100644 --- a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go +++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go @@ -472,6 +472,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { deployCmd := flag.NewFlagSet("deploy-universe", flag.ExitOnError) // required flags + nativeOnly := deployCmd.Bool("native-only", false, "if true, link and link feed are not set up") linkAddress := deployCmd.String("link-address", "", "address of link token") linkEthAddress := deployCmd.String("link-eth-feed", "", "address of link eth feed") bhsContractAddressString := deployCmd.String("bhs-address", "", "address of BHS contract") @@ -486,6 +487,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { estimateGasMultiplier := deployCmd.Float64("estimate-gas-multiplier", 1.1, "") pollPeriod := deployCmd.String("poll-period", "300ms", "") requestTimeout := deployCmd.String("request-timeout", "30m0s", "") + simulationBlock := deployCmd.String("simulation-block", "pending", "simulation block can be 'pending' or 'latest'") // optional flags fallbackWeiPerUnitLinkString := deployCmd.String("fallback-wei-per-unit-link", "6e16", "fallback wei/link ratio") @@ -507,6 +509,19 @@ func DeployUniverseViaCLI(e helpers.Environment) { deployCmd, os.Args[2:], ) + if *nativeOnly { + if *linkAddress != "" || *linkEthAddress != "" { + panic("native-only flag is set, but link address or link eth address is provided") + } + if *subscriptionBalanceJuelsString != "0" { + panic("native-only flag is set, but link subscription balance is provided") + } + } + + if *simulationBlock != "pending" && *simulationBlock != "latest" { + helpers.PanicErr(fmt.Errorf("simulation block must be 'pending' or 'latest'")) + } + fallbackWeiPerUnitLink := decimal.RequireFromString(*fallbackWeiPerUnitLinkString).BigInt() subscriptionBalanceJuels := decimal.RequireFromString(*subscriptionBalanceJuelsString).BigInt() subscriptionBalanceNativeWei := decimal.RequireFromString(*subscriptionBalanceNativeWeiString).BigInt() @@ -569,9 +584,12 @@ func DeployUniverseViaCLI(e helpers.Environment) { vrfKeyRegistrationConfig, contractAddresses, coordinatorConfig, + *batchFulfillmentEnabled, + *nativeOnly, nodesMap, uint64(*gasLaneMaxGas), coordinatorJobSpecConfig, + *simulationBlock, ) vrfPrimaryNode := nodesMap[model.VRFPrimaryNodeName] @@ -587,9 +605,12 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, vrfKeyRegistrationConfig model.VRFKeyRegistrationConfig, contractAddresses model.ContractAddresses, coordinatorConfig CoordinatorConfigV2Plus, + batchFulfillmentEnabled bool, + nativeOnly bool, nodesMap map[string]model.Node, gasLaneMaxGas uint64, coordinatorJobSpecConfig model.CoordinatorJobSpecConfig, + simulationBlock string, ) model.JobSpecs { var compressedPkHex string var keyHash common.Hash @@ -618,12 +639,12 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, helpers.PanicErr(err) } - if len(contractAddresses.LinkAddress) == 0 { + if !nativeOnly && len(contractAddresses.LinkAddress) == 0 { fmt.Println("\nDeploying LINK Token...") contractAddresses.LinkAddress = helpers.DeployLinkToken(e).String() } - if len(contractAddresses.LinkEthAddress) == 0 { + if !nativeOnly && len(contractAddresses.LinkEthAddress) == 0 { fmt.Println("\nDeploying LINK/ETH Feed...") contractAddresses.LinkEthAddress = helpers.DeployLinkEthFeed(e, contractAddresses.LinkAddress, coordinatorConfig.FallbackWeiPerUnitLink).String() } @@ -727,6 +748,7 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, coordinatorJobSpecConfig.RequestTimeout, //requestTimeout contractAddresses.CoordinatorAddress, coordinatorJobSpecConfig.EstimateGasMultiplier, //estimateGasMultiplier + simulationBlock, func() string { if keys := nodesMap[model.VRFPrimaryNodeName].SendingKeys; len(keys) > 0 { return keys[0].Address @@ -735,6 +757,7 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, }(), contractAddresses.CoordinatorAddress, contractAddresses.CoordinatorAddress, + simulationBlock, ) formattedVrfV2PlusBackupJobSpec := fmt.Sprintf( @@ -751,6 +774,7 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, coordinatorJobSpecConfig.RequestTimeout, //requestTimeout contractAddresses.CoordinatorAddress, coordinatorJobSpecConfig.EstimateGasMultiplier, //estimateGasMultiplier + simulationBlock, func() string { if keys := nodesMap[model.VRFPrimaryNodeName].SendingKeys; len(keys) > 0 { return keys[0].Address @@ -759,6 +783,7 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, }(), contractAddresses.CoordinatorAddress, contractAddresses.CoordinatorAddress, + simulationBlock, ) formattedBHSJobSpec := fmt.Sprintf( diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go index 213a2f0dcff..716e0058ff4 100644 --- a/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go +++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go @@ -53,10 +53,12 @@ func DeployCoordinator( coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(coordinatorAddress, e.Ec) helpers.PanicErr(err) - linkTx, err := coordinator.SetLINKAndLINKNativeFeed(e.Owner, - common.HexToAddress(linkAddress), common.HexToAddress(linkEthAddress)) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), e.Ec, linkTx, e.ChainID) + if linkAddress != "" && linkEthAddress != "" { + linkTx, err := coordinator.SetLINKAndLINKNativeFeed(e.Owner, + common.HexToAddress(linkAddress), common.HexToAddress(linkEthAddress)) + helpers.PanicErr(err) + helpers.ConfirmTXMined(context.Background(), e.Ec, linkTx, e.ChainID) + } return coordinatorAddress } diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index da0e0d3c00b..6e7ad1e7e4e 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -681,3 +681,14 @@ func getJsonNumberValue(value json.Number) (interface{}, error) { return result, nil } + +func selectBlock(block string) (string, error) { + if block == "" { + return "latest", nil + } + block = strings.ToLower(block) + if block == "pending" || block == "latest" { + return block, nil + } + return "", pkgerrors.Errorf("unsupported block param: %s", block) +} diff --git a/core/services/pipeline/task.estimategas.go b/core/services/pipeline/task.estimategas.go index 43c148b287f..8fccc5e8eac 100644 --- a/core/services/pipeline/task.estimategas.go +++ b/core/services/pipeline/task.estimategas.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" "github.com/shopspring/decimal" "go.uber.org/multierr" @@ -28,6 +29,7 @@ type EstimateGasLimitTask struct { Multiplier string `json:"multiplier"` Data string `json:"data"` EVMChainID string `json:"evmChainID" mapstructure:"evmChainID"` + Block string `json:"block"` specGasLimit *uint32 legacyChains legacyevm.LegacyChainContainer @@ -61,6 +63,7 @@ func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars data BytesParam multiplier DecimalParam chainID StringParam + block StringParam ) err := multierr.Combine( errors.Wrap(ResolveParam(&fromAddr, From(VarExpr(t.From, vars), utils.ZeroAddress)), "from"), @@ -69,6 +72,7 @@ func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars // Default to 1, i.e. exactly what estimateGas suggests errors.Wrap(ResolveParam(&multiplier, From(VarExpr(t.Multiplier, vars), NonemptyString(t.Multiplier), decimal.New(1, 0))), "multiplier"), errors.Wrap(ResolveParam(&chainID, From(VarExpr(t.getEvmChainID(), vars), NonemptyString(t.getEvmChainID()), "")), "evmChainID"), + errors.Wrap(ResolveParam(&block, From(VarExpr(t.Block, vars), t.Block)), "block"), ) if err != nil { return Result{Error: err}, runInfo @@ -82,18 +86,32 @@ func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars maximumGasLimit := SelectGasLimit(chain.Config().EVM().GasEstimator(), t.jobType, t.specGasLimit) to := common.Address(toAddr) - gasLimit, err := chain.Client().EstimateGas(ctx, ethereum.CallMsg{ - From: common.Address(fromAddr), - To: &to, - Data: data, - }) + var gasLimit hexutil.Uint64 + args := map[string]interface{}{ + "from": common.Address(fromAddr), + "to": &to, + "input": hexutil.Bytes([]byte(data)), + } + + selectedBlock, err := selectBlock(string(block)) + if err != nil { + return Result{Error: err}, runInfo + } + err = chain.Client().CallContext(ctx, + &gasLimit, + "eth_estimateGas", + args, + selectedBlock, + ) + if err != nil { // Fallback to the maximum conceivable gas limit // if we're unable to call estimate gas for whatever reason. lggr.Warnw("EstimateGas: unable to estimate, fallback to configured limit", "err", err, "fallback", maximumGasLimit) return Result{Value: maximumGasLimit}, runInfo } - gasLimitDecimal, err := decimal.NewFromString(strconv.FormatUint(gasLimit, 10)) + + gasLimitDecimal, err := decimal.NewFromString(strconv.FormatUint(uint64(gasLimit), 10)) if err != nil { return Result{Error: err}, retryableRunInfo() } diff --git a/core/services/pipeline/task.eth_call.go b/core/services/pipeline/task.eth_call.go index 56b2df08c4e..f011cd7a9b6 100644 --- a/core/services/pipeline/task.eth_call.go +++ b/core/services/pipeline/task.eth_call.go @@ -3,6 +3,7 @@ package pipeline import ( "context" "fmt" + "strings" "time" "github.com/ethereum/go-ethereum" @@ -33,6 +34,7 @@ type ETHCallTask struct { GasUnlimited string `json:"gasUnlimited"` ExtractRevertReason bool `json:"extractRevertReason"` EVMChainID string `json:"evmChainID" mapstructure:"evmChainID"` + Block string `json:"block"` specGasLimit *uint32 legacyChains legacyevm.LegacyChainContainer @@ -78,6 +80,7 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in gasFeeCap MaybeBigIntParam gasUnlimited BoolParam chainID StringParam + block StringParam ) err = multierr.Combine( errors.Wrap(ResolveParam(&contractAddr, From(VarExpr(t.Contract, vars), NonemptyString(t.Contract))), "contract"), @@ -89,6 +92,7 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in errors.Wrap(ResolveParam(&gasFeeCap, From(VarExpr(t.GasFeeCap, vars), t.GasFeeCap)), "gasFeeCap"), errors.Wrap(ResolveParam(&chainID, From(VarExpr(t.getEvmChainID(), vars), NonemptyString(t.getEvmChainID()), "")), "evmChainID"), errors.Wrap(ResolveParam(&gasUnlimited, From(VarExpr(t.GasUnlimited, vars), NonemptyString(t.GasUnlimited), false)), "gasUnlimited"), + errors.Wrap(ResolveParam(&block, From(VarExpr(t.Block, vars), t.Block)), "block"), ) if err != nil { return Result{Error: err}, runInfo @@ -131,7 +135,15 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in With("gasFeeCap", call.GasFeeCap) start := time.Now() - resp, err := chain.Client().CallContract(ctx, call, nil) + + var resp []byte + blockStr := block.String() + if blockStr == "" || strings.ToLower(blockStr) == "latest" { + resp, err = chain.Client().CallContract(ctx, call, nil) + } else if strings.ToLower(blockStr) == "pending" { + resp, err = chain.Client().PendingCallContract(ctx, call) + } + elapsed := time.Since(start) if err != nil { if t.ExtractRevertReason { @@ -149,6 +161,5 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in } promETHCallTime.WithLabelValues(t.DotID()).Set(float64(elapsed)) - return Result{Value: resp}, runInfo } diff --git a/core/services/pipeline/task.eth_call_test.go b/core/services/pipeline/task.eth_call_test.go index cb58a03a9df..28af94ba25c 100644 --- a/core/services/pipeline/task.eth_call_test.go +++ b/core/services/pipeline/task.eth_call_test.go @@ -43,6 +43,7 @@ func TestETHCallTask(t *testing.T) { data string evmChainID string gas string + block string specGasLimit *uint32 vars pipeline.Vars inputs []pipeline.Result @@ -58,6 +59,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -78,6 +80,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "$(gasLimit)", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -99,6 +102,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", &specGasLimit, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -119,6 +123,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -140,6 +145,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -155,6 +161,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -170,6 +177,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "zork": []byte("foo bar"), @@ -185,6 +193,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte(nil), @@ -200,6 +209,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "0", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -215,6 +225,7 @@ func TestETHCallTask(t *testing.T) { "$(foo)", "$(evmChainID)", "", + "", nil, pipeline.NewVarsFrom(map[string]interface{}{ "foo": []byte("foo bar"), @@ -229,6 +240,48 @@ func TestETHCallTask(t *testing.T) { }, nil, nil, chains.ErrNoSuchChainID.Error(), }, + { + "simulate using latest block", + "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF", + "", + "$(foo)", + "0", + "", + "latest", + nil, + pipeline.NewVarsFrom(map[string]interface{}{ + "foo": []byte("foo bar"), + }), + nil, + func(ethClient *evmclimocks.Client, config *pipelinemocks.Config) { + contractAddr := common.HexToAddress("0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF") + ethClient. + On("CallContract", mock.Anything, ethereum.CallMsg{To: &contractAddr, Gas: uint64(drJobTypeGasLimit), Data: []byte("foo bar")}, (*big.Int)(nil)). + Return([]byte("baz quux"), nil) + }, + []byte("baz quux"), nil, "", + }, + { + "simulate using pending block", + "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF", + "", + "$(foo)", + "0", + "", + "pending", + nil, + pipeline.NewVarsFrom(map[string]interface{}{ + "foo": []byte("foo bar"), + }), + nil, + func(ethClient *evmclimocks.Client, config *pipelinemocks.Config) { + contractAddr := common.HexToAddress("0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF") + ethClient. + On("PendingCallContract", mock.Anything, ethereum.CallMsg{To: &contractAddr, Gas: uint64(drJobTypeGasLimit), Data: []byte("foo bar")}). + Return([]byte("baz quux"), nil) + }, + []byte("baz quux"), nil, "", + }, } for _, test := range tests { @@ -241,6 +294,7 @@ func TestETHCallTask(t *testing.T) { Data: test.data, EVMChainID: test.evmChainID, Gas: test.gas, + Block: test.block, } ethClient := evmclimocks.NewClient(t) diff --git a/core/services/pipeline/task.vrfv2plus.go b/core/services/pipeline/task.vrfv2plus.go index ff9f96e7eca..6bc299eeb6f 100644 --- a/core/services/pipeline/task.vrfv2plus.go +++ b/core/services/pipeline/task.vrfv2plus.go @@ -138,6 +138,7 @@ func (t *VRFTaskV2Plus) Run(_ context.Context, lggr logger.Logger, vars Vars, in return Result{Error: err}, retryableRunInfo() } // onlyPremium is false because this task assumes that chainlink node fulfills the VRF request + // gas cost should be billed to the requesting subscription b, err := vrfCoordinatorV2PlusABI.Pack("fulfillRandomWords", onChainProof, rc, false /* onlyPremium */) if err != nil { return Result{Error: err}, runInfo diff --git a/core/services/vrf/vrfcommon/validate.go b/core/services/vrf/vrfcommon/validate.go index 07e8676ddb7..09f2e669483 100644 --- a/core/services/vrf/vrfcommon/validate.go +++ b/core/services/vrf/vrfcommon/validate.go @@ -47,9 +47,6 @@ func ValidatedVRFSpec(tomlString string) (job.Job, error) { if bytes.Equal(spec.PublicKey[:], empty[:]) { return jb, errors.Wrap(ErrKeyNotSet, "publicKey") } - if spec.MinIncomingConfirmations == 0 { - return jb, errors.Wrap(ErrKeyNotSet, "minIncomingConfirmations") - } if spec.CoordinatorAddress.String() == "" { return jb, errors.Wrap(ErrKeyNotSet, "coordinatorAddress") } diff --git a/core/testdata/testspecs/v2_specs.go b/core/testdata/testspecs/v2_specs.go index a78f5d8530c..5ca79f1abb4 100644 --- a/core/testdata/testspecs/v2_specs.go +++ b/core/testdata/testspecs/v2_specs.go @@ -376,6 +376,7 @@ estimate_gas [type=estimategaslimit to="%s" multiplier="1.1" data="$(generate_proof.output)" + block="latest" ] simulate_fulfillment [type=ethcall to="%s" @@ -384,6 +385,7 @@ simulate_fulfillment [type=ethcall extractRevertReason=true contract="%s" data="$(generate_proof.output)" + block="latest" ] decode_log->generate_proof->estimate_gas->simulate_fulfillment `, coordinatorAddress, coordinatorAddress, coordinatorAddress) diff --git a/integration-tests/actions/vrf/common/models.go b/integration-tests/actions/vrf/common/models.go index bb486bd598b..ab6ca034800 100644 --- a/integration-tests/actions/vrf/common/models.go +++ b/integration-tests/actions/vrf/common/models.go @@ -66,4 +66,5 @@ type VRFJobSpecConfig struct { PollPeriod time.Duration RequestTimeout time.Duration VRFOwnerConfig *VRFOwnerConfig + SimulationBlock *string } diff --git a/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go b/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go index 3813a970a2b..39d7133dd46 100644 --- a/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go +++ b/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go @@ -170,6 +170,7 @@ func CreateVRFV2Job( Address: vrfJobSpecConfig.CoordinatorAddress, EstimateGasMultiplier: vrfJobSpecConfig.EstimateGasMultiplier, FromAddress: vrfJobSpecConfig.FromAddresses[0], + SimulationBlock: vrfJobSpecConfig.SimulationBlock, } ost, err := os.String() if err != nil { @@ -394,6 +395,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Conf BatchFulfillmentGasMultiplier: *vrfv2Config.VRFJobBatchFulfillmentGasMultiplier, PollPeriod: vrfv2Config.VRFJobPollPeriod.Duration, RequestTimeout: vrfv2Config.VRFJobRequestTimeout.Duration, + SimulationBlock: vrfv2Config.VRFJobSimulationBlock, VRFOwnerConfig: vrfOwnerConfig, } diff --git a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go index 23a778f229e..a3c6352bf37 100644 --- a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go @@ -90,6 +90,7 @@ func CreateVRFV2PlusJob( Address: vrfJobSpecConfig.CoordinatorAddress, EstimateGasMultiplier: vrfJobSpecConfig.EstimateGasMultiplier, FromAddress: vrfJobSpecConfig.FromAddresses[0], + SimulationBlock: vrfJobSpecConfig.SimulationBlock, } ost, err := os.String() if err != nil { @@ -332,6 +333,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Conf BatchFulfillmentGasMultiplier: *vrfv2Config.VRFJobBatchFulfillmentGasMultiplier, PollPeriod: vrfv2Config.VRFJobPollPeriod.Duration, RequestTimeout: vrfv2Config.VRFJobRequestTimeout.Duration, + SimulationBlock: vrfv2Config.VRFJobSimulationBlock, VRFOwnerConfig: nil, } diff --git a/integration-tests/client/chainlink_models.go b/integration-tests/client/chainlink_models.go index 370497423f3..0e144d3ab39 100644 --- a/integration-tests/client/chainlink_models.go +++ b/integration-tests/client/chainlink_models.go @@ -627,11 +627,23 @@ func (d *PipelineSpec) String() (string, error) { return MarshallTemplate(d, "API call pipeline template", sourceString) } +func getOptionalSimBlock(simBlock *string) (string, error) { + optionalSimBlock := "" + if simBlock != nil { + if *simBlock != "latest" && *simBlock != "pending" { + return "", fmt.Errorf("invalid simulation block value: %s", *simBlock) + } + optionalSimBlock = fmt.Sprintf("block=\"%s\"", *simBlock) + } + return optionalSimBlock, nil +} + // VRFV2TxPipelineSpec VRFv2 request with tx callback type VRFV2PlusTxPipelineSpec struct { Address string EstimateGasMultiplier float64 FromAddress string + SimulationBlock *string // can be nil, "latest" or "pending". } // Type returns the type of the pipeline @@ -641,7 +653,11 @@ func (d *VRFV2PlusTxPipelineSpec) Type() string { // String representation of the pipeline func (d *VRFV2PlusTxPipelineSpec) String() (string, error) { - sourceString := ` + optionalSimBlock, err := getOptionalSimBlock(d.SimulationBlock) + if err != nil { + return "", err + } + sourceTemplate := ` decode_log [type=ethabidecodelog abi="RandomWordsRequested(bytes32 indexed keyHash,uint256 requestId,uint256 preSeed,uint256 indexed subId,uint16 minimumRequestConfirmations,uint32 callbackGasLimit,uint32 numWords,bytes extraArgs,address indexed sender)" data="$(jobRun.logData)" @@ -654,7 +670,8 @@ generate_proof [type=vrfv2plus estimate_gas [type=estimategaslimit to="{{ .Address }}" multiplier="{{ .EstimateGasMultiplier }}" - data="$(generate_proof.output)"] + data="$(generate_proof.output)" + %s] simulate_fulfillment [type=ethcall from="{{ .FromAddress }}" to="{{ .Address }}" @@ -662,8 +679,11 @@ simulate_fulfillment [type=ethcall gasPrice="$(jobSpec.maxGasPrice)" extractRevertReason=true contract="{{ .Address }}" - data="$(generate_proof.output)"] + data="$(generate_proof.output)" + %s] decode_log->generate_proof->estimate_gas->simulate_fulfillment` + + sourceString := fmt.Sprintf(sourceTemplate, optionalSimBlock, optionalSimBlock) return MarshallTemplate(d, "VRFV2 Plus pipeline template", sourceString) } @@ -672,6 +692,7 @@ type VRFV2TxPipelineSpec struct { Address string EstimateGasMultiplier float64 FromAddress string + SimulationBlock *string // can be nil, "latest" or "pending". } // Type returns the type of the pipeline @@ -681,7 +702,11 @@ func (d *VRFV2TxPipelineSpec) Type() string { // String representation of the pipeline func (d *VRFV2TxPipelineSpec) String() (string, error) { - sourceString := ` + optionalSimBlock, err := getOptionalSimBlock(d.SimulationBlock) + if err != nil { + return "", err + } + sourceTemplate := ` decode_log [type=ethabidecodelog abi="RandomWordsRequested(bytes32 indexed keyHash,uint256 requestId,uint256 preSeed,uint64 indexed subId,uint16 minimumRequestConfirmations,uint32 callbackGasLimit,uint32 numWords,address indexed sender)" data="$(jobRun.logData)" @@ -694,7 +719,8 @@ vrf [type=vrfv2 estimate_gas [type=estimategaslimit to="{{ .Address }}" multiplier="{{ .EstimateGasMultiplier }}" - data="$(vrf.output)"] + data="$(vrf.output)" + %s] simulate [type=ethcall from="{{ .FromAddress }}" to="{{ .Address }}" @@ -702,8 +728,11 @@ simulate [type=ethcall gasPrice="$(jobSpec.maxGasPrice)" extractRevertReason=true contract="{{ .Address }}" - data="$(vrf.output)"] + data="$(vrf.output)" + %s] decode_log->vrf->estimate_gas->simulate` + + sourceString := fmt.Sprintf(sourceTemplate, optionalSimBlock, optionalSimBlock) return MarshallTemplate(d, "VRFV2 pipeline template", sourceString) } diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 29cc5534791..e13f12b2a43 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -1140,3 +1140,92 @@ func TestVRFV2PlusWithBHS(t *testing.T) { require.Equal(t, 0, randomWordsRequestedEvent.Raw.BlockHash.Cmp(randRequestBlockHash)) }) } + +func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) { + t.Parallel() + l := logging.GetTestLogger(t) + + config, err := tc.GetConfig("Smoke", tc.VRFv2Plus) + if err != nil { + t.Fatal(err) + } + + // override config with minConf = 0 and use pending block for simulation + config.VRFv2Plus.General.MinimumConfirmations = ptr.Ptr[uint16](0) + config.VRFv2Plus.General.VRFJobSimulationBlock = ptr.Ptr[string]("pending") + + network, err := actions.EthereumNetworkConfigFromConfig(l, &config) + require.NoError(t, err, "Error building ethereum network config") + + env, err := test_env.NewCLTestEnvBuilder(). + WithTestInstance(t). + WithTestConfig(&config). + WithPrivateEthereumNetwork(network). + WithCLNodes(1). + WithFunding(big.NewFloat(*config.Common.ChainlinkNodeFunding)). + WithStandardCleanup(). + Build() + require.NoError(t, err, "error creating test env") + + env.ParallelTransactions(true) + + mockETHLinkFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, big.NewInt(*config.VRFv2Plus.General.LinkNativeFeedResponse)) + require.NoError(t, err, "error deploying mock ETH/LINK feed") + + linkToken, err := actions.DeployLINKToken(env.ContractDeployer) + require.NoError(t, err, "error deploying LINK contract") + + numberOfTxKeysToCreate := 2 + vrfv2PlusContracts, subIDs, vrfv2PlusData, nodesMap, err := vrfv2plus.SetupVRFV2_5Environment( + env, + []vrfcommon.VRFNodeType{vrfcommon.VRF}, + &config, + linkToken, + mockETHLinkFeed, + numberOfTxKeysToCreate, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up VRF v2_5 env") + + subID := subIDs[0] + + subscription, err := vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + + vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.CoordinatorV2Plus) + + var isNativeBilling = false + + jobRunsBeforeTest, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + require.NoError(t, err, "error reading job runs") + + l.Info().Uint16("minimumConfirmationDelay", *config.VRFv2Plus.General.MinimumConfirmations).Msg("Minimum Confirmation Delay") + + // test and assert + randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + vrfv2PlusContracts.VRFV2PlusConsumer[0], + vrfv2PlusContracts.CoordinatorV2Plus, + vrfv2PlusData, + subID, + isNativeBilling, + *config.VRFv2Plus.General.MinimumConfirmations, + *config.VRFv2Plus.General.CallbackGasLimit, + *config.VRFv2Plus.General.NumberOfWords, + *config.VRFv2Plus.General.RandomnessRequestCountPerRequest, + *config.VRFv2Plus.General.RandomnessRequestCountPerRequestDeviation, + config.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + jobRuns, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + require.NoError(t, err, "error reading job runs") + require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) + + status, err := vrfv2PlusContracts.VRFV2PlusConsumer[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, status.Fulfilled) + l.Debug().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") +} diff --git a/integration-tests/testconfig/vrfv2/config.go b/integration-tests/testconfig/vrfv2/config.go index dca1319e8d8..c9037b59085 100644 --- a/integration-tests/testconfig/vrfv2/config.go +++ b/integration-tests/testconfig/vrfv2/config.go @@ -240,6 +240,7 @@ type General struct { VRFJobBatchFulfillmentGasMultiplier *float64 `toml:"vrf_job_batch_fulfillment_gas_multiplier"` VRFJobPollPeriod *blockchain.StrDuration `toml:"vrf_job_poll_period"` VRFJobRequestTimeout *blockchain.StrDuration `toml:"vrf_job_request_timeout"` + VRFJobSimulationBlock *string `toml:"vrf_job_simulation_block"` //BHS Job Config BHSJobWaitBlocks *int `toml:"bhs_job_wait_blocks"` @@ -378,5 +379,9 @@ func (c *General) Validate() error { return errors.New("bhs_job_wait_blocks must be set to a non-negative value") } + if c.VRFJobSimulationBlock != nil && (*c.VRFJobSimulationBlock != "latest" && *c.VRFJobSimulationBlock != "pending") { + return errors.New("simulation_block must be nil or \"latest\" or \"pending\"") + } + return nil } From 4d32897ac481c12df236a8a54bec0792ffe617e6 Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Thu, 15 Feb 2024 22:11:33 +0200 Subject: [PATCH 36/98] Node API capabilities registry (#12046) * Pin to latest version of chainlink-common * Pin to latest version * Pin to latest version --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/chainlink/application.go | 1 + core/services/job/spawner_test.go | 3 ++- core/services/ocr2/delegate.go | 10 +++++++--- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- 9 files changed, 19 insertions(+), 13 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index b09e87a7624..1101784a212 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 68043ed7056..a91b2c130ea 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1169,8 +1169,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 h1:Yk0RK9WV59ISOZZMsdtxZBAKaBfdgb05oXyca/qSqcw= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 h1:UIl76fBNtmgCn5SbxggOBOoZDxRznIue5Y42+kAVU+Y= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index e7f867c54fb..d16bfc747c6 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -427,6 +427,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { keyStore.Eth(), opts.RelayerChainInteroperators, mailMon, + registry, ) delegates[job.Bootstrap] = ocrbootstrap.NewDelegateBootstrap( db, diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index 3e8ccbab848..2139b4a02e2 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -16,6 +16,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/bridges" mocklp "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" @@ -304,7 +305,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { ocr2DelegateConfig := ocr2.NewDelegateConfig(config.OCR2(), config.Mercury(), config.Threshold(), config.Insecure(), config.JobPipeline(), config.Database(), processConfig) d := ocr2.NewDelegate(nil, orm, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig, - keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon) + keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, capabilities.NewRegistry()) delegateOCR2 := &delegate{jobOCR2VRF.Type, []job.ServiceCtx{}, 0, nil, d} spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{ diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index c185ec6ddbe..25c3cf9a485 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -119,7 +119,8 @@ type Delegate struct { isNewlyCreatedJob bool // Set to true if this is a new job freshly added, false if job was present already on node boot. mailMon *mailbox.Monitor - legacyChains legacyevm.LegacyChainContainer // legacy: use relayers instead + legacyChains legacyevm.LegacyChainContainer // legacy: use relayers instead + capabilitiesRegistry types.CapabilitiesRegistry } type DelegateConfig interface { @@ -229,6 +230,7 @@ func NewDelegate( ethKs keystore.Eth, relayers RelayGetter, mailMon *mailbox.Monitor, + capabilitiesRegistry types.CapabilitiesRegistry, ) *Delegate { return &Delegate{ db: db, @@ -248,6 +250,7 @@ func NewDelegate( RelayGetter: relayers, isNewlyCreatedJob: false, mailMon: mailMon, + capabilitiesRegistry: capabilitiesRegistry, } } @@ -455,7 +458,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return d.newServicesOCR2Functions(lggr, jb, bootstrapPeers, kb, ocrDB, thresholdPluginDB, s4PluginDB, lc, ocrLogger) case types.GenericPlugin: - return d.newServicesGenericPlugin(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, ocrLogger) + return d.newServicesGenericPlugin(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, ocrLogger, d.capabilitiesRegistry) default: return nil, errors.Errorf("plugin type %s not supported", spec.PluginType) @@ -514,6 +517,7 @@ func (d *Delegate) newServicesGenericPlugin( ocrDB *db, lc ocrtypes.LocalConfig, ocrLogger commontypes.Logger, + capabilitiesRegistry types.CapabilitiesRegistry, ) (srvs []job.ServiceCtx, err error) { spec := jb.OCR2OracleSpec @@ -656,7 +660,7 @@ func (d *Delegate) newServicesGenericPlugin( case 3: //OCR3 with OCR2 OnchainKeyring and ContractTransmitter - plugin := ocr3.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog) + plugin := ocr3.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog, capabilitiesRegistry) contractTransmitter := ocrcommon.NewOCR3ContractTransmitterAdapter(provider.ContractTransmitter()) oracleArgs := libocr2.OCR3OracleArgs[any]{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, diff --git a/go.mod b/go.mod index a7d52bfbcbc..9f6564e2d0b 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 2df7a8d7c46..95f7b19be62 100644 --- a/go.sum +++ b/go.sum @@ -1164,8 +1164,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 h1:Yk0RK9WV59ISOZZMsdtxZBAKaBfdgb05oXyca/qSqcw= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 h1:UIl76fBNtmgCn5SbxggOBOoZDxRznIue5Y42+kAVU+Y= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 366594098ec..7786f84f0aa 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index df94da9318d..cf994786a45 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1503,8 +1503,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4 h1:Yk0RK9WV59ISOZZMsdtxZBAKaBfdgb05oXyca/qSqcw= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240213113935-001c2f4befd4/go.mod h1:pRlQrvcizMmuHAUV4N96oO2e3XbA99JCQELLc6ES160= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 h1:UIl76fBNtmgCn5SbxggOBOoZDxRznIue5Y42+kAVU+Y= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= From beee9176c9af183c8506530da4822567e9bd630c Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Thu, 15 Feb 2024 23:13:44 +0200 Subject: [PATCH 37/98] Pin to latest version chainlink-common (#12053) * Pin to latest version * Pin to latest version of common --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 1101784a212..e382b9e79b1 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index a91b2c130ea..f8c51fe0c86 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1169,8 +1169,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 h1:UIl76fBNtmgCn5SbxggOBOoZDxRznIue5Y42+kAVU+Y= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 h1:VgsaJqVkTfcRv/s4EWPPmgL8o2mjftKZSqRGluZro7M= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/go.mod b/go.mod index 9f6564e2d0b..e5182f0c386 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 95f7b19be62..78787f7abbf 100644 --- a/go.sum +++ b/go.sum @@ -1164,8 +1164,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 h1:UIl76fBNtmgCn5SbxggOBOoZDxRznIue5Y42+kAVU+Y= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 h1:VgsaJqVkTfcRv/s4EWPPmgL8o2mjftKZSqRGluZro7M= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 7786f84f0aa..38518f62cbb 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index cf994786a45..04cf650971e 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1503,8 +1503,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5 h1:UIl76fBNtmgCn5SbxggOBOoZDxRznIue5Y42+kAVU+Y= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215185320-c5d622aaecb5/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 h1:VgsaJqVkTfcRv/s4EWPPmgL8o2mjftKZSqRGluZro7M= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= From d814cf58efd97f92b5996f44af553979bfb8dffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedemann=20F=C3=BCrst?= <59653747+friedemannf@users.noreply.github.com> Date: Thu, 15 Feb 2024 22:25:24 +0100 Subject: [PATCH 38/98] Bump libocr to fe2ba71b2f0a0b66f95256426fb6b8e2957e1af4 (#12049) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index e382b9e79b1..7c0a41fa366 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -23,7 +23,7 @@ require ( github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 + github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a github.com/spf13/cobra v1.6.1 github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.4 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f8c51fe0c86..b32a445d60a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1187,8 +1187,8 @@ github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+ github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= -github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 h1:3y9WsXkZ5lxFrmfH7DQHs/q308lylKId5l/3VC0QAdM= -github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1/go.mod h1:kC0qmVPUaVkFqGiZMNhmRmjdphuUmeyLEdlWFOQzFWI= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a h1:nGkZ9uXS8lPIJOi68rdftEo2c9Q8qbRAi5+XMnKobVc= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a/go.mod h1:kC0qmVPUaVkFqGiZMNhmRmjdphuUmeyLEdlWFOQzFWI= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/go.mod b/go.mod index e5182f0c386..799dbe9b906 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 - github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 + github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/wsrpc v0.7.2 diff --git a/go.sum b/go.sum index 78787f7abbf..097aaea35c9 100644 --- a/go.sum +++ b/go.sum @@ -1182,8 +1182,8 @@ github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+ github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= -github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 h1:3y9WsXkZ5lxFrmfH7DQHs/q308lylKId5l/3VC0QAdM= -github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1/go.mod h1:kC0qmVPUaVkFqGiZMNhmRmjdphuUmeyLEdlWFOQzFWI= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a h1:nGkZ9uXS8lPIJOi68rdftEo2c9Q8qbRAi5+XMnKobVc= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a/go.mod h1:kC0qmVPUaVkFqGiZMNhmRmjdphuUmeyLEdlWFOQzFWI= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 38518f62cbb..0f9df5b63f9 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 + github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/wasp v0.4.2 github.com/spf13/cobra v1.8.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 04cf650971e..275761a080e 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1523,8 +1523,8 @@ github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+ github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= -github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1 h1:3y9WsXkZ5lxFrmfH7DQHs/q308lylKId5l/3VC0QAdM= -github.com/smartcontractkit/libocr v0.0.0-20240112202000-6359502d2ff1/go.mod h1:kC0qmVPUaVkFqGiZMNhmRmjdphuUmeyLEdlWFOQzFWI= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a h1:nGkZ9uXS8lPIJOi68rdftEo2c9Q8qbRAi5+XMnKobVc= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a/go.mod h1:kC0qmVPUaVkFqGiZMNhmRmjdphuUmeyLEdlWFOQzFWI= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= From f7865e840c8f05341873a097fe7cc7077bc73a97 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 15 Feb 2024 13:32:14 -0800 Subject: [PATCH 39/98] chore: github action version bumps (#12023) * chore: bump pnpm/action-setup to v3.0.0 * chore: bump docker/metadata-action to v5.5.0 * chore: bump dorny/paths-filter to v3.0.0 --- .github/actions/build-sign-publish-chainlink/action.yml | 2 +- .github/actions/delete-deployments/action.yml | 2 +- .github/actions/setup-nodejs/action.yaml | 2 +- .github/workflows/bash-scripts.yml | 2 +- .github/workflows/dependency-check.yml | 2 +- .github/workflows/integration-tests.yml | 2 +- .github/workflows/solidity-foundry.yml | 2 +- .github/workflows/solidity-hardhat.yml | 2 +- .github/workflows/solidity.yml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/actions/build-sign-publish-chainlink/action.yml b/.github/actions/build-sign-publish-chainlink/action.yml index 305a940e8a2..5bcbf205c1b 100644 --- a/.github/actions/build-sign-publish-chainlink/action.yml +++ b/.github/actions/build-sign-publish-chainlink/action.yml @@ -122,7 +122,7 @@ runs: - name: Generate docker metadata for root image id: meta-root - uses: docker/metadata-action@2c0bd771b40637d97bf205cbccdd294a32112176 # v4.5.0 + uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 env: DOCKER_METADATA_PR_HEAD_SHA: "true" with: diff --git a/.github/actions/delete-deployments/action.yml b/.github/actions/delete-deployments/action.yml index 5fc7ef0287b..f2595b41022 100644 --- a/.github/actions/delete-deployments/action.yml +++ b/.github/actions/delete-deployments/action.yml @@ -29,7 +29,7 @@ inputs: runs: using: composite steps: - - uses: pnpm/action-setup@c3b53f6a16e57305370b4ae5a540c2077a1d50dd # v2.2.4 + - uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0 with: version: ^8.0.0 diff --git a/.github/actions/setup-nodejs/action.yaml b/.github/actions/setup-nodejs/action.yaml index 1bb529b421c..e0bdaebe99e 100644 --- a/.github/actions/setup-nodejs/action.yaml +++ b/.github/actions/setup-nodejs/action.yaml @@ -7,7 +7,7 @@ description: Setup pnpm for contracts runs: using: composite steps: - - uses: pnpm/action-setup@c3b53f6a16e57305370b4ae5a540c2077a1d50dd # v2.2.4 + - uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0 with: version: ^7.0.0 diff --git a/.github/workflows/bash-scripts.yml b/.github/workflows/bash-scripts.yml index 52ce17f1f28..9fe2a0e60e4 100644 --- a/.github/workflows/bash-scripts.yml +++ b/.github/workflows/bash-scripts.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 + - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 id: bash-scripts with: filters: | diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml index 1ad3c50b351..1f820cb2bbf 100644 --- a/.github/workflows/dependency-check.yml +++ b/.github/workflows/dependency-check.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 + - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 id: changes with: filters: | diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 1edb3f003db..283ba31a4de 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -57,7 +57,7 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 + - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 id: changes with: filters: | diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 128209e931c..7c930207fe7 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 + - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 id: changes with: # Foundry is only used for Solidity v0.8 contracts, therefore we can ignore diff --git a/.github/workflows/solidity-hardhat.yml b/.github/workflows/solidity-hardhat.yml index bbb092f6a13..da9d7daccbb 100644 --- a/.github/workflows/solidity-hardhat.yml +++ b/.github/workflows/solidity-hardhat.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 + - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 id: changes with: filters: | diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 6995a00d880..904cdacfbff 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 + - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 id: changes with: list-files: "csv" From 9ed21610069f475fb79850e3b7cb572e0ec3346b Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 15 Feb 2024 14:46:39 -0700 Subject: [PATCH 40/98] Add plugins build back into CI (#12054) --- .github/workflows/integration-tests.yml | 6 +++--- plugins/chainlink.Dockerfile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 283ba31a4de..e5610fcd8a4 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -123,9 +123,9 @@ jobs: - name: "" dockerfile: core/chainlink.Dockerfile tag-suffix: "" - # - name: (plugins) - # dockerfile: plugins/chainlink.Dockerfile - # tag-suffix: -plugins + - name: (plugins) + dockerfile: plugins/chainlink.Dockerfile + tag-suffix: -plugins name: Build Chainlink Image ${{ matrix.image.name }} runs-on: ubuntu20.04-16cores-64GB needs: [changes, enforce-ctf-version] diff --git a/plugins/chainlink.Dockerfile b/plugins/chainlink.Dockerfile index a518b37a9e1..cdfc3ee1356 100644 --- a/plugins/chainlink.Dockerfile +++ b/plugins/chainlink.Dockerfile @@ -37,7 +37,7 @@ RUN go install ./cmd/chainlink-feeds WORKDIR /chainlink-data-streams COPY --from=buildgo /chainlink-data-streams . -RUN go install ./cmd/chainlink-data-streams/mercury/cmd/chainlink-mercury +RUN go install ./mercury/cmd/chainlink-mercury WORKDIR /chainlink-solana COPY --from=buildgo /chainlink-solana . From fd94ff5412f38ac7e2f9435337ccc1c6c37917fa Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Thu, 15 Feb 2024 16:57:35 -0500 Subject: [PATCH 41/98] FUN-1247 (refactor): Move Functions Coordinator duplicate request ID check earlier (#12018) --- .../gas-snapshots/functions.gas-snapshot | 68 ++++++++-------- .../functions/dev/v1_X/FunctionsBilling.sol | 5 ++ .../dev/v1_X/FunctionsCoordinator.sol | 50 ++++++++---- .../v0.8/functions/dev/v1_X/ocr/OCR2Base.sol | 35 +++++---- .../tests/v1_X/FunctionsSubscriptions.t.sol | 2 +- .../src/v0.8/functions/tests/v1_X/Gas.t.sol | 78 +++++++++++++++++-- .../FunctionsCoordinatorHarness.sol | 10 +-- .../FunctionsCoordinatorTestHelper.sol | 53 ++++++++++++- .../functions_coordinator.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 10 files changed, 223 insertions(+), 82 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 39efc0d10ea..ab6a4933e69 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,20 +1,20 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14805978) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14805956) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14805972) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14817392) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14817369) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14817341) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14817292) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14817281) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14817325) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14859450) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14859428) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14859444) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14870866) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14870843) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14870815) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14870766) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14870755) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14870799) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) -FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32458) -FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 53807) -FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 53910) +FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32414) +FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 53763) +FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 53866) FunctionsBilling_GetAdminFee:test_GetAdminFee_Success() (gas: 18226) -FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 23671) +FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 23693) FunctionsBilling_GetDONFee:test_GetDONFee_Success() (gas: 15792) FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 31773) FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70128) @@ -24,45 +24,43 @@ FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanc FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13296) FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 147278) FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 18974) -FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 38251) +FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 38273) FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810) FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13302) FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 180763) FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 398400) FunctionsClient_Constructor:test_Constructor_Success() (gas: 7573) -FunctionsClient_FulfillRequest:test_FulfillRequest_MaximumGas() (gas: 497786) -FunctionsClient_FulfillRequest:test_FulfillRequest_MinimumGas() (gas: 198990) FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14623) FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22923) FunctionsClient__SendRequest:test__SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 55059) FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 12006) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15334) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 106506) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15356) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 106528) FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15313) FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 656362) FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20364) -FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 101285) +FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 101307) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13892) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 651054) FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22703) -FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 108848) +FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 108804) FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 18957) FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 19690) FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 246) FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 223) FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 225) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12007) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 167477) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 157808) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 169845) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 160176) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38115) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35238) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 175953) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 178321) FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28086) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 151496) -FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321059) -FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334680) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2510006) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540441) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 153883) +FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321333) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334954) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2510380) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540815) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17983) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12904) FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 37159) @@ -91,7 +89,7 @@ FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() ( FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082) FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132) FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291) -FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 286243) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 286199) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65887) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896) @@ -99,7 +97,7 @@ FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalid FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27503) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 292812) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 292746) FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 193512) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30688) FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403) @@ -146,7 +144,7 @@ FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCa FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 42404) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13441) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 47347) -FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success(uint96) (runs: 256, μ: 81598, ~: 81598) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 81490) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20745) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfBalanceInvariant() (gas: 189) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15638) @@ -208,12 +206,12 @@ FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 96 FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12253) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19199) FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 12995) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12184656) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12237753) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16571) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13301) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20448) FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 12931) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12184660) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12237757) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18493) @@ -230,6 +228,10 @@ FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79131) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20695) +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MinimumGas() (gas: 20135) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MaximumGas() (gas: 498083) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MinimumGas() (gas: 199286) Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38546) Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 979631) Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 157578) \ No newline at end of file diff --git a/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol index c3f351e6c76..3abfd893186 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol @@ -372,4 +372,9 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // Overriden in FunctionsCoordinator.sol function _onlyOwner() internal view virtual; + + // Used in FunctionsCoordinator.sol + function _isExistingRequest(bytes32 requestId) internal view returns (bool) { + return s_requestCommitments[requestId] != bytes32(0); + } } diff --git a/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol index 33c45c218d4..9b3e0cc7d7b 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol @@ -125,14 +125,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_transmitters; } - /// @dev Report hook called within OCR2Base.sol - function _report( - uint256 /*initialGas*/, - address /*transmitter*/, - uint8 /*signerCount*/, - address[MAX_NUM_ORACLES] memory /*signers*/, + function _beforeTransmit( bytes calldata report - ) internal override { + ) internal view override returns (bool shouldStop, DecodedReport memory decodedReport) { ( bytes32[] memory requestIds, bytes[] memory results, @@ -152,15 +147,44 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli revert ReportInvalid("Fields must be equal length"); } + for (uint256 i = 0; i < numberOfFulfillments; ++i) { + if (_isExistingRequest(requestIds[i])) { + // If there is an existing request, validate report + // Leave shouldStop to default, false + break; + } + if (i == numberOfFulfillments - 1) { + // If the last fulfillment on the report does not exist, then all are duplicates + // Indicate that it's safe to stop to save on the gas of validating the report + shouldStop = true; + } + } + + return ( + shouldStop, + DecodedReport({ + requestIds: requestIds, + results: results, + errors: errors, + onchainMetadata: onchainMetadata, + offchainMetadata: offchainMetadata + }) + ); + } + + /// @dev Report hook called within OCR2Base.sol + function _report(DecodedReport memory decodedReport) internal override { + uint256 numberOfFulfillments = uint8(decodedReport.requestIds.length); + // Bounded by "MaxRequestBatchSize" on the Job's ReportingPluginConfig for (uint256 i = 0; i < numberOfFulfillments; ++i) { FunctionsResponse.FulfillResult result = FunctionsResponse.FulfillResult( _fulfillAndBill( - requestIds[i], - results[i], - errors[i], - onchainMetadata[i], - offchainMetadata[i], + decodedReport.requestIds[i], + decodedReport.results[i], + decodedReport.errors[i], + decodedReport.onchainMetadata[i], + decodedReport.offchainMetadata[i], uint8(numberOfFulfillments) // will not exceed "MaxRequestBatchSize" on the Job's ReportingPluginConfig ) ); @@ -172,7 +196,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli result == FunctionsResponse.FulfillResult.FULFILLED || result == FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR ) { - emit OracleResponse(requestIds[i], msg.sender); + emit OracleResponse(decodedReport.requestIds[i], msg.sender); } } } diff --git a/contracts/src/v0.8/functions/dev/v1_X/ocr/OCR2Base.sol b/contracts/src/v0.8/functions/dev/v1_X/ocr/OCR2Base.sol index 375159bf4c9..cf461bdb217 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/ocr/OCR2Base.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/ocr/OCR2Base.sol @@ -59,6 +59,14 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { // i.e. the address the oracle actually sends transactions to the contract from address[] internal s_transmitters; + struct DecodedReport { + bytes32[] requestIds; + bytes[] results; + bytes[] errors; + bytes[] onchainMetadata; + bytes[] offchainMetadata; + } + /* * Config logic */ @@ -238,18 +246,9 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { /** * @dev hook called after the report has been fully validated * for the extending contract to handle additional logic, such as oracle payment - * @param initialGas the amount of gas before validation - * @param transmitter the address of the account that submitted the report - * @param signers the addresses of all signing accounts - * @param report serialized report + * @param decodedReport decodedReport */ - function _report( - uint256 initialGas, - address transmitter, - uint8 signerCount, - address[MAX_NUM_ORACLES] memory signers, - bytes calldata report - ) internal virtual; + function _report(DecodedReport memory decodedReport) internal virtual; // The constant-length components of the msg.data sent to transmit. // See the "If we wanted to call sam" example on for example reasoning @@ -283,6 +282,10 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { if (msg.data.length != expected) revert ReportInvalid("calldata length mismatch"); } + function _beforeTransmit( + bytes calldata report + ) internal virtual returns (bool shouldStop, DecodedReport memory decodedReport); + /** * @notice transmit is called to post a new report to the contract * @param report serialized report, which the signatures are signing. @@ -299,7 +302,11 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { bytes32[] calldata ss, bytes32 rawVs // signatures ) external override { - uint256 initialGas = gasleft(); // This line must come first + (bool shouldStop, DecodedReport memory decodedReport) = _beforeTransmit(report); + + if (shouldStop) { + return; + } { // reportContext consists of: @@ -328,7 +335,6 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { } address[MAX_NUM_ORACLES] memory signed; - uint8 signerCount = 0; { // Verify signatures attached to report @@ -342,10 +348,9 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { if (o.role != Role.Signer) revert ReportInvalid("address not authorized to sign"); if (signed[o.index] != address(0)) revert ReportInvalid("non-unique signature"); signed[o.index] = signer; - signerCount += 1; } } - _report(initialGas, msg.sender, signerCount, signed, report); + _report(decodedReport); } } diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol index 907eadacd8e..d036b5354ef 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol @@ -346,7 +346,7 @@ contract FunctionsSubscriptions_OnTokenTransfer is FunctionsClientSetup { s_linkToken.transferAndCall(address(s_functionsRouter), totalSupplyJuels, abi.encode(invalidSubscriptionId)); } - function test_OnTokenTransfer_Success(uint96 fundingAmount) public { + function test_OnTokenTransfer_Success() public { // Funding amount must be less than LINK total supply uint256 totalSupplyJuels = 1_000_000_000 * 1e18; // Some of the total supply is already in the subscription account diff --git a/contracts/src/v0.8/functions/tests/v1_X/Gas.t.sol b/contracts/src/v0.8/functions/tests/v1_X/Gas.t.sol index f2d7af54e4f..1ecc0fb7c0b 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/Gas.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/Gas.t.sol @@ -152,8 +152,8 @@ contract Gas_SendRequest is FunctionsSubscriptionSetup { } } -/// @notice #fulfillRequest -contract FunctionsClient_FulfillRequest is FunctionsClientRequestSetup { +// Setup Fulfill Gas tests +contract Gas_FulfillRequest_Setup is FunctionsClientRequestSetup { mapping(uint256 reportNumber => Report) s_reports; FunctionsClientTestHelper s_functionsClientWithMaximumReturnData; @@ -163,8 +163,6 @@ contract FunctionsClient_FulfillRequest is FunctionsClientRequestSetup { } function setUp() public virtual override { - vm.pauseGasMetering(); - FunctionsSubscriptionSetup.setUp(); { @@ -271,9 +269,77 @@ contract FunctionsClient_FulfillRequest is FunctionsClientRequestSetup { vm.stopPrank(); vm.startPrank(NOP_TRANSMITTER_ADDRESS_1); } +} + +/// @notice #fulfillRequest +contract Gas_FulfillRequest_Success is Gas_FulfillRequest_Setup { + function setUp() public virtual override { + vm.pauseGasMetering(); + + Gas_FulfillRequest_Setup.setUp(); + } + + /// @dev The order of these test cases matters as the first test will consume more gas by writing over default values + function test_FulfillRequest_Success_MaximumGas() public { + // Pull storage variables into memory + uint8 reportNumber = 1; + bytes32[] memory rs = s_reports[reportNumber].rs; + bytes32[] memory ss = s_reports[reportNumber].ss; + bytes32 vs = s_reports[reportNumber].vs; + bytes memory report = s_reports[reportNumber].report; + bytes32[3] memory reportContext = s_reports[reportNumber].reportContext; + vm.resumeGasMetering(); + + // 1 fulfillment in the report, single request takes on all report validation cost + // maximum request + // maximum NOPs + // maximum return data + // first storage write to change default values + s_functionsCoordinator.transmit(reportContext, report, rs, ss, vs); + } + + function test_FulfillRequest_Success_MinimumGas() public { + // Pull storage variables into memory + uint8 reportNumber = 2; + bytes32[] memory rs = s_reports[reportNumber].rs; + bytes32[] memory ss = s_reports[reportNumber].ss; + bytes32 vs = s_reports[reportNumber].vs; + bytes memory report = s_reports[reportNumber].report; + bytes32[3] memory reportContext = s_reports[reportNumber].reportContext; + vm.resumeGasMetering(); + + // max fulfillments in the report, cost of validation split between all + // minimal request + // minimum NOPs + // no return data + // not storage writing default values + s_functionsCoordinator.transmit(reportContext, report, rs, ss, vs); + } +} + +/// @notice #fulfillRequest +contract Gas_FulfillRequest_DuplicateRequestID is Gas_FulfillRequest_Setup { + function setUp() public virtual override { + vm.pauseGasMetering(); + + // Send requests + Gas_FulfillRequest_Setup.setUp(); + // Fulfill request #1 & #2 + for (uint256 i = 1; i < 3; i++) { + uint256 reportNumber = i; + bytes32[] memory rs = s_reports[reportNumber].rs; + bytes32[] memory ss = s_reports[reportNumber].ss; + bytes32 vs = s_reports[reportNumber].vs; + bytes memory report = s_reports[reportNumber].report; + bytes32[3] memory reportContext = s_reports[reportNumber].reportContext; + s_functionsCoordinator.transmit(reportContext, report, rs, ss, vs); + } + + // Now tests will attempt to transmit reports with respones to requests that have already been fulfilled + } /// @dev The order of these test cases matters as the first test will consume more gas by writing over default values - function test_FulfillRequest_MaximumGas() public { + function test_FulfillRequest_DuplicateRequestID_MaximumGas() public { // Pull storage variables into memory uint8 reportNumber = 1; bytes32[] memory rs = s_reports[reportNumber].rs; @@ -291,7 +357,7 @@ contract FunctionsClient_FulfillRequest is FunctionsClientRequestSetup { s_functionsCoordinator.transmit(reportContext, report, rs, ss, vs); } - function test_FulfillRequest_MinimumGas() public { + function test_FulfillRequest_DuplicateRequestID_MinimumGas() public { // Pull storage variables into memory uint8 reportNumber = 2; bytes32[] memory rs = s_reports[reportNumber].rs; diff --git a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol index 15d9790f617..e4e9f7279a7 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol @@ -34,14 +34,8 @@ contract FunctionsCoordinatorHarness is FunctionsCoordinator { return super._getTransmitters(); } - function report_HARNESS( - uint256 initialGas, - address transmitter, - uint8 signerCount, - address[MAX_NUM_ORACLES] memory signers, - bytes calldata report - ) external { - return super._report(initialGas, transmitter, signerCount, signers, report); + function report_HARNESS(DecodedReport memory decodedReport) external { + return super._report(decodedReport); } function onlyOwner_HARNESS() external view { diff --git a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol index 1a7d721d63a..abfec4c2de5 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol @@ -15,17 +15,62 @@ contract FunctionsCoordinatorTestHelper is FunctionsCoordinator { function callReport(bytes calldata report) external { address[MAX_NUM_ORACLES] memory signers; signers[0] = msg.sender; - _report(gasleft(), msg.sender, 1, signers, report); + ( + bytes32[] memory requestIds, + bytes[] memory results, + bytes[] memory errors, + bytes[] memory onchainMetadata, + bytes[] memory offchainMetadata + ) = abi.decode(report, (bytes32[], bytes[], bytes[], bytes[], bytes[])); + _report( + DecodedReport({ + requestIds: requestIds, + results: results, + errors: errors, + onchainMetadata: onchainMetadata, + offchainMetadata: offchainMetadata + }) + ); } function callReportMultipleSigners(bytes calldata report, address secondSigner) external { address[MAX_NUM_ORACLES] memory signers; signers[0] = msg.sender; signers[1] = secondSigner; - _report(gasleft(), msg.sender, 2, signers, report); + ( + bytes32[] memory requestIds, + bytes[] memory results, + bytes[] memory errors, + bytes[] memory onchainMetadata, + bytes[] memory offchainMetadata + ) = abi.decode(report, (bytes32[], bytes[], bytes[], bytes[], bytes[])); + _report( + DecodedReport({ + requestIds: requestIds, + results: results, + errors: errors, + onchainMetadata: onchainMetadata, + offchainMetadata: offchainMetadata + }) + ); } - function callReportWithSigners(bytes calldata report, address[MAX_NUM_ORACLES] memory signers) external { - _report(gasleft(), msg.sender, 2, signers, report); + function callReportWithSigners(bytes calldata report, address[MAX_NUM_ORACLES] memory /* signers */) external { + ( + bytes32[] memory requestIds, + bytes[] memory results, + bytes[] memory errors, + bytes[] memory onchainMetadata, + bytes[] memory offchainMetadata + ) = abi.decode(report, (bytes32[], bytes[], bytes[], bytes[], bytes[])); + _report( + DecodedReport({ + requestIds: requestIds, + results: results, + errors: errors, + onchainMetadata: onchainMetadata, + offchainMetadata: offchainMetadata + }) + ); } } diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index a280297782e..07b1b5e1720 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -72,7 +72,7 @@ type FunctionsResponseRequestMeta struct { var FunctionsCoordinatorMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"type\":\"event\"},{\"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\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1FeeShareWei\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"callbackCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestBilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620056d0380380620056d083398101604081905262000034916200046d565b8282828233806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000139565b5050506001600160a01b038116620000ed57604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03908116608052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200012d82620001e4565b5050505050506200062c565b336001600160a01b03821603620001935760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee62000342565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160f01b026001600160f01b0364ffffffffff909216600160c81b0264ffffffffff60c81b196001600160481b03909416600160801b0293909316600160801b600160f01b031963ffffffff9586166c010000000000000000000000000263ffffffff60601b19978716680100000000000000000297909716600160401b600160801b0319998716640100000000026001600160401b0319909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e0830151610100840151909216600160e01b026001600160e01b0390921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906200033790839062000576565b60405180910390a150565b6200034c6200034e565b565b6000546001600160a01b031633146200034c5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000086565b80516001600160a01b0381168114620003c257600080fd5b919050565b60405161012081016001600160401b0381118282101715620003f957634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff81168114620003c257600080fd5b80516001600160481b0381168114620003c257600080fd5b805164ffffffffff81168114620003c257600080fd5b805161ffff81168114620003c257600080fd5b80516001600160e01b0381168114620003c257600080fd5b60008060008385036101608112156200048557600080fd5b6200049085620003aa565b935061012080601f1983011215620004a757600080fd5b620004b1620003c7565b9150620004c160208701620003ff565b8252620004d160408701620003ff565b6020830152620004e460608701620003ff565b6040830152620004f760808701620003ff565b60608301526200050a60a0870162000414565b60808301526200051d60c087016200042c565b60a08301526200053060e0870162000442565b60c08301526101006200054581880162000455565b60e084015262000557828801620003ff565b908301525091506200056d6101408501620003aa565b90509250925092565b815163ffffffff908116825260208084015182169083015260408084015182169083015260608084015191821690830152610120820190506080830151620005c960808401826001600160481b03169052565b5060a0830151620005e360a084018264ffffffffff169052565b5060c0830151620005fa60c084018261ffff169052565b5060e08301516200061660e08401826001600160e01b03169052565b506101009283015163ffffffff16919092015290565b60805161505e6200067260003960008181610845015281816109d301528181610ca601528181610f3a01528181611045015281816117890152613490015261505e6000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806381ff7048116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610560578063e4ddcea614610573578063f2fde38b1461058957600080fd5b8063c3f909d4146103b0578063d227d24514610528578063d328a91e1461055857600080fd5b8063a631571e116100bd578063a631571e1461035d578063afcb95d71461037d578063b1dc65a41461039d57600080fd5b806381ff7048146102b557806385b214cf146103225780638da5cb5b1461033557600080fd5b806366316d8d116101455780637f15e1661161011f5780637f15e16614610285578063814118341461029857806381f1b938146102ad57600080fd5b806366316d8d1461026257806379ba5097146102755780637d4807871461027d57600080fd5b8063181f5a7711610176578063181f5a77146101ba5780632a905ccc1461020c57806359b5b7ac1461022e57600080fd5b8063083a5466146101925780631112dadc146101a7575b600080fd5b6101a56101a03660046139d4565b61059c565b005b6101a56101b5366004613b7d565b6105f1565b6101f66040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e322e300000000081525081565b6040516102039190613ca1565b60405180910390f35b610214610841565b60405168ffffffffffffffffff9091168152602001610203565b61021461023c366004613d42565b50600854700100000000000000000000000000000000900468ffffffffffffffffff1690565b6101a5610270366004613dd1565b6108d7565b6101a5610a90565b6101a5610b92565b6101a56102933660046139d4565b610d92565b6102a0610de2565b6040516102039190613e5b565b6101f6610e51565b6102ff60015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610203565b6101a5610330366004613e6e565b610f22565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b61037061036b366004613e87565b610fd4565b6040516102039190613fdc565b604080516001815260006020820181905291810191909152606001610203565b6101a56103ab366004614030565b611175565b61051b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830152700100000000000000000000000000000000810468ffffffffffffffffff166080830152790100000000000000000000000000000000000000000000000000810464ffffffffff1660a08301527e01000000000000000000000000000000000000000000000000000000000000900461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08301527c0100000000000000000000000000000000000000000000000000000000900490911661010082015290565b60405161020391906140e7565b61053b6105363660046141d7565b611785565b6040516bffffffffffffffffffffffff9091168152602001610203565b6101f66118e5565b6101a561056e3660046142f0565b61193c565b61057b6124b8565b604051908152602001610203565b6101a56105973660046143bd565b612711565b6105a4612725565b60008190036105df576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105ec828483614473565b505050565b6105f96127a8565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff64ffffffffff909216790100000000000000000000000000000000000000000000000000027fffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90941670010000000000000000000000000000000002939093167fffff0000000000000000000000000000ffffffffffffffffffffffffffffffff63ffffffff9586166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9787166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e08301516101008401519092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906108369083906140e7565b60405180910390a150565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d29190614599565b905090565b6108df6127b0565b806bffffffffffffffffffffffff166000036109195750336000908152600a60205260409020546bffffffffffffffffffffffff16610973565b336000908152600a60205260409020546bffffffffffffffffffffffff80831691161015610973576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906109a09084906bffffffffffffffffffffffff166145e5565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506109f57f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610a7457600080fd5b505af1158015610a88573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b9a6127a8565b610ba26127b0565b6000610bac610de2565b905060005b8151811015610d8e576000600a6000848481518110610bd257610bd261460a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610d7d576000600a6000858581518110610c3157610c3161460a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610cc87f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610cf557610cf561460a565b6020026020010151836040518363ffffffff1660e01b8152600401610d4a92919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d6457600080fd5b505af1158015610d78573d6000803e3d6000fd5b505050505b50610d8781614639565b9050610bb1565b5050565b610d9a612725565b6000819003610dd5576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105ec828483614473565b60606006805480602002602001604051908101604052809291908181526020018280548015610e4757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e1c575b5050505050905090565b6060600d8054610e60906143da565b9050600003610e9b576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610ea8906143da565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed4906143da565b8015610e475780601f10610ef657610100808354040283529160200191610e47565b820191906000526020600020905b815481529060010190602001808311610f0457509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f91576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416906108369083815260200190565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461109c576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110ad6110a883614671565b61295c565b90506110bf60608301604084016143bd565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261110d60c0870160a0880161475e565b61111f610160880161014089016143bd565b611129888061477b565b61113b6101208b016101008c016147e0565b60208b01356111516101008d0160e08e016147fb565b8b60405161116799989796959493929190614818565b60405180910390a35b919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16111d68a8a8a8a8a8a612dfa565b6003546000906002906111f49060ff808216916101009004166148c0565b6111fe9190614908565b6112099060016148c0565b60ff169050878114611277576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610b0d565b878614611306576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f7265706f727420727320616e64207373206d757374206265206f66206571756160448201527f6c206c656e6774680000000000000000000000000000000000000000000000006064820152608401610b0d565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113495761134961492a565b600281111561135a5761135a61492a565b90525090506002816020015160028111156113775761137761492a565b141580156113c057506006816000015160ff168154811061139a5761139a61460a565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b15611427576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610b0d565b5050505061143361396c565b6000808a8a604051611446929190614959565b60405190819003812061145d918e90602001614969565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117675760006001848984602081106114c6576114c661460a565b6114d391901a601b6148c0565b8e8e868181106114e5576114e561460a565b905060200201358d8d878181106114fe576114fe61460a565b905060200201356040516000815260200160405260405161153b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561155d573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156115dd576115dd61492a565b60028111156115ee576115ee61492a565b905250925060018360200151600281111561160b5761160b61492a565b14611672576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610b0d565b8251600090879060ff16601f811061168c5761168c61460a565b602002015173ffffffffffffffffffffffffffffffffffffffff161461170e576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610b0d565b8086846000015160ff16601f81106117285761172861460a565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526117536001866148c0565b9450508061176090614639565b90506114a7565b505050611778833383858e8e612eb1565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b15801561182557600080fd5b505afa158015611839573d6000803e3d6000fd5b5050505066038d7ea4c6800082111561187e576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611888610841565b905060006118cb87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061023c92505050565b90506118d9858583856130b0565b98975050505050505050565b6060600c80546118f4906143da565b905060000361192f576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610ea8906143da565b855185518560ff16601f8311156119af576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610b0d565b80600003611a19576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610b0d565b818314611aa7576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610b0d565b611ab281600361497d565b8311611b1a576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610b0d565b611b22612725565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611b69908861321d565b60055415611d1e57600554600090611b8390600190614994565b9050600060058281548110611b9a57611b9a61460a565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611bd457611bd461460a565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611c5457611c546149a7565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611cbd57611cbd6149a7565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611b69915050565b60005b8151518110156122d557815180516000919083908110611d4357611d4361460a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611dc8576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7369676e6572206d757374206e6f7420626520656d70747900000000000000006044820152606401610b0d565b600073ffffffffffffffffffffffffffffffffffffffff1682602001518281518110611df657611df661460a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611e7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d7074790000006044820152606401610b0d565b60006004600084600001518481518110611e9757611e9761460a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611ee157611ee161492a565b14611f48576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610b0d565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611f7957611f7961460a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561201a5761201a61492a565b02179055506000915061202a9050565b60046000846020015184815181106120445761204461460a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561208e5761208e61492a565b146120f5576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610b0d565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106121285761212861460a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156121c9576121c961492a565b0217905550508251805160059250839081106121e7576121e761460a565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106122635761226361460a565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055806122cd81614639565b915050611d21565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161238d918491740100000000000000000000000000000000000000009004166149d6565b92506101000a81548163ffffffff021916908363ffffffff1602179055506123ec4630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613236565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986124a3988b9891977401000000000000000000000000000000000000000090920463ffffffff169690959194919391926149f3565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000080830482166060850152700100000000000000000000000000000000830468ffffffffffffffffff166080850152790100000000000000000000000000000000000000000000000000830464ffffffffff1660a0808601919091527e0100000000000000000000000000000000000000000000000000000000000090930461ffff1660c08501526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08601527c01000000000000000000000000000000000000000000000000000000009004909116610100840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa158015612646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266a9190614aa3565b50935050925050804261267d9190614994565b836020015163ffffffff1610801561269f57506000836020015163ffffffff16115b156126cd57505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b6000821361270a576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610b0d565b5092915050565b612719612725565b612722816132e1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146127a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b0d565b565b6127a6612725565b600b546bffffffffffffffffffffffff166000036127ca57565b60006127d4610de2565b80519091506000819003612814576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b546000906128339083906bffffffffffffffffffffffff16614af3565b905060005b828110156128fe5781600a60008684815181106128575761285761460a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166128bf9190614b1e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806128f790614639565b9050612838565b506129098282614b43565b600b80546000906129299084906bffffffffffffffffffffffff166145e5565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c0100000000000000000000000081048316606083015268ffffffffffffffffff700100000000000000000000000000000000820416608083015264ffffffffff79010000000000000000000000000000000000000000000000000082041660a083015261ffff7e01000000000000000000000000000000000000000000000000000000000000909104811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08501527c0100000000000000000000000000000000000000000000000000000000900490931661010080840191909152850151919291161115612b17576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854600090700100000000000000000000000000000000900468ffffffffffffffffff1690506000612b548560e001513a8488608001516130b0565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612bb0576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083610100015163ffffffff1642612bc99190614b6b565b905060003087604001518860a001518960c001516001612be99190614b7e565b8a5180516020918201206101008d015160e08e0151604051612c9d98979695948c918c9132910173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a015267ffffffffffffffff97881660408a0152959096166060880152608087019390935261ffff9190911660a086015263ffffffff90811660c08601526bffffffffffffffffffffffff9190911660e0850152919091166101008301529091166101208201526101400190565b6040516020818303038152906040528051906020012090506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001846bffffffffffffffffffffffff168152602001886040015173ffffffffffffffffffffffffffffffffffffffff1681526020018860a0015167ffffffffffffffff1681526020018860e0015163ffffffff168152602001886080015168ffffffffffffffffff1681526020018568ffffffffffffffffff168152602001866040015163ffffffff1664ffffffffff168152602001866060015163ffffffff1664ffffffffff1681526020018363ffffffff16815250955085604051602001612dac9190613fdc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009384526007909252909120555092949350505050565b6000612e0782602061497d565b612e1285602061497d565b612e1e88610144614b6b565b612e289190614b6b565b612e329190614b6b565b612e3d906000614b6b565b9050368114612ea8576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610b0d565b50505050505050565b600080808080612ec386880188614c7a565b84519499509297509095509350915060ff16801580612ee3575084518114155b80612eef575083518114155b80612efb575082518114155b80612f07575081518114155b15612f6e576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4669656c6473206d75737420626520657175616c206c656e67746800000000006044820152606401610b0d565b60005b818110156130a1576000613006888381518110612f9057612f9061460a565b6020026020010151888481518110612faa57612faa61460a565b6020026020010151888581518110612fc457612fc461460a565b6020026020010151888681518110612fde57612fde61460a565b6020026020010151888781518110612ff857612ff861460a565b6020026020010151886133d6565b9050600081600681111561301c5761301c61492a565b1480613039575060018160068111156130375761303761492a565b145b15613090578782815181106130505761305061460a565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b5061309a81614639565b9050612f71565b50505050505050505050505050565b600854600090790100000000000000000000000000000000000000000000000000900464ffffffffff1684101561310b57600854790100000000000000000000000000000000000000000000000000900464ffffffffff1693505b600854600090612710906131259063ffffffff168761497d565b61312f9190614d4c565b6131399086614b6b565b60085490915060009087906131729063ffffffff6c010000000000000000000000008204811691680100000000000000009004166149d6565b61317c91906149d6565b63ffffffff16905060006131c66000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506136ea92505050565b905060006131e7826131d8858761497d565b6131e29190614b6b565b61382c565b9050600061320368ffffffffffffffffff808916908a16614b1e565b905061320f8183614b1e565b9a9950505050505050505050565b6000613227610de2565b511115610d8e57610d8e6127b0565b6000808a8a8a8a8a8a8a8a8a60405160200161325a99989796959493929190614d60565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613360576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b0d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080848060200190518101906133ed9190614e2c565b905060003a8261012001518361010001516134089190614ef4565b64ffffffffff16613419919061497d565b905060008460ff166134616000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506136ea92505050565b61346b9190614d4c565b9050600061347c6131e28385614b6b565b905060006134893a61382c565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298e8e868b60e0015168ffffffffffffffffff16896134e89190614b1e565b338d6040518763ffffffff1660e01b815260040161350b96959493929190614f12565b60408051808303816000875af1158015613529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354d9190614f8e565b909250905060008260068111156135665761356661492a565b1480613583575060018260068111156135815761358161492a565b145b156136d95760008e8152600760205260408120556135a18185614b1e565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0890151600b805468ffffffffffffffffff9092169390929161360d91859116614b1e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508d7f90815c2e624694e8010bffad2bcefaf96af282ef1bc2ebc0042d1b89a585e0468487848b60c0015168ffffffffffffffffff168c60e0015168ffffffffffffffffff16878b61368c9190614b1e565b6136969190614b1e565b6136a09190614b1e565b604080516bffffffffffffffffffffffff9586168152602081019490945291841683830152909216606082015290519081900360800190a25b509c9b505050505050505050505050565b6000466136f681613860565b1561377257606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061376b9190614fc1565b9392505050565b61377b81613883565b156138235773420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e8460405180608001604052806048815260200161500a604891396040516020016137db929190614fda565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016138069190613ca1565b602060405180830381865afa158015613747573d6000803e3d6000fd5b50600092915050565b600061385a6138396124b8565b61384b84670de0b6b3a764000061497d565b6138559190614d4c565b6138ca565b92915050565b600061a4b1821480613874575062066eed82145b8061385a57505062066eee1490565b6000600a82148061389557506101a482145b806138a2575062aa37dc82145b806138ae575061210582145b806138bb575062014a3382145b8061385a57505062014a341490565b60006bffffffffffffffffffffffff821115613968576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610b0d565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f84011261399d57600080fd5b50813567ffffffffffffffff8111156139b557600080fd5b6020830191508360208285010111156139cd57600080fd5b9250929050565b600080602083850312156139e757600080fd5b823567ffffffffffffffff8111156139fe57600080fd5b613a0a8582860161398b565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715613a6957613a69613a16565b60405290565b604051610160810167ffffffffffffffff81118282101715613a6957613a69613a16565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ada57613ada613a16565b604052919050565b63ffffffff8116811461272257600080fd5b803561117081613ae2565b68ffffffffffffffffff8116811461272257600080fd5b803561117081613aff565b64ffffffffff8116811461272257600080fd5b803561117081613b21565b803561ffff8116811461117057600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461117057600080fd5b60006101208284031215613b9057600080fd5b613b98613a45565b613ba183613af4565b8152613baf60208401613af4565b6020820152613bc060408401613af4565b6040820152613bd160608401613af4565b6060820152613be260808401613b16565b6080820152613bf360a08401613b34565b60a0820152613c0460c08401613b3f565b60c0820152613c1560e08401613b51565b60e0820152610100613c28818501613af4565b908201529392505050565b60005b83811015613c4e578181015183820152602001613c36565b50506000910152565b60008151808452613c6f816020860160208601613c33565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061376b6020830184613c57565b600082601f830112613cc557600080fd5b813567ffffffffffffffff811115613cdf57613cdf613a16565b613d1060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613a93565b818152846020838601011115613d2557600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613d5457600080fd5b813567ffffffffffffffff811115613d6b57600080fd5b613d7784828501613cb4565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461272257600080fd5b803561117081613d7f565b6bffffffffffffffffffffffff8116811461272257600080fd5b803561117081613dac565b60008060408385031215613de457600080fd5b8235613def81613d7f565b91506020830135613dff81613dac565b809150509250929050565b600081518084526020808501945080840160005b83811015613e5057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e1e565b509495945050505050565b60208152600061376b6020830184613e0a565b600060208284031215613e8057600080fd5b5035919050565b600060208284031215613e9957600080fd5b813567ffffffffffffffff811115613eb057600080fd5b8201610160818503121561376b57600080fd5b805182526020810151613eee602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613f0e60408401826bffffffffffffffffffffffff169052565b506060810151613f36606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613f52608084018267ffffffffffffffff169052565b5060a0810151613f6a60a084018263ffffffff169052565b5060c0810151613f8760c084018268ffffffffffffffffff169052565b5060e0810151613fa460e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161385a8284613ec3565b60008083601f840112613ffd57600080fd5b50813567ffffffffffffffff81111561401557600080fd5b6020830191508360208260051b85010111156139cd57600080fd5b60008060008060008060008060e0898b03121561404c57600080fd5b606089018a81111561405d57600080fd5b8998503567ffffffffffffffff8082111561407757600080fd5b6140838c838d0161398b565b909950975060808b013591508082111561409c57600080fd5b6140a88c838d01613feb565b909750955060a08b01359150808211156140c157600080fd5b506140ce8b828c01613feb565b999c989b50969995989497949560c00135949350505050565b815163ffffffff90811682526020808401518216908301526040808401518216908301526060808401519182169083015261012082019050608083015161413b608084018268ffffffffffffffffff169052565b5060a083015161415460a084018264ffffffffff169052565b5060c083015161416a60c084018261ffff169052565b5060e083015161419a60e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b506101008381015163ffffffff8116848301525b505092915050565b67ffffffffffffffff8116811461272257600080fd5b8035611170816141b6565b6000806000806000608086880312156141ef57600080fd5b85356141fa816141b6565b9450602086013567ffffffffffffffff81111561421657600080fd5b6142228882890161398b565b909550935050604086013561423681613ae2565b949793965091946060013592915050565b600067ffffffffffffffff82111561426157614261613a16565b5060051b60200190565b600082601f83011261427c57600080fd5b8135602061429161428c83614247565b613a93565b82815260059290921b840181019181810190868411156142b057600080fd5b8286015b848110156142d45780356142c781613d7f565b83529183019183016142b4565b509695505050505050565b803560ff8116811461117057600080fd5b60008060008060008060c0878903121561430957600080fd5b863567ffffffffffffffff8082111561432157600080fd5b61432d8a838b0161426b565b9750602089013591508082111561434357600080fd5b61434f8a838b0161426b565b965061435d60408a016142df565b9550606089013591508082111561437357600080fd5b61437f8a838b01613cb4565b945061438d60808a016141cc565b935060a08901359150808211156143a357600080fd5b506143b089828a01613cb4565b9150509295509295509295565b6000602082840312156143cf57600080fd5b813561376b81613d7f565b600181811c908216806143ee57607f821691505b602082108103614427577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105ec57600081815260208120601f850160051c810160208610156144545750805b601f850160051c820191505b81811015610a8857828155600101614460565b67ffffffffffffffff83111561448b5761448b613a16565b61449f8361449983546143da565b8361442d565b6000601f8411600181146144f157600085156144bb5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614587565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156145405786850135825560209485019460019092019101614520565b508682101561457b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b805161117081613aff565b6000602082840312156145ab57600080fd5b815161376b81613aff565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff82811682821603908082111561270a5761270a6145b6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361466a5761466a6145b6565b5060010190565b6000610160823603121561468457600080fd5b61468c613a6f565b823567ffffffffffffffff8111156146a357600080fd5b6146af36828601613cb4565b825250602083013560208201526146c860408401613da1565b60408201526146d960608401613dc6565b60608201526146ea60808401613b16565b60808201526146fb60a084016141cc565b60a082015261470c60c084016141cc565b60c082015261471d60e08401613af4565b60e0820152610100614730818501613b3f565b908201526101206147428482016141cc565b90820152610140614754848201613da1565b9082015292915050565b60006020828403121561477057600080fd5b813561376b816141b6565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126147b057600080fd5b83018035915067ffffffffffffffff8211156147cb57600080fd5b6020019150368190038213156139cd57600080fd5b6000602082840312156147f257600080fd5b61376b82613b3f565b60006020828403121561480d57600080fd5b813561376b81613ae2565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016830101905061320f60e0830184613ec3565b60ff818116838216019081111561385a5761385a6145b6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff83168061491b5761491b6148d9565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761385a5761385a6145b6565b8181038181111561385a5761385a6145b6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff81811683821601908082111561270a5761270a6145b6565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614a238184018a613e0a565b90508281036080840152614a378189613e0a565b905060ff871660a084015282810360c0840152614a548187613c57565b905067ffffffffffffffff851660e0840152828103610100840152614a798185613c57565b9c9b505050505050505050505050565b805169ffffffffffffffffffff8116811461117057600080fd5b600080600080600060a08688031215614abb57600080fd5b614ac486614a89565b9450602086015193506040860151925060608601519150614ae760808701614a89565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614b1257614b126148d9565b92169190910492915050565b6bffffffffffffffffffffffff81811683821601908082111561270a5761270a6145b6565b6bffffffffffffffffffffffff8181168382160280821691908281146141ae576141ae6145b6565b8082018082111561385a5761385a6145b6565b67ffffffffffffffff81811683821601908082111561270a5761270a6145b6565b600082601f830112614bb057600080fd5b81356020614bc061428c83614247565b82815260059290921b84018101918181019086841115614bdf57600080fd5b8286015b848110156142d45780358352918301918301614be3565b600082601f830112614c0b57600080fd5b81356020614c1b61428c83614247565b82815260059290921b84018101918181019086841115614c3a57600080fd5b8286015b848110156142d457803567ffffffffffffffff811115614c5e5760008081fd5b614c6c8986838b0101613cb4565b845250918301918301614c3e565b600080600080600060a08688031215614c9257600080fd5b853567ffffffffffffffff80821115614caa57600080fd5b614cb689838a01614b9f565b96506020880135915080821115614ccc57600080fd5b614cd889838a01614bfa565b95506040880135915080821115614cee57600080fd5b614cfa89838a01614bfa565b94506060880135915080821115614d1057600080fd5b614d1c89838a01614bfa565b93506080880135915080821115614d3257600080fd5b50614d3f88828901614bfa565b9150509295509295909350565b600082614d5b57614d5b6148d9565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614da78285018b613e0a565b91508382036080850152614dbb828a613e0a565b915060ff881660a085015283820360c0850152614dd88288613c57565b90861660e08501528381036101008501529050614a798185613c57565b805161117081613d7f565b805161117081613dac565b8051611170816141b6565b805161117081613ae2565b805161117081613b21565b60006101608284031215614e3f57600080fd5b614e47613a6f565b82518152614e5760208401614df5565b6020820152614e6860408401614e00565b6040820152614e7960608401614df5565b6060820152614e8a60808401614e0b565b6080820152614e9b60a08401614e16565b60a0820152614eac60c0840161458e565b60c0820152614ebd60e0840161458e565b60e0820152610100614ed0818501614e21565b90820152610120614ee2848201614e21565b90820152610140613c28848201614e16565b64ffffffffff81811683821601908082111561270a5761270a6145b6565b6000610200808352614f268184018a613c57565b90508281036020840152614f3a8189613c57565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614f83905060a0830184613ec3565b979650505050505050565b60008060408385031215614fa157600080fd5b825160078110614fb057600080fd5b6020840151909250613dff81613dac565b600060208284031215614fd357600080fd5b5051919050565b60008351614fec818460208801613c33565b835190830190615000818360208801613c33565b0194935050505056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", + Bin: "0x60a06040523480156200001157600080fd5b50604051620057a9380380620057a983398101604081905262000034916200046d565b8282828233806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000139565b5050506001600160a01b038116620000ed57604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03908116608052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200012d82620001e4565b5050505050506200062c565b336001600160a01b03821603620001935760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee62000342565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160f01b026001600160f01b0364ffffffffff909216600160c81b0264ffffffffff60c81b196001600160481b03909416600160801b0293909316600160801b600160f01b031963ffffffff9586166c010000000000000000000000000263ffffffff60601b19978716680100000000000000000297909716600160401b600160801b0319998716640100000000026001600160401b0319909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e0830151610100840151909216600160e01b026001600160e01b0390921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906200033790839062000576565b60405180910390a150565b6200034c6200034e565b565b6000546001600160a01b031633146200034c5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000086565b80516001600160a01b0381168114620003c257600080fd5b919050565b60405161012081016001600160401b0381118282101715620003f957634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff81168114620003c257600080fd5b80516001600160481b0381168114620003c257600080fd5b805164ffffffffff81168114620003c257600080fd5b805161ffff81168114620003c257600080fd5b80516001600160e01b0381168114620003c257600080fd5b60008060008385036101608112156200048557600080fd5b6200049085620003aa565b935061012080601f1983011215620004a757600080fd5b620004b1620003c7565b9150620004c160208701620003ff565b8252620004d160408701620003ff565b6020830152620004e460608701620003ff565b6040830152620004f760808701620003ff565b60608301526200050a60a0870162000414565b60808301526200051d60c087016200042c565b60a08301526200053060e0870162000442565b60c08301526101006200054581880162000455565b60e084015262000557828801620003ff565b908301525091506200056d6101408501620003aa565b90509250925092565b815163ffffffff908116825260208084015182169083015260408084015182169083015260608084015191821690830152610120820190506080830151620005c960808401826001600160481b03169052565b5060a0830151620005e360a084018264ffffffffff169052565b5060c0830151620005fa60c084018261ffff169052565b5060e08301516200061660e08401826001600160e01b03169052565b506101009283015163ffffffff16919092015290565b6080516151376200067260003960008181610845015281816109d301528181610ca601528181610f3a0152818161104501528181611790015261357001526151376000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806381ff7048116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610560578063e4ddcea614610573578063f2fde38b1461058957600080fd5b8063c3f909d4146103b0578063d227d24514610528578063d328a91e1461055857600080fd5b8063a631571e116100bd578063a631571e1461035d578063afcb95d71461037d578063b1dc65a41461039d57600080fd5b806381ff7048146102b557806385b214cf146103225780638da5cb5b1461033557600080fd5b806366316d8d116101455780637f15e1661161011f5780637f15e16614610285578063814118341461029857806381f1b938146102ad57600080fd5b806366316d8d1461026257806379ba5097146102755780637d4807871461027d57600080fd5b8063181f5a7711610176578063181f5a77146101ba5780632a905ccc1461020c57806359b5b7ac1461022e57600080fd5b8063083a5466146101925780631112dadc146101a7575b600080fd5b6101a56101a0366004613aad565b61059c565b005b6101a56101b5366004613c56565b6105f1565b6101f66040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e322e300000000081525081565b6040516102039190613d7a565b60405180910390f35b610214610841565b60405168ffffffffffffffffff9091168152602001610203565b61021461023c366004613e1b565b50600854700100000000000000000000000000000000900468ffffffffffffffffff1690565b6101a5610270366004613eaa565b6108d7565b6101a5610a90565b6101a5610b92565b6101a5610293366004613aad565b610d92565b6102a0610de2565b6040516102039190613f34565b6101f6610e51565b6102ff60015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610203565b6101a5610330366004613f47565b610f22565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b61037061036b366004613f60565b610fd4565b60405161020391906140b5565b604080516001815260006020820181905291810191909152606001610203565b6101a56103ab366004614109565b611175565b61051b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830152700100000000000000000000000000000000810468ffffffffffffffffff166080830152790100000000000000000000000000000000000000000000000000810464ffffffffff1660a08301527e01000000000000000000000000000000000000000000000000000000000000900461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08301527c0100000000000000000000000000000000000000000000000000000000900490911661010082015290565b60405161020391906141c0565b61053b6105363660046142b0565b61178c565b6040516bffffffffffffffffffffffff9091168152602001610203565b6101f66118ec565b6101a561056e3660046143c9565b611943565b61057b6124bf565b604051908152602001610203565b6101a5610597366004614496565b612718565b6105a461272c565b60008190036105df576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105ec82848361454c565b505050565b6105f96127af565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff64ffffffffff909216790100000000000000000000000000000000000000000000000000027fffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90941670010000000000000000000000000000000002939093167fffff0000000000000000000000000000ffffffffffffffffffffffffffffffff63ffffffff9586166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9787166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e08301516101008401519092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906108369083906141c0565b60405180910390a150565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d29190614672565b905090565b6108df6127b7565b806bffffffffffffffffffffffff166000036109195750336000908152600a60205260409020546bffffffffffffffffffffffff16610973565b336000908152600a60205260409020546bffffffffffffffffffffffff80831691161015610973576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906109a09084906bffffffffffffffffffffffff166146be565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506109f57f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610a7457600080fd5b505af1158015610a88573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b9a6127af565b610ba26127b7565b6000610bac610de2565b905060005b8151811015610d8e576000600a6000848481518110610bd257610bd26146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610d7d576000600a6000858581518110610c3157610c316146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610cc87f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610cf557610cf56146e3565b6020026020010151836040518363ffffffff1660e01b8152600401610d4a92919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d6457600080fd5b505af1158015610d78573d6000803e3d6000fd5b505050505b50610d8781614712565b9050610bb1565b5050565b610d9a61272c565b6000819003610dd5576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105ec82848361454c565b60606006805480602002602001604051908101604052809291908181526020018280548015610e4757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e1c575b5050505050905090565b6060600d8054610e60906144b3565b9050600003610e9b576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610ea8906144b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed4906144b3565b8015610e475780601f10610ef657610100808354040283529160200191610e47565b820191906000526020600020905b815481529060010190602001808311610f0457509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f91576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416906108369083815260200190565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461109c576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110ad6110a88361474a565b612963565b90506110bf6060830160408401614496565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261110d60c0870160a08801614837565b61111f61016088016101408901614496565b6111298880614854565b61113b6101208b016101008c016148b9565b60208b01356111516101008d0160e08e016148d4565b8b604051611167999897969594939291906148f1565b60405180910390a35b919050565b6000806111828989612e01565b915091508115611193575050611782565b604080518b3580825262ffffff6020808f0135600881901c9290921690840152909290917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16111f08b8b8b8b8b8b612f8a565b60035460009060029061120e9060ff80821691610100900416614999565b61121891906149e1565b611223906001614999565b60ff169050888114611291576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610b0d565b888714611320576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f7265706f727420727320616e64207373206d757374206265206f66206571756160448201527f6c206c656e6774680000000000000000000000000000000000000000000000006064820152608401610b0d565b3360009081526004602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561136357611363614a03565b600281111561137457611374614a03565b905250905060028160200151600281111561139157611391614a03565b141580156113da57506006816000015160ff16815481106113b4576113b46146e3565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b15611441576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610b0d565b5050505061144d613a4c565b60008a8a60405161145f929190614a32565b604051908190038120611476918e90602001614a42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117725760006001848984602081106114df576114df6146e3565b6114ec91901a601b614999565b8e8e868181106114fe576114fe6146e3565b905060200201358d8d87818110611517576115176146e3565b9050602002013560405160008152602001604052604051611554949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611576573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156115f6576115f6614a03565b600281111561160757611607614a03565b905250925060018360200151600281111561162457611624614a03565b1461168b576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610b0d565b8251600090869060ff16601f81106116a5576116a56146e3565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611727576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610b0d565b8085846000015160ff16601f8110611741576117416146e3565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201525061176b81614712565b90506114c0565b50505061177e82613041565b5050505b5050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b15801561182c57600080fd5b505afa158015611840573d6000803e3d6000fd5b5050505066038d7ea4c68000821115611885576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061188f610841565b905060006118d287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061023c92505050565b90506118e085858385613190565b98975050505050505050565b6060600c80546118fb906144b3565b9050600003611936576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610ea8906144b3565b855185518560ff16601f8311156119b6576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610b0d565b80600003611a20576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610b0d565b818314611aae576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610b0d565b611ab9816003614a56565b8311611b21576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610b0d565b611b2961272c565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611b7090886132fd565b60055415611d2557600554600090611b8a90600190614a6d565b9050600060058281548110611ba157611ba16146e3565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611bdb57611bdb6146e3565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611c5b57611c5b614a80565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611cc457611cc4614a80565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611b70915050565b60005b8151518110156122dc57815180516000919083908110611d4a57611d4a6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611dcf576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7369676e6572206d757374206e6f7420626520656d70747900000000000000006044820152606401610b0d565b600073ffffffffffffffffffffffffffffffffffffffff1682602001518281518110611dfd57611dfd6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611e82576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d7074790000006044820152606401610b0d565b60006004600084600001518481518110611e9e57611e9e6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611ee857611ee8614a03565b14611f4f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610b0d565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611f8057611f806146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561202157612021614a03565b0217905550600091506120319050565b600460008460200151848151811061204b5761204b6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561209557612095614a03565b146120fc576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610b0d565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061212f5761212f6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156121d0576121d0614a03565b0217905550508251805160059250839081106121ee576121ee6146e3565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600691908390811061226a5761226a6146e3565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055806122d481614712565b915050611d28565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161239491849174010000000000000000000000000000000000000000900416614aaf565b92506101000a81548163ffffffff021916908363ffffffff1602179055506123f34630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613316565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986124aa988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614acc565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000080830482166060850152700100000000000000000000000000000000830468ffffffffffffffffff166080850152790100000000000000000000000000000000000000000000000000830464ffffffffff1660a0808601919091527e0100000000000000000000000000000000000000000000000000000000000090930461ffff1660c08501526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08601527c01000000000000000000000000000000000000000000000000000000009004909116610100840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa15801561264d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126719190614b7c565b5093505092505080426126849190614a6d565b836020015163ffffffff161080156126a657506000836020015163ffffffff16115b156126d457505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b60008213612711576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610b0d565b5092915050565b61272061272c565b612729816133c1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146127ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b0d565b565b6127ad61272c565b600b546bffffffffffffffffffffffff166000036127d157565b60006127db610de2565b8051909150600081900361281b576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b5460009061283a9083906bffffffffffffffffffffffff16614bcc565b905060005b828110156129055781600a600086848151811061285e5761285e6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166128c69190614bf7565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806128fe90614712565b905061283f565b506129108282614c1c565b600b80546000906129309084906bffffffffffffffffffffffff166146be565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c0100000000000000000000000081048316606083015268ffffffffffffffffff700100000000000000000000000000000000820416608083015264ffffffffff79010000000000000000000000000000000000000000000000000082041660a083015261ffff7e01000000000000000000000000000000000000000000000000000000000000909104811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08501527c0100000000000000000000000000000000000000000000000000000000900490931661010080840191909152850151919291161115612b1e576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854600090700100000000000000000000000000000000900468ffffffffffffffffff1690506000612b5b8560e001513a848860800151613190565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612bb7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083610100015163ffffffff1642612bd09190614c44565b905060003087604001518860a001518960c001516001612bf09190614c57565b8a5180516020918201206101008d015160e08e0151604051612ca498979695948c918c9132910173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a015267ffffffffffffffff97881660408a0152959096166060880152608087019390935261ffff9190911660a086015263ffffffff90811660c08601526bffffffffffffffffffffffff9190911660e0850152919091166101008301529091166101208201526101400190565b6040516020818303038152906040528051906020012090506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001846bffffffffffffffffffffffff168152602001886040015173ffffffffffffffffffffffffffffffffffffffff1681526020018860a0015167ffffffffffffffff1681526020018860e0015163ffffffff168152602001886080015168ffffffffffffffffff1681526020018568ffffffffffffffffff168152602001866040015163ffffffff1664ffffffffff168152602001866060015163ffffffff1664ffffffffff1681526020018363ffffffff16815250955085604051602001612db391906140b5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009384526007909252909120555092949350505050565b6000612e356040518060a0016040528060608152602001606081526020016060815260200160608152602001606081525090565b600080808080612e47888a018a614d53565b84519499509297509095509350915060ff16801580612e67575084518114155b80612e73575083518114155b80612e7f575082518114155b80612e8b575081518114155b15612ef2576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4669656c6473206d75737420626520657175616c206c656e67746800000000006044820152606401610b0d565b60005b81811015612f5857612f2e878281518110612f1257612f126146e3565b6020026020010151600090815260076020526040902054151590565b612f5857612f3d600183614a6d565b8103612f4857600198505b612f5181614712565b9050612ef5565b50506040805160a0810182529586526020860194909452928401919091526060830152608082015290505b9250929050565b6000612f97826020614a56565b612fa2856020614a56565b612fae88610144614c44565b612fb89190614c44565b612fc29190614c44565b612fcd906000614c44565b9050368114613038576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610b0d565b50505050505050565b80515160ff1660005b818110156105ec5760006130f38460000151838151811061306d5761306d6146e3565b60200260200101518560200151848151811061308b5761308b6146e3565b6020026020010151866040015185815181106130a9576130a96146e3565b6020026020010151876060015186815181106130c7576130c76146e3565b6020026020010151886080015187815181106130e5576130e56146e3565b6020026020010151886134b6565b9050600081600681111561310957613109614a03565b14806131265750600181600681111561312457613124614a03565b145b1561317f57835180518390811061313f5761313f6146e3565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b5061318981614712565b905061304a565b600854600090790100000000000000000000000000000000000000000000000000900464ffffffffff168410156131eb57600854790100000000000000000000000000000000000000000000000000900464ffffffffff1693505b600854600090612710906132059063ffffffff1687614a56565b61320f9190614e25565b6132199086614c44565b60085490915060009087906132529063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614aaf565b61325c9190614aaf565b63ffffffff16905060006132a66000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137ca92505050565b905060006132c7826132b88587614a56565b6132c29190614c44565b61390c565b905060006132e368ffffffffffffffffff808916908a16614bf7565b90506132ef8183614bf7565b9a9950505050505050505050565b6000613307610de2565b511115610d8e57610d8e6127b7565b6000808a8a8a8a8a8a8a8a8a60405160200161333a99989796959493929190614e39565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b0d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080848060200190518101906134cd9190614f05565b905060003a8261012001518361010001516134e89190614fcd565b64ffffffffff166134f99190614a56565b905060008460ff166135416000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137ca92505050565b61354b9190614e25565b9050600061355c6132c28385614c44565b905060006135693a61390c565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298e8e868b60e0015168ffffffffffffffffff16896135c89190614bf7565b338d6040518763ffffffff1660e01b81526004016135eb96959493929190614feb565b60408051808303816000875af1158015613609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362d9190615067565b9092509050600082600681111561364657613646614a03565b14806136635750600182600681111561366157613661614a03565b145b156137b95760008e8152600760205260408120556136818185614bf7565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0890151600b805468ffffffffffffffffff909216939092916136ed91859116614bf7565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508d7f90815c2e624694e8010bffad2bcefaf96af282ef1bc2ebc0042d1b89a585e0468487848b60c0015168ffffffffffffffffff168c60e0015168ffffffffffffffffff16878b61376c9190614bf7565b6137769190614bf7565b6137809190614bf7565b604080516bffffffffffffffffffffffff9586168152602081019490945291841683830152909216606082015290519081900360800190a25b509c9b505050505050505050505050565b6000466137d681613940565b1561385257606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384b919061509a565b9392505050565b61385b81613963565b156139035773420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e846040518060800160405280604881526020016150e3604891396040516020016138bb9291906150b3565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016138e69190613d7a565b602060405180830381865afa158015613827573d6000803e3d6000fd5b50600092915050565b600061393a6139196124bf565b61392b84670de0b6b3a7640000614a56565b6139359190614e25565b6139aa565b92915050565b600061a4b1821480613954575062066eed82145b8061393a57505062066eee1490565b6000600a82148061397557506101a482145b80613982575062aa37dc82145b8061398e575061210582145b8061399b575062014a3382145b8061393a57505062014a341490565b60006bffffffffffffffffffffffff821115613a48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610b0d565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f840112613a7d57600080fd5b50813567ffffffffffffffff811115613a9557600080fd5b602083019150836020828501011115612f8357600080fd5b60008060208385031215613ac057600080fd5b823567ffffffffffffffff811115613ad757600080fd5b613ae385828601613a6b565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715613b4257613b42613aef565b60405290565b604051610160810167ffffffffffffffff81118282101715613b4257613b42613aef565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bb357613bb3613aef565b604052919050565b63ffffffff8116811461272957600080fd5b803561117081613bbb565b68ffffffffffffffffff8116811461272957600080fd5b803561117081613bd8565b64ffffffffff8116811461272957600080fd5b803561117081613bfa565b803561ffff8116811461117057600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461117057600080fd5b60006101208284031215613c6957600080fd5b613c71613b1e565b613c7a83613bcd565b8152613c8860208401613bcd565b6020820152613c9960408401613bcd565b6040820152613caa60608401613bcd565b6060820152613cbb60808401613bef565b6080820152613ccc60a08401613c0d565b60a0820152613cdd60c08401613c18565b60c0820152613cee60e08401613c2a565b60e0820152610100613d01818501613bcd565b908201529392505050565b60005b83811015613d27578181015183820152602001613d0f565b50506000910152565b60008151808452613d48816020860160208601613d0c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061384b6020830184613d30565b600082601f830112613d9e57600080fd5b813567ffffffffffffffff811115613db857613db8613aef565b613de960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613b6c565b818152846020838601011115613dfe57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e2d57600080fd5b813567ffffffffffffffff811115613e4457600080fd5b613e5084828501613d8d565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461272957600080fd5b803561117081613e58565b6bffffffffffffffffffffffff8116811461272957600080fd5b803561117081613e85565b60008060408385031215613ebd57600080fd5b8235613ec881613e58565b91506020830135613ed881613e85565b809150509250929050565b600081518084526020808501945080840160005b83811015613f2957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613ef7565b509495945050505050565b60208152600061384b6020830184613ee3565b600060208284031215613f5957600080fd5b5035919050565b600060208284031215613f7257600080fd5b813567ffffffffffffffff811115613f8957600080fd5b8201610160818503121561384b57600080fd5b805182526020810151613fc7602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613fe760408401826bffffffffffffffffffffffff169052565b50606081015161400f606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50608081015161402b608084018267ffffffffffffffff169052565b5060a081015161404360a084018263ffffffff169052565b5060c081015161406060c084018268ffffffffffffffffff169052565b5060e081015161407d60e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161393a8284613f9c565b60008083601f8401126140d657600080fd5b50813567ffffffffffffffff8111156140ee57600080fd5b6020830191508360208260051b8501011115612f8357600080fd5b60008060008060008060008060e0898b03121561412557600080fd5b606089018a81111561413657600080fd5b8998503567ffffffffffffffff8082111561415057600080fd5b61415c8c838d01613a6b565b909950975060808b013591508082111561417557600080fd5b6141818c838d016140c4565b909750955060a08b013591508082111561419a57600080fd5b506141a78b828c016140c4565b999c989b50969995989497949560c00135949350505050565b815163ffffffff908116825260208084015182169083015260408084015182169083015260608084015191821690830152610120820190506080830151614214608084018268ffffffffffffffffff169052565b5060a083015161422d60a084018264ffffffffff169052565b5060c083015161424360c084018261ffff169052565b5060e083015161427360e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b506101008381015163ffffffff8116848301525b505092915050565b67ffffffffffffffff8116811461272957600080fd5b80356111708161428f565b6000806000806000608086880312156142c857600080fd5b85356142d38161428f565b9450602086013567ffffffffffffffff8111156142ef57600080fd5b6142fb88828901613a6b565b909550935050604086013561430f81613bbb565b949793965091946060013592915050565b600067ffffffffffffffff82111561433a5761433a613aef565b5060051b60200190565b600082601f83011261435557600080fd5b8135602061436a61436583614320565b613b6c565b82815260059290921b8401810191818101908684111561438957600080fd5b8286015b848110156143ad5780356143a081613e58565b835291830191830161438d565b509695505050505050565b803560ff8116811461117057600080fd5b60008060008060008060c087890312156143e257600080fd5b863567ffffffffffffffff808211156143fa57600080fd5b6144068a838b01614344565b9750602089013591508082111561441c57600080fd5b6144288a838b01614344565b965061443660408a016143b8565b9550606089013591508082111561444c57600080fd5b6144588a838b01613d8d565b945061446660808a016142a5565b935060a089013591508082111561447c57600080fd5b5061448989828a01613d8d565b9150509295509295509295565b6000602082840312156144a857600080fd5b813561384b81613e58565b600181811c908216806144c757607f821691505b602082108103614500577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105ec57600081815260208120601f850160051c8101602086101561452d5750805b601f850160051c820191505b81811015610a8857828155600101614539565b67ffffffffffffffff83111561456457614564613aef565b6145788361457283546144b3565b83614506565b6000601f8411600181146145ca57600085156145945750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614660565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561461957868501358255602094850194600190920191016145f9565b5086821015614654577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b805161117081613bd8565b60006020828403121561468457600080fd5b815161384b81613bd8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8281168282160390808211156127115761271161468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036147435761474361468f565b5060010190565b6000610160823603121561475d57600080fd5b614765613b48565b823567ffffffffffffffff81111561477c57600080fd5b61478836828601613d8d565b825250602083013560208201526147a160408401613e7a565b60408201526147b260608401613e9f565b60608201526147c360808401613bef565b60808201526147d460a084016142a5565b60a08201526147e560c084016142a5565b60c08201526147f660e08401613bcd565b60e0820152610100614809818501613c18565b9082015261012061481b8482016142a5565b9082015261014061482d848201613e7a565b9082015292915050565b60006020828403121561484957600080fd5b813561384b8161428f565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261488957600080fd5b83018035915067ffffffffffffffff8211156148a457600080fd5b602001915036819003821315612f8357600080fd5b6000602082840312156148cb57600080fd5b61384b82613c18565b6000602082840312156148e657600080fd5b813561384b81613bbb565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01683010190506132ef60e0830184613f9c565b60ff818116838216019081111561393a5761393a61468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806149f4576149f46149b2565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761393a5761393a61468f565b8181038181111561393a5761393a61468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff8181168382160190808211156127115761271161468f565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614afc8184018a613ee3565b90508281036080840152614b108189613ee3565b905060ff871660a084015282810360c0840152614b2d8187613d30565b905067ffffffffffffffff851660e0840152828103610100840152614b528185613d30565b9c9b505050505050505050505050565b805169ffffffffffffffffffff8116811461117057600080fd5b600080600080600060a08688031215614b9457600080fd5b614b9d86614b62565b9450602086015193506040860151925060608601519150614bc060808701614b62565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614beb57614beb6149b2565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156127115761271161468f565b6bffffffffffffffffffffffff8181168382160280821691908281146142875761428761468f565b8082018082111561393a5761393a61468f565b67ffffffffffffffff8181168382160190808211156127115761271161468f565b600082601f830112614c8957600080fd5b81356020614c9961436583614320565b82815260059290921b84018101918181019086841115614cb857600080fd5b8286015b848110156143ad5780358352918301918301614cbc565b600082601f830112614ce457600080fd5b81356020614cf461436583614320565b82815260059290921b84018101918181019086841115614d1357600080fd5b8286015b848110156143ad57803567ffffffffffffffff811115614d375760008081fd5b614d458986838b0101613d8d565b845250918301918301614d17565b600080600080600060a08688031215614d6b57600080fd5b853567ffffffffffffffff80821115614d8357600080fd5b614d8f89838a01614c78565b96506020880135915080821115614da557600080fd5b614db189838a01614cd3565b95506040880135915080821115614dc757600080fd5b614dd389838a01614cd3565b94506060880135915080821115614de957600080fd5b614df589838a01614cd3565b93506080880135915080821115614e0b57600080fd5b50614e1888828901614cd3565b9150509295509295909350565b600082614e3457614e346149b2565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614e808285018b613ee3565b91508382036080850152614e94828a613ee3565b915060ff881660a085015283820360c0850152614eb18288613d30565b90861660e08501528381036101008501529050614b528185613d30565b805161117081613e58565b805161117081613e85565b80516111708161428f565b805161117081613bbb565b805161117081613bfa565b60006101608284031215614f1857600080fd5b614f20613b48565b82518152614f3060208401614ece565b6020820152614f4160408401614ed9565b6040820152614f5260608401614ece565b6060820152614f6360808401614ee4565b6080820152614f7460a08401614eef565b60a0820152614f8560c08401614667565b60c0820152614f9660e08401614667565b60e0820152610100614fa9818501614efa565b90820152610120614fbb848201614efa565b90820152610140613d01848201614eef565b64ffffffffff8181168382160190808211156127115761271161468f565b6000610200808352614fff8184018a613d30565b905082810360208401526150138189613d30565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff86166080850152915061505c905060a0830184613f9c565b979650505050505050565b6000806040838503121561507a57600080fd5b82516007811061508957600080fd5b6020840151909250613ed881613e85565b6000602082840312156150ac57600080fd5b5051919050565b600083516150c5818460208801613d0c565b8351908301906150d9818360208801613d0c565b0194935050505056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 16bb718e7c1..e3e20993f78 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -4,7 +4,7 @@ functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServ functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.bin 7e8a63d56d81fe16a51d4196f5ca3e9623eaa04b56a6e8d7dee1eb0c266944ab +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.bin 9686bdf83a0ce09ad07e81f6af52889735ea5af5709ffd018bb7b75e5d284c5e functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsLoadTestClient.bin c8dbbd5ebb34435800d6674700068837c3a252db60046a14b0e61e829db517de functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c functions_router: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRouter.bin 1f6d18f9e0846ad74b37a0a6acef5942ab73ace1e84307f201899f69e732e776 From 21c1ae8867fa3edac3822059f2b2ce1867c77ef0 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Thu, 15 Feb 2024 18:34:31 -0500 Subject: [PATCH 42/98] (feat): Add ability for Functions ToS migrations (#11827) --- .../gas-snapshots/functions.gas-snapshot | 50 +++++++++---------- .../accessControl/TermsOfServiceAllowList.sol | 18 ++++++- .../src/v0.8/functions/tests/v1_X/Setup.t.sol | 8 ++- contracts/test/v0.8/functions/v1/utils.ts | 4 +- .../functions_allow_list.go | 8 +-- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../v1/internal/testutils.go | 4 +- 7 files changed, 60 insertions(+), 34 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index ab6a4933e69..279aa389e4f 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,12 +1,12 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14859450) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14859428) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14859444) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14870866) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14870843) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14870815) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14870766) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14870755) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14870799) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14860808) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14860786) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14860802) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14872224) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14872201) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14872173) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14872124) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14872113) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14872157) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) @@ -50,17 +50,17 @@ FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 246) FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 223) FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 225) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12007) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 169845) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 160176) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 169829) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 160160) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38115) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35238) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 178321) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 178305) FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28086) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 153883) -FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321333) -FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334954) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2510380) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540815) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 153867) +FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321317) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334938) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2510364) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540803) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17983) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12904) FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 37159) @@ -165,7 +165,7 @@ FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddres FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54413) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14981) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 176494) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 176478) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27655) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57797) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15001) @@ -181,7 +181,7 @@ FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 102439) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87245) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18049) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191902) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191894) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42023) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12891) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684) @@ -193,7 +193,7 @@ FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 5775 FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26434) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152708) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94864) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94913) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25859) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 88990) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23619) @@ -206,25 +206,25 @@ FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 96 FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12253) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19199) FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 12995) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12237753) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12239111) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16571) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13301) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20448) FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 12931) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12237757) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12239115) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18493) FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15751) FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11593) FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15969) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23496) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23560) FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15445) FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 86643) FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13502) FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96216) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13749) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22073) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13824) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22183) Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79131) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol index 3d93a3fef04..fe4ebe983ef 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol @@ -39,8 +39,24 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // | Initialization | // ================================================================ - constructor(TermsOfServiceAllowListConfig memory config) ConfirmedOwner(msg.sender) { + constructor( + TermsOfServiceAllowListConfig memory config, + address[] memory initialAllowedSenders, + address[] memory initialBlockedSenders + ) ConfirmedOwner(msg.sender) { updateConfig(config); + + for (uint256 i = 0; i < initialAllowedSenders.length; ++i) { + s_allowedSenders.add(initialAllowedSenders[i]); + } + + for (uint256 j = 0; j < initialBlockedSenders.length; ++j) { + if (s_allowedSenders.contains(initialBlockedSenders[j])) { + // Allowed senders cannot also be blocked + revert InvalidCalldata(); + } + s_blockedSenders.add(initialBlockedSenders[j]); + } } // ================================================================ diff --git a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol index 0e131f9b89c..296e61c040c 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol @@ -45,7 +45,13 @@ contract FunctionsRouterSetup is BaseTest { getCoordinatorConfig(), address(s_linkEthFeed) ); - s_termsOfServiceAllowList = new TermsOfServiceAllowList(getTermsOfServiceConfig()); + address[] memory initialAllowedSenders; + address[] memory initialBlockedSenders; + s_termsOfServiceAllowList = new TermsOfServiceAllowList( + getTermsOfServiceConfig(), + initialAllowedSenders, + initialBlockedSenders + ); } function getRouterConfig() public view returns (FunctionsRouter.Config memory) { diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts index b91905b9448..ffe5468f136 100644 --- a/contracts/test/v0.8/functions/v1/utils.ts +++ b/contracts/test/v0.8/functions/v1/utils.ts @@ -257,9 +257,11 @@ export function getSetupFactory(): () => { .connect(roles.defaultAccount) .deploy(router.address, coordinatorConfig, mockLinkEth.address) + const initialAllowedSenders: string[] = [] + const initialBlockedSenders: string[] = [] const accessControl = await factories.accessControlFactory .connect(roles.defaultAccount) - .deploy(accessControlConfig) + .deploy(accessControlConfig, initialAllowedSenders, initialBlockedSenders) const client = await factories.clientTestHelperFactory .connect(roles.consumer) diff --git a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go index ff15cc75d41..023956b7314 100644 --- a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go +++ b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go @@ -36,15 +36,15 @@ type TermsOfServiceAllowListConfig struct { } var TermsOfServiceAllowListMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getBlockedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blockedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040516200173438038062001734833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160068054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b61143a80620002fa6000396000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063817ef62e116100b2578063a39b06e311610081578063c3f909d411610066578063c3f909d4146102c3578063cc7ebf4914610322578063f2fde38b1461032a57600080fd5b8063a39b06e314610237578063a5e1d61d146102b057600080fd5b8063817ef62e146101e157806382184c7b146101e957806389f9a2c4146101fc5780638da5cb5b1461020f57600080fd5b80633908c4d4116100ee5780633908c4d41461018e57806347663acb146101a35780636b14daf8146101b657806379ba5097146101d957600080fd5b806301a05958146101205780630a8c9c2414610146578063181f5a771461016657806320229a861461017b575b600080fd5b61012861033d565b60405167ffffffffffffffff90911681526020015b60405180910390f35b610159610154366004610fd6565b61034e565b60405161013d9190611009565b61016e6104bc565b60405161013d9190611063565b610159610189366004610fd6565b6104d8565b6101a161019c3660046110f3565b61063e565b005b6101a16101b1366004611154565b6108e9565b6101c96101c436600461116f565b61094a565b604051901515815260200161013d565b6101a1610974565b610159610a76565b6101a16101f7366004611154565b610a82565b6101a161020a366004611221565b610ae8565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013d565b6102a26102453660046112aa565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161013d565b6101c96102be366004611154565b610ba3565b60408051808201825260008082526020918201528151808301835260065460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161013d565b610128610bc3565b6101a1610338366004611154565b610bcf565b60006103496004610be3565b905090565b60608167ffffffffffffffff168367ffffffffffffffff16118061038557506103776002610be3565b8267ffffffffffffffff1610155b8061039757506103956002610be3565b155b156103ce576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103d88383611303565b6103e3906001611324565b67ffffffffffffffff1667ffffffffffffffff811115610405576104056111f2565b60405190808252806020026020018201604052801561042e578160200160208202803683370190505b50905060005b61043e8484611303565b67ffffffffffffffff1681116104b45761046d6104658267ffffffffffffffff8716611345565b600290610bed565b82828151811061047f5761047f611358565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526104ad81611387565b9050610434565b505b92915050565b6040518060600160405280602c8152602001611402602c913981565b60608167ffffffffffffffff168367ffffffffffffffff16118061050f57506105016004610be3565b8267ffffffffffffffff1610155b80610521575061051f6004610be3565b155b15610558576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105628383611303565b61056d906001611324565b67ffffffffffffffff1667ffffffffffffffff81111561058f5761058f6111f2565b6040519080825280602002602001820160405280156105b8578160200160208202803683370190505b50905060005b6105c88484611303565b67ffffffffffffffff1681116104b4576105f76105ef8267ffffffffffffffff8716611345565b600490610bed565b82828151811061060957610609611358565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261063781611387565b90506105be565b610649600485610bf9565b15610680576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206006546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa1580156107b4573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff161461080b576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061085057503373ffffffffffffffffffffffffffffffffffffffff8716148015906108505750333b155b15610887576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610892600286610c28565b156108e15760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b6108f1610c4a565b6108fc600482610ccd565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b906020015b60405180910390a150565b60065460009060ff1661095f5750600161096d565b61096a600285610bf9565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606103496002610cef565b610a8a610c4a565b610a95600282610ccd565b50610aa1600482610c28565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e19060200161093f565b610af0610c4a565b805160068054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910161093f565b60065460009060ff16610bb857506000919050565b6104b6600483610bf9565b60006103496002610be3565b610bd7610c4a565b610be081610cfc565b50565b60006104b6825490565b600061096d8383610df1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561096d565b600061096d8373ffffffffffffffffffffffffffffffffffffffff8416610e1b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ccb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109f1565b565b600061096d8373ffffffffffffffffffffffffffffffffffffffff8416610e6a565b6060600061096d83610f5d565b3373ffffffffffffffffffffffffffffffffffffffff821603610d7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610e0857610e08611358565b9060005260206000200154905092915050565b6000818152600183016020526040812054610e62575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104b6565b5060006104b6565b60008181526001830160205260408120548015610f53576000610e8e6001836113bf565b8554909150600090610ea2906001906113bf565b9050818114610f07576000866000018281548110610ec257610ec2611358565b9060005260206000200154905080876000018481548110610ee557610ee5611358565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610f1857610f186113d2565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104b6565b60009150506104b6565b606081600001805480602002602001604051908101604052809291908181526020018280548015610fad57602002820191906000526020600020905b815481526020019060010190808311610f99575b50505050509050919050565b803567ffffffffffffffff81168114610fd157600080fd5b919050565b60008060408385031215610fe957600080fd5b610ff283610fb9565b915061100060208401610fb9565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561105757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611025565b50909695505050505050565b600060208083528351808285015260005b8181101561109057858101830151858201604001528201611074565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610fd157600080fd5b600080600080600060a0868803121561110b57600080fd5b611114866110cf565b9450611122602087016110cf565b93506040860135925060608601359150608086013560ff8116811461114657600080fd5b809150509295509295909350565b60006020828403121561116657600080fd5b61096d826110cf565b60008060006040848603121561118457600080fd5b61118d846110cf565b9250602084013567ffffffffffffffff808211156111aa57600080fd5b818601915086601f8301126111be57600080fd5b8135818111156111cd57600080fd5b8760208285010111156111df57600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561123357600080fd5b6040516040810181811067ffffffffffffffff8211171561127d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461129057600080fd5b815261129e602084016110cf565b60208201529392505050565b600080604083850312156112bd57600080fd5b6112c6836110cf565b9150611000602084016110cf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8281168282160390808211156104b4576104b46112d4565b67ffffffffffffffff8181168382160190808211156104b4576104b46112d4565b808201808211156104b6576104b66112d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113b8576113b86112d4565b5060010190565b818103818111156104b6576104b66112d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"initialAllowedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"initialBlockedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getBlockedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blockedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162001a3038038062001a308339810160408190526200003491620004d9565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620001d4565b505050620000d2836200027f60201b60201c565b60005b8251811015620001255762000111838281518110620000f857620000f8620005a8565b602002602001015160026200030660201b90919060201c565b506200011d81620005be565b9050620000d5565b5060005b8151811015620001ca57620001658282815181106200014c576200014c620005a8565b602002602001015160026200032660201b90919060201c565b156200018457604051638129bbcd60e01b815260040160405180910390fd5b620001b68282815181106200019d576200019d620005a8565b602002602001015160046200030660201b90919060201c565b50620001c281620005be565b905062000129565b50505050620005e6565b336001600160a01b038216036200022e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200028962000349565b805160068054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b60006200031d836001600160a01b038416620003a7565b90505b92915050565b6001600160a01b038116600090815260018301602052604081205415156200031d565b6000546001600160a01b03163314620003a55760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000818152600183016020526040812054620003f05750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000320565b50600062000320565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200042757600080fd5b919050565b600082601f8301126200043e57600080fd5b815160206001600160401b03808311156200045d576200045d620003f9565b8260051b604051601f19603f83011681018181108482111715620004855762000485620003f9565b604052938452858101830193838101925087851115620004a457600080fd5b83870191505b84821015620004ce57620004be826200040f565b83529183019190830190620004aa565b979650505050505050565b60008060008385036080811215620004f057600080fd5b6040811215620004ff57600080fd5b50604080519081016001600160401b038082118383101715620005265762000526620003f9565b816040528651915081151582146200053d57600080fd5b8183526200054e602088016200040f565b60208401526040870151929550808311156200056957600080fd5b62000577888489016200042c565b945060608701519250808311156200058e57600080fd5b50506200059e868287016200042c565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600060018201620005df57634e487b7160e01b600052601160045260246000fd5b5060010190565b61143a80620005f66000396000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063817ef62e116100b2578063a39b06e311610081578063c3f909d411610066578063c3f909d4146102c3578063cc7ebf4914610322578063f2fde38b1461032a57600080fd5b8063a39b06e314610237578063a5e1d61d146102b057600080fd5b8063817ef62e146101e157806382184c7b146101e957806389f9a2c4146101fc5780638da5cb5b1461020f57600080fd5b80633908c4d4116100ee5780633908c4d41461018e57806347663acb146101a35780636b14daf8146101b657806379ba5097146101d957600080fd5b806301a05958146101205780630a8c9c2414610146578063181f5a771461016657806320229a861461017b575b600080fd5b61012861033d565b60405167ffffffffffffffff90911681526020015b60405180910390f35b610159610154366004610fd6565b61034e565b60405161013d9190611009565b61016e6104bc565b60405161013d9190611063565b610159610189366004610fd6565b6104d8565b6101a161019c3660046110f3565b61063e565b005b6101a16101b1366004611154565b6108e9565b6101c96101c436600461116f565b61094a565b604051901515815260200161013d565b6101a1610974565b610159610a76565b6101a16101f7366004611154565b610a82565b6101a161020a366004611221565b610ae8565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013d565b6102a26102453660046112aa565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161013d565b6101c96102be366004611154565b610ba3565b60408051808201825260008082526020918201528151808301835260065460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161013d565b610128610bc3565b6101a1610338366004611154565b610bcf565b60006103496004610be3565b905090565b60608167ffffffffffffffff168367ffffffffffffffff16118061038557506103776002610be3565b8267ffffffffffffffff1610155b8061039757506103956002610be3565b155b156103ce576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103d88383611303565b6103e3906001611324565b67ffffffffffffffff1667ffffffffffffffff811115610405576104056111f2565b60405190808252806020026020018201604052801561042e578160200160208202803683370190505b50905060005b61043e8484611303565b67ffffffffffffffff1681116104b45761046d6104658267ffffffffffffffff8716611345565b600290610bed565b82828151811061047f5761047f611358565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526104ad81611387565b9050610434565b505b92915050565b6040518060600160405280602c8152602001611402602c913981565b60608167ffffffffffffffff168367ffffffffffffffff16118061050f57506105016004610be3565b8267ffffffffffffffff1610155b80610521575061051f6004610be3565b155b15610558576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105628383611303565b61056d906001611324565b67ffffffffffffffff1667ffffffffffffffff81111561058f5761058f6111f2565b6040519080825280602002602001820160405280156105b8578160200160208202803683370190505b50905060005b6105c88484611303565b67ffffffffffffffff1681116104b4576105f76105ef8267ffffffffffffffff8716611345565b600490610bed565b82828151811061060957610609611358565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261063781611387565b90506105be565b610649600485610bf9565b15610680576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206006546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa1580156107b4573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff161461080b576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061085057503373ffffffffffffffffffffffffffffffffffffffff8716148015906108505750333b155b15610887576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610892600286610c28565b156108e15760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b6108f1610c4a565b6108fc600482610ccd565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b906020015b60405180910390a150565b60065460009060ff1661095f5750600161096d565b61096a600285610bf9565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606103496002610cef565b610a8a610c4a565b610a95600282610ccd565b50610aa1600482610c28565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e19060200161093f565b610af0610c4a565b805160068054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910161093f565b60065460009060ff16610bb857506000919050565b6104b6600483610bf9565b60006103496002610be3565b610bd7610c4a565b610be081610cfc565b50565b60006104b6825490565b600061096d8383610df1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561096d565b600061096d8373ffffffffffffffffffffffffffffffffffffffff8416610e1b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ccb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109f1565b565b600061096d8373ffffffffffffffffffffffffffffffffffffffff8416610e6a565b6060600061096d83610f5d565b3373ffffffffffffffffffffffffffffffffffffffff821603610d7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610e0857610e08611358565b9060005260206000200154905092915050565b6000818152600183016020526040812054610e62575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104b6565b5060006104b6565b60008181526001830160205260408120548015610f53576000610e8e6001836113bf565b8554909150600090610ea2906001906113bf565b9050818114610f07576000866000018281548110610ec257610ec2611358565b9060005260206000200154905080876000018481548110610ee557610ee5611358565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610f1857610f186113d2565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104b6565b60009150506104b6565b606081600001805480602002602001604051908101604052809291908181526020018280548015610fad57602002820191906000526020600020905b815481526020019060010190808311610f99575b50505050509050919050565b803567ffffffffffffffff81168114610fd157600080fd5b919050565b60008060408385031215610fe957600080fd5b610ff283610fb9565b915061100060208401610fb9565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561105757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611025565b50909695505050505050565b600060208083528351808285015260005b8181101561109057858101830151858201604001528201611074565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610fd157600080fd5b600080600080600060a0868803121561110b57600080fd5b611114866110cf565b9450611122602087016110cf565b93506040860135925060608601359150608086013560ff8116811461114657600080fd5b809150509295509295909350565b60006020828403121561116657600080fd5b61096d826110cf565b60008060006040848603121561118457600080fd5b61118d846110cf565b9250602084013567ffffffffffffffff808211156111aa57600080fd5b818601915086601f8301126111be57600080fd5b8135818111156111cd57600080fd5b8760208285010111156111df57600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561123357600080fd5b6040516040810181811067ffffffffffffffff8211171561127d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461129057600080fd5b815261129e602084016110cf565b60208201529392505050565b600080604083850312156112bd57600080fd5b6112c6836110cf565b9150611000602084016110cf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8281168282160390808211156104b4576104b46112d4565b67ffffffffffffffff8181168382160190808211156104b4576104b46112d4565b808201808211156104b6576104b66112d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113b8576113b86112d4565b5060010190565b818103818111156104b6576104b66112d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", } var TermsOfServiceAllowListABI = TermsOfServiceAllowListMetaData.ABI var TermsOfServiceAllowListBin = TermsOfServiceAllowListMetaData.Bin -func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.ContractBackend, config TermsOfServiceAllowListConfig) (common.Address, *types.Transaction, *TermsOfServiceAllowList, error) { +func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.ContractBackend, config TermsOfServiceAllowListConfig, initialAllowedSenders []common.Address, initialBlockedSenders []common.Address) (common.Address, *types.Transaction, *TermsOfServiceAllowList, error) { parsed, err := TermsOfServiceAllowListMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -53,7 +53,7 @@ func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.Contrac return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TermsOfServiceAllowListBin), backend, config) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TermsOfServiceAllowListBin), backend, config, initialAllowedSenders, initialBlockedSenders) if err != nil { return common.Address{}, nil, nil, err } diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index e3e20993f78..102e377859c 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,6 +1,6 @@ GETH_VERSION: 1.13.8 functions: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db -functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 586696a0cacc0e5112bdd6c99535748a3fbf08c9319360aee868831d38a96d7b +functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 0c2156289e11f884ca6e92bf851192d3917c9094a0a301bcefa61266678d0e57 functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go index 5ea1d3e4030..7f75717feba 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -211,7 +211,9 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, Enabled: false, // TODO: true SignerPublicKey: proofSignerPublicKey, } - allowListAddress, _, allowListContract, err := functions_allow_list.DeployTermsOfServiceAllowList(owner, b, allowListConfig) + var initialAllowedSenders []common.Address + var initialBlockedSenders []common.Address + allowListAddress, _, allowListContract, err := functions_allow_list.DeployTermsOfServiceAllowList(owner, b, allowListConfig, initialAllowedSenders, initialBlockedSenders) require.NoError(t, err) // Deploy Coordinator contract (matches updateConfig() in FunctionsBilling.sol) From 187dafb507cf3db61e4f74dd14f30ad19a755d5b Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Thu, 15 Feb 2024 17:12:55 -0800 Subject: [PATCH 43/98] KS-35: EVM Encoder compatible with consensus capability (#12025) --- core/chains/evm/abi/selector_parser.go | 249 ++++++++++++++++++++ core/chains/evm/abi/selector_parser_test.go | 126 ++++++++++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/relay/evm/cap_encoder.go | 97 ++++++++ core/services/relay/evm/cap_encoder_test.go | 58 +++++ go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- 10 files changed, 539 insertions(+), 9 deletions(-) create mode 100644 core/chains/evm/abi/selector_parser.go create mode 100644 core/chains/evm/abi/selector_parser_test.go create mode 100644 core/services/relay/evm/cap_encoder.go create mode 100644 core/services/relay/evm/cap_encoder_test.go diff --git a/core/chains/evm/abi/selector_parser.go b/core/chains/evm/abi/selector_parser.go new file mode 100644 index 00000000000..30e687ba33a --- /dev/null +++ b/core/chains/evm/abi/selector_parser.go @@ -0,0 +1,249 @@ +// Sourced from https://github.com/ethereum/go-ethereum/blob/fe91d476ba3e29316b6dc99b6efd4a571481d888/accounts/abi/selector_parser.go#L126 +// Modified assembleArgs to retain argument names + +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package abi + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +func isDigit(c byte) bool { + return c >= '0' && c <= '9' +} + +func isAlpha(c byte) bool { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') +} + +func isIdentifierSymbol(c byte) bool { + return c == '$' || c == '_' +} + +func parseToken(unescapedSelector string, isIdent bool) (string, string, error) { + if len(unescapedSelector) == 0 { + return "", "", errors.New("empty token") + } + firstChar := unescapedSelector[0] + position := 1 + if !(isAlpha(firstChar) || (isIdent && isIdentifierSymbol(firstChar))) { + return "", "", fmt.Errorf("invalid token start: %c", firstChar) + } + for position < len(unescapedSelector) { + char := unescapedSelector[position] + if !(isAlpha(char) || isDigit(char) || (isIdent && isIdentifierSymbol(char))) { + break + } + position++ + } + return unescapedSelector[:position], unescapedSelector[position:], nil +} + +func parseIdentifier(unescapedSelector string) (string, string, error) { + return parseToken(unescapedSelector, true) +} + +func parseElementaryType(unescapedSelector string) (string, string, error) { + parsedType, rest, err := parseToken(unescapedSelector, false) + if err != nil { + return "", "", fmt.Errorf("failed to parse elementary type: %v", err) + } + // handle arrays + for len(rest) > 0 && rest[0] == '[' { + parsedType = parsedType + string(rest[0]) + rest = rest[1:] + for len(rest) > 0 && isDigit(rest[0]) { + parsedType = parsedType + string(rest[0]) + rest = rest[1:] + } + if len(rest) == 0 || rest[0] != ']' { + return "", "", fmt.Errorf("failed to parse array: expected ']', got %c", unescapedSelector[0]) + } + parsedType = parsedType + string(rest[0]) + rest = rest[1:] + } + return parsedType, rest, nil +} + +func parseCompositeType(unescapedSelector string) ([]interface{}, string, error) { + if len(unescapedSelector) == 0 || unescapedSelector[0] != '(' { + return nil, "", fmt.Errorf("expected '(', got %c", unescapedSelector[0]) + } + parsedType, rest, err := parseType(unescapedSelector[1:]) + if err != nil { + return nil, "", fmt.Errorf("failed to parse type: %v", err) + } + result := []interface{}{parsedType} + for len(rest) > 0 && rest[0] != ')' { + parsedType, rest, err = parseType(rest[1:]) + if err != nil { + return nil, "", fmt.Errorf("failed to parse type: %v", err) + } + result = append(result, parsedType) + } + if len(rest) == 0 || rest[0] != ')' { + return nil, "", fmt.Errorf("expected ')', got '%s'", rest) + } + if len(rest) >= 3 && rest[1] == '[' && rest[2] == ']' { + return append(result, "[]"), rest[3:], nil + } + return result, rest[1:], nil +} + +func parseType(unescapedSelector string) (interface{}, string, error) { + if len(unescapedSelector) == 0 { + return nil, "", errors.New("empty type") + } + if unescapedSelector[0] == '(' { + return parseCompositeType(unescapedSelector) + } + return parseElementaryType(unescapedSelector) +} + +func parseArgs(unescapedSelector string) ([]abi.ArgumentMarshaling, error) { + if len(unescapedSelector) == 0 || unescapedSelector[0] != '(' { + return nil, fmt.Errorf("expected '(', got %c", unescapedSelector[0]) + } + result := []abi.ArgumentMarshaling{} + rest := unescapedSelector[1:] + var parsedType any + var err error + for len(rest) > 0 && rest[0] != ')' { + // parse method name + var name string + name, rest, err = parseIdentifier(rest[:]) + if err != nil { + return nil, fmt.Errorf("failed to parse name: %v", err) + } + + // skip whitespace between name and identifier + for rest[0] == ' ' { + rest = rest[1:] + } + + // parse type + parsedType, rest, err = parseType(rest[:]) + if err != nil { + return nil, fmt.Errorf("failed to parse type: %v", err) + } + + arg, err := assembleArg(name, parsedType) + if err != nil { + return nil, fmt.Errorf("failed to parse type: %v", err) + } + + result = append(result, arg) + + for rest[0] == ' ' || rest[0] == ',' { + rest = rest[1:] + } + } + if len(rest) == 0 || rest[0] != ')' { + return nil, fmt.Errorf("expected ')', got '%s'", rest) + } + if len(rest) > 1 { + return nil, fmt.Errorf("failed to parse selector '%s': unexpected string '%s'", unescapedSelector, rest) + } + return result, nil +} + +func assembleArg(name string, arg any) (abi.ArgumentMarshaling, error) { + if s, ok := arg.(string); ok { + return abi.ArgumentMarshaling{Name: name, Type: s, InternalType: s, Components: nil, Indexed: false}, nil + } else if components, ok := arg.([]interface{}); ok { + subArgs, err := assembleArgs(components) + if err != nil { + return abi.ArgumentMarshaling{}, fmt.Errorf("failed to assemble components: %v", err) + } + tupleType := "tuple" + if len(subArgs) != 0 && subArgs[len(subArgs)-1].Type == "[]" { + subArgs = subArgs[:len(subArgs)-1] + tupleType = "tuple[]" + } + return abi.ArgumentMarshaling{Name: name, Type: tupleType, InternalType: tupleType, Components: subArgs, Indexed: false}, nil + } + return abi.ArgumentMarshaling{}, fmt.Errorf("failed to assemble args: unexpected type %T", arg) +} + +func assembleArgs(args []interface{}) ([]abi.ArgumentMarshaling, error) { + arguments := make([]abi.ArgumentMarshaling, 0) + for i, arg := range args { + // generate dummy name to avoid unmarshal issues + name := fmt.Sprintf("name%d", i) + arg, err := assembleArg(name, arg) + if err != nil { + return nil, err + } + arguments = append(arguments, arg) + } + return arguments, nil +} + +// ParseSelector converts a method selector into a struct that can be JSON encoded +// and consumed by other functions in this package. +// Note, although uppercase letters are not part of the ABI spec, this function +// still accepts it as the general format is valid. +func ParseSelector(unescapedSelector string) (abi.SelectorMarshaling, error) { + name, rest, err := parseIdentifier(unescapedSelector) + if err != nil { + return abi.SelectorMarshaling{}, fmt.Errorf("failed to parse selector '%s': %v", unescapedSelector, err) + } + args := []interface{}{} + if len(rest) >= 2 && rest[0] == '(' && rest[1] == ')' { + rest = rest[2:] + } else { + args, rest, err = parseCompositeType(rest) + if err != nil { + return abi.SelectorMarshaling{}, fmt.Errorf("failed to parse selector '%s': %v", unescapedSelector, err) + } + } + if len(rest) > 0 { + return abi.SelectorMarshaling{}, fmt.Errorf("failed to parse selector '%s': unexpected string '%s'", unescapedSelector, rest) + } + + // Reassemble the fake ABI and construct the JSON + fakeArgs, err := assembleArgs(args) + if err != nil { + return abi.SelectorMarshaling{}, fmt.Errorf("failed to parse selector: %v", err) + } + + return abi.SelectorMarshaling{Name: name, Type: "function", Inputs: fakeArgs}, nil +} + +// ParseSelector converts a method selector into a struct that can be JSON encoded +// and consumed by other functions in this package. +// Note, although uppercase letters are not part of the ABI spec, this function +// still accepts it as the general format is valid. +func ParseSignature(unescapedSelector string) (abi.SelectorMarshaling, error) { + name, rest, err := parseIdentifier(unescapedSelector) + if err != nil { + return abi.SelectorMarshaling{}, fmt.Errorf("failed to parse selector '%s': %v", unescapedSelector, err) + } + args := []abi.ArgumentMarshaling{} + if len(rest) < 2 || rest[0] != '(' || rest[1] != ')' { + args, err = parseArgs(rest) + if err != nil { + return abi.SelectorMarshaling{}, fmt.Errorf("failed to parse selector '%s': %v", unescapedSelector, err) + } + } + + return abi.SelectorMarshaling{Name: name, Type: "function", Inputs: args}, nil +} diff --git a/core/chains/evm/abi/selector_parser_test.go b/core/chains/evm/abi/selector_parser_test.go new file mode 100644 index 00000000000..caae3744678 --- /dev/null +++ b/core/chains/evm/abi/selector_parser_test.go @@ -0,0 +1,126 @@ +// Sourced from https://github.com/ethereum/go-ethereum/blob/fe91d476ba3e29316b6dc99b6efd4a571481d888/accounts/abi/selector_parser_test.go + +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package abi + +import ( + "fmt" + "log" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +func TestParseSelector(t *testing.T) { + t.Parallel() + mkType := func(types ...interface{}) []abi.ArgumentMarshaling { + var result []abi.ArgumentMarshaling + for i, typeOrComponents := range types { + name := fmt.Sprintf("name%d", i) + if typeName, ok := typeOrComponents.(string); ok { + result = append(result, abi.ArgumentMarshaling{Name: name, Type: typeName, InternalType: typeName, Components: nil, Indexed: false}) + } else if components, ok := typeOrComponents.([]abi.ArgumentMarshaling); ok { + result = append(result, abi.ArgumentMarshaling{Name: name, Type: "tuple", InternalType: "tuple", Components: components, Indexed: false}) + } else if components, ok := typeOrComponents.([][]abi.ArgumentMarshaling); ok { + result = append(result, abi.ArgumentMarshaling{Name: name, Type: "tuple[]", InternalType: "tuple[]", Components: components[0], Indexed: false}) + } else { + log.Fatalf("unexpected type %T", typeOrComponents) + } + } + return result + } + tests := []struct { + input string + name string + args []abi.ArgumentMarshaling + }{ + {"noargs()", "noargs", []abi.ArgumentMarshaling{}}, + {"simple(uint256,uint256,uint256)", "simple", mkType("uint256", "uint256", "uint256")}, + {"other(uint256,address)", "other", mkType("uint256", "address")}, + {"withArray(uint256[],address[2],uint8[4][][5])", "withArray", mkType("uint256[]", "address[2]", "uint8[4][][5]")}, + {"singleNest(bytes32,uint8,(uint256,uint256),address)", "singleNest", mkType("bytes32", "uint8", mkType("uint256", "uint256"), "address")}, + {"multiNest(address,(uint256[],uint256),((address,bytes32),uint256))", "multiNest", + mkType("address", mkType("uint256[]", "uint256"), mkType(mkType("address", "bytes32"), "uint256"))}, + {"arrayNest((uint256,uint256)[],bytes32)", "arrayNest", mkType([][]abi.ArgumentMarshaling{mkType("uint256", "uint256")}, "bytes32")}, + {"multiArrayNest((uint256,uint256)[],(uint256,uint256)[])", "multiArrayNest", + mkType([][]abi.ArgumentMarshaling{mkType("uint256", "uint256")}, [][]abi.ArgumentMarshaling{mkType("uint256", "uint256")})}, + {"singleArrayNestAndArray((uint256,uint256)[],bytes32[])", "singleArrayNestAndArray", + mkType([][]abi.ArgumentMarshaling{mkType("uint256", "uint256")}, "bytes32[]")}, + {"singleArrayNestWithArrayAndArray((uint256[],address[2],uint8[4][][5])[],bytes32[])", "singleArrayNestWithArrayAndArray", + mkType([][]abi.ArgumentMarshaling{mkType("uint256[]", "address[2]", "uint8[4][][5]")}, "bytes32[]")}, + } + for i, tt := range tests { + selector, err := ParseSelector(tt.input) + if err != nil { + t.Errorf("test %d: failed to parse selector '%v': %v", i, tt.input, err) + } + if selector.Name != tt.name { + t.Errorf("test %d: unexpected function name: '%s' != '%s'", i, selector.Name, tt.name) + } + + if selector.Type != "function" { + t.Errorf("test %d: unexpected type: '%s' != '%s'", i, selector.Type, "function") + } + if !reflect.DeepEqual(selector.Inputs, tt.args) { + t.Errorf("test %d: unexpected args: '%v' != '%v'", i, selector.Inputs, tt.args) + } + } +} + +func TestParseSignature(t *testing.T) { + t.Parallel() + mkType := func(name string, typeOrComponents interface{}) abi.ArgumentMarshaling { + if typeName, ok := typeOrComponents.(string); ok { + return abi.ArgumentMarshaling{Name: name, Type: typeName, InternalType: typeName, Components: nil, Indexed: false} + } else if components, ok := typeOrComponents.([]abi.ArgumentMarshaling); ok { + return abi.ArgumentMarshaling{Name: name, Type: "tuple", InternalType: "tuple", Components: components, Indexed: false} + } else if components, ok := typeOrComponents.([][]abi.ArgumentMarshaling); ok { + return abi.ArgumentMarshaling{Name: name, Type: "tuple[]", InternalType: "tuple[]", Components: components[0], Indexed: false} + } + log.Fatalf("unexpected type %T", typeOrComponents) + return abi.ArgumentMarshaling{} + } + tests := []struct { + input string + name string + args []abi.ArgumentMarshaling + }{ + {"noargs()", "noargs", []abi.ArgumentMarshaling{}}, + {"simple(a uint256, b uint256, c uint256)", "simple", []abi.ArgumentMarshaling{mkType("a", "uint256"), mkType("b", "uint256"), mkType("c", "uint256")}}, + {"other(foo uint256, bar address)", "other", []abi.ArgumentMarshaling{mkType("foo", "uint256"), mkType("bar", "address")}}, + {"withArray(a uint256[], b address[2], c uint8[4][][5])", "withArray", []abi.ArgumentMarshaling{mkType("a", "uint256[]"), mkType("b", "address[2]"), mkType("c", "uint8[4][][5]")}}, + {"singleNest(d bytes32, e uint8, f (uint256,uint256), g address)", "singleNest", []abi.ArgumentMarshaling{mkType("d", "bytes32"), mkType("e", "uint8"), mkType("f", []abi.ArgumentMarshaling{mkType("name0", "uint256"), mkType("name1", "uint256")}), mkType("g", "address")}}, + } + for i, tt := range tests { + selector, err := ParseSignature(tt.input) + if err != nil { + t.Errorf("test %d: failed to parse selector '%v': %v", i, tt.input, err) + } + if selector.Name != tt.name { + t.Errorf("test %d: unexpected function name: '%s' != '%s'", i, selector.Name, tt.name) + } + + if selector.Type != "function" { + t.Errorf("test %d: unexpected type: '%s' != '%s'", i, selector.Type, "function") + } + if !reflect.DeepEqual(selector.Inputs, tt.args) { + t.Errorf("test %d: unexpected args: '%v' != '%v'", i, selector.Inputs, tt.args) + } + } +} diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 7c0a41fa366..ae9d592c6ca 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a diff --git a/core/scripts/go.sum b/core/scripts/go.sum index b32a445d60a..36569639eac 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1169,8 +1169,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 h1:VgsaJqVkTfcRv/s4EWPPmgL8o2mjftKZSqRGluZro7M= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 h1:1IeZowwqz3Uql9UqH8KP3C0J48wd/W0bVPMF5D+wDdA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/core/services/relay/evm/cap_encoder.go b/core/services/relay/evm/cap_encoder.go new file mode 100644 index 00000000000..b6865096af9 --- /dev/null +++ b/core/services/relay/evm/cap_encoder.go @@ -0,0 +1,97 @@ +package evm + +import ( + "context" + "encoding/json" + "fmt" + + consensustypes "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/values" + abiutil "github.com/smartcontractkit/chainlink/v2/core/chains/evm/abi" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +const ( + abiConfigFieldName = "abi" + encoderName = "user" + idLen = 32 +) + +type capEncoder struct { + codec commontypes.RemoteCodec +} + +var _ consensustypes.Encoder = (*capEncoder)(nil) + +func NewEVMEncoder(config *values.Map) (consensustypes.Encoder, error) { + // parse the "inner" encoder config - user-defined fields + wrappedSelector, err := config.Underlying[abiConfigFieldName].Unwrap() + if err != nil { + return nil, err + } + selectorStr, ok := wrappedSelector.(string) + if !ok { + return nil, fmt.Errorf("expected %s to be a string", abiConfigFieldName) + } + selector, err := abiutil.ParseSignature("inner(" + selectorStr + ")") + if err != nil { + return nil, err + } + jsonSelector, err := json.Marshal(selector.Inputs) + if err != nil { + return nil, err + } + + codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ + encoderName: {TypeABI: string(jsonSelector)}, + }} + c, err := NewCodec(codecConfig) + if err != nil { + return nil, err + } + + return &capEncoder{codec: c}, nil +} + +func (c *capEncoder) Encode(ctx context.Context, input values.Map) ([]byte, error) { + unwrappedInput, err := input.Unwrap() + if err != nil { + return nil, err + } + unwrappedMap, ok := unwrappedInput.(map[string]any) + if !ok { + return nil, fmt.Errorf("expected unwrapped input to be a map") + } + userPayload, err := c.codec.Encode(ctx, unwrappedMap, encoderName) + if err != nil { + return nil, err + } + // prepend workflowID and workflowExecutionID to the encoded user data + workflowIDbytes, executionIDBytes, err := extractIDs(unwrappedMap) + if err != nil { + return nil, err + } + return append(append(workflowIDbytes, executionIDBytes...), userPayload...), nil +} + +// extract workflowID and executionID from the input map, validate and align to 32 bytes +// NOTE: consider requiring them to be exactly 32 bytes to avoid issues with padding +func extractIDs(input map[string]any) ([]byte, []byte, error) { + workflowID, ok := input[consensustypes.WorkflowIDFieldName].(string) + if !ok { + return nil, nil, fmt.Errorf("expected %s to be a string", consensustypes.WorkflowIDFieldName) + } + executionID, ok := input[consensustypes.ExecutionIDFieldName].(string) + if !ok { + return nil, nil, fmt.Errorf("expected %s to be a string", consensustypes.ExecutionIDFieldName) + } + if len(workflowID) > 32 || len(executionID) > 32 { + return nil, nil, fmt.Errorf("IDs too long: %d, %d", len(workflowID), len(executionID)) + } + alignedWorkflowID := make([]byte, idLen) + copy(alignedWorkflowID, workflowID) + alignedExecutionID := make([]byte, idLen) + copy(alignedExecutionID, executionID) + return alignedWorkflowID, alignedExecutionID, nil +} diff --git a/core/services/relay/evm/cap_encoder_test.go b/core/services/relay/evm/cap_encoder_test.go new file mode 100644 index 00000000000..1d8b6da4610 --- /dev/null +++ b/core/services/relay/evm/cap_encoder_test.go @@ -0,0 +1,58 @@ +package evm_test + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + consensustypes "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" +) + +var ( + reportA = []byte{0x01, 0x02, 0x03} + reportB = []byte{0xaa, 0xbb, 0xcc, 0xdd} + workflowID = "my_id" + executionID = "my_execution_id" +) + +func TestEVMEncoder(t *testing.T) { + config := map[string]any{ + "abi": "mercury_reports bytes[]", + } + wrapped, err := values.NewMap(config) + require.NoError(t, err) + enc, err := evm.NewEVMEncoder(wrapped) + require.NoError(t, err) + + // output of a DF2.0 aggregator + metadata fields appended by OCR + input := map[string]any{ + "mercury_reports": []any{reportA, reportB}, + consensustypes.WorkflowIDFieldName: workflowID, + consensustypes.ExecutionIDFieldName: executionID, + } + wrapped, err = values.NewMap(input) + require.NoError(t, err) + encoded, err := enc.Encode(testutils.Context(t), *wrapped) + require.NoError(t, err) + + expected := + // start of the outer tuple ((user_fields), workflow_id, workflow_execution_id) + "6d795f6964000000000000000000000000000000000000000000000000000000" + // workflow ID + "6d795f657865637574696f6e5f69640000000000000000000000000000000000" + // execution ID + // start of the inner tuple (user_fields) + "0000000000000000000000000000000000000000000000000000000000000020" + // offset of mercury_reports array + "0000000000000000000000000000000000000000000000000000000000000002" + // length of mercury_reports array + "0000000000000000000000000000000000000000000000000000000000000040" + // offset of reportA + "0000000000000000000000000000000000000000000000000000000000000080" + // offset of reportB + "0000000000000000000000000000000000000000000000000000000000000003" + // length of reportA + "0102030000000000000000000000000000000000000000000000000000000000" + // reportA + "0000000000000000000000000000000000000000000000000000000000000004" + // length of reportB + "aabbccdd00000000000000000000000000000000000000000000000000000000" // reportB + // end of the inner tuple (user_fields) + + require.Equal(t, expected, hex.EncodeToString(encoded)) +} diff --git a/go.mod b/go.mod index 799dbe9b906..e68fe191db2 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 097aaea35c9..c9b2aa88574 100644 --- a/go.sum +++ b/go.sum @@ -1164,8 +1164,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 h1:VgsaJqVkTfcRv/s4EWPPmgL8o2mjftKZSqRGluZro7M= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 h1:1IeZowwqz3Uql9UqH8KP3C0J48wd/W0bVPMF5D+wDdA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0f9df5b63f9..e8d46fd8ab8 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 275761a080e..9b5c4ad604d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1503,8 +1503,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290 h1:VgsaJqVkTfcRv/s4EWPPmgL8o2mjftKZSqRGluZro7M= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215194703-6ab175aa7290/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 h1:1IeZowwqz3Uql9UqH8KP3C0J48wd/W0bVPMF5D+wDdA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= From 9fc36ba78f1361d5deecf020af84e84daefbc9ff Mon Sep 17 00:00:00 2001 From: chudilka1 Date: Fri, 16 Feb 2024 11:40:45 +0000 Subject: [PATCH 44/98] Exclude tsconfig from Sonar analysis (#12051) --- sonar-project.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/sonar-project.properties b/sonar-project.properties index c5a2eb33ad2..d4e263fdd3c 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -31,6 +31,7 @@ sonar.exclusions=\ **/*.bin,\ **/*_codecgen.go,\ **/*_gen.go,\ +**/tsconfig.json,\ **/debug.go # Coverage exclusions From 4c4ac47228b56e758854189f450f3037be4c7ef6 Mon Sep 17 00:00:00 2001 From: Cedric Date: Fri, 16 Feb 2024 13:36:29 +0000 Subject: [PATCH 45/98] [chore] Make OCR3 use bytes rather than any for Info (#12058) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/ocr2/delegate.go | 2 +- core/services/ocrcommon/adapters.go | 10 +++++----- core/services/ocrcommon/adapters_test.go | 3 ++- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- 9 files changed, 17 insertions(+), 16 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index ae9d592c6ca..c5136dbdb14 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 36569639eac..e00dca85002 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1169,8 +1169,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 h1:1IeZowwqz3Uql9UqH8KP3C0J48wd/W0bVPMF5D+wDdA= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 h1:8YWKoBemWvERQp6R6NoGVTVOg/4yuoKaSHdil/ym9uo= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 25c3cf9a485..55e026bd114 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -662,7 +662,7 @@ func (d *Delegate) newServicesGenericPlugin( //OCR3 with OCR2 OnchainKeyring and ContractTransmitter plugin := ocr3.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog, capabilitiesRegistry) contractTransmitter := ocrcommon.NewOCR3ContractTransmitterAdapter(provider.ContractTransmitter()) - oracleArgs := libocr2.OCR3OracleArgs[any]{ + oracleArgs := libocr2.OCR3OracleArgs[[]byte]{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, ContractConfigTracker: provider.ContractConfigTracker(), diff --git a/core/services/ocrcommon/adapters.go b/core/services/ocrcommon/adapters.go index ca7e84ccfa6..1eee437eb6b 100644 --- a/core/services/ocrcommon/adapters.go +++ b/core/services/ocrcommon/adapters.go @@ -7,7 +7,7 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) -var _ ocr3types.OnchainKeyring[any] = (*OCR3OnchainKeyringAdapter)(nil) +var _ ocr3types.OnchainKeyring[[]byte] = (*OCR3OnchainKeyringAdapter)(nil) type OCR3OnchainKeyringAdapter struct { o ocrtypes.OnchainKeyring @@ -21,7 +21,7 @@ func (k *OCR3OnchainKeyringAdapter) PublicKey() ocrtypes.OnchainPublicKey { return k.o.PublicKey() } -func (k *OCR3OnchainKeyringAdapter) Sign(digest ocrtypes.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[any]) (signature []byte, err error) { +func (k *OCR3OnchainKeyringAdapter) Sign(digest ocrtypes.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[[]byte]) (signature []byte, err error) { return k.o.Sign(ocrtypes.ReportContext{ ReportTimestamp: ocrtypes.ReportTimestamp{ ConfigDigest: digest, @@ -32,7 +32,7 @@ func (k *OCR3OnchainKeyringAdapter) Sign(digest ocrtypes.ConfigDigest, seqNr uin }, r.Report) } -func (k *OCR3OnchainKeyringAdapter) Verify(opk ocrtypes.OnchainPublicKey, digest ocrtypes.ConfigDigest, seqNr uint64, ri ocr3types.ReportWithInfo[any], signature []byte) bool { +func (k *OCR3OnchainKeyringAdapter) Verify(opk ocrtypes.OnchainPublicKey, digest ocrtypes.ConfigDigest, seqNr uint64, ri ocr3types.ReportWithInfo[[]byte], signature []byte) bool { return k.o.Verify(opk, ocrtypes.ReportContext{ ReportTimestamp: ocrtypes.ReportTimestamp{ ConfigDigest: digest, @@ -47,7 +47,7 @@ func (k *OCR3OnchainKeyringAdapter) MaxSignatureLength() int { return k.o.MaxSignatureLength() } -var _ ocr3types.ContractTransmitter[any] = (*OCR3ContractTransmitterAdapter)(nil) +var _ ocr3types.ContractTransmitter[[]byte] = (*OCR3ContractTransmitterAdapter)(nil) type OCR3ContractTransmitterAdapter struct { ct ocrtypes.ContractTransmitter @@ -57,7 +57,7 @@ func NewOCR3ContractTransmitterAdapter(ct ocrtypes.ContractTransmitter) *OCR3Con return &OCR3ContractTransmitterAdapter{ct} } -func (c *OCR3ContractTransmitterAdapter) Transmit(ctx context.Context, digest ocrtypes.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[any], signatures []ocrtypes.AttributedOnchainSignature) error { +func (c *OCR3ContractTransmitterAdapter) Transmit(ctx context.Context, digest ocrtypes.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[[]byte], signatures []ocrtypes.AttributedOnchainSignature) error { return c.ct.Transmit(ctx, ocrtypes.ReportContext{ ReportTimestamp: ocrtypes.ReportTimestamp{ ConfigDigest: digest, diff --git a/core/services/ocrcommon/adapters_test.go b/core/services/ocrcommon/adapters_test.go index a29cec27de7..6c13ac85f15 100644 --- a/core/services/ocrcommon/adapters_test.go +++ b/core/services/ocrcommon/adapters_test.go @@ -20,8 +20,9 @@ var ( account ocrtypes.Account = "Test-Account" configDigest = ocrtypes.ConfigDigest([]byte("kKfYauxXBMjuP5EuuyacN6BwCfKJnP6d")) seqNr uint64 = 11 - rwi = ocr3types.ReportWithInfo[any]{ + rwi = ocr3types.ReportWithInfo[[]byte]{ Report: []byte("report"), + Info: []byte("info"), } signatures = []types.AttributedOnchainSignature{{ Signature: []byte("signature1"), diff --git a/go.mod b/go.mod index e68fe191db2..1e4b658d84f 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index c9b2aa88574..85b56c9f232 100644 --- a/go.sum +++ b/go.sum @@ -1164,8 +1164,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 h1:1IeZowwqz3Uql9UqH8KP3C0J48wd/W0bVPMF5D+wDdA= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 h1:8YWKoBemWvERQp6R6NoGVTVOg/4yuoKaSHdil/ym9uo= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e8d46fd8ab8..1e3567c8902 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 9b5c4ad604d..415fee4117e 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1503,8 +1503,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417 h1:1IeZowwqz3Uql9UqH8KP3C0J48wd/W0bVPMF5D+wDdA= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240215221559-8a726e745417/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 h1:8YWKoBemWvERQp6R6NoGVTVOg/4yuoKaSHdil/ym9uo= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= From 60de6072c26cc306deba102864b9e94756b2bda2 Mon Sep 17 00:00:00 2001 From: Cedric Date: Fri, 16 Feb 2024 18:16:13 +0000 Subject: [PATCH 46/98] [KS-33] Add loop binary (#12050) * WIP * Add loopp binary for OCR3 capability * Update pin * Add binary to dockerfile * Add command to run ocr3 capability * Add make install command to Dockerfile * Add workflow to job type * Bump common * Pick up moved StreamID --- GNUmakefile | 4 ++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/job/validate.go | 1 + core/services/ocr2/delegate.go | 2 +- core/services/streams/stream_registry.go | 2 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- plugins/chainlink.Dockerfile | 6 ++- plugins/cmd/chainlink-ocr3-capability/main.go | 44 +++++++++++++++++++ 12 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 plugins/cmd/chainlink-ocr3-capability/main.go diff --git a/GNUmakefile b/GNUmakefile index eab8a73b954..20f3eb92d51 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -62,6 +62,10 @@ chainlink-local-start: install-medianpoc: ## Build & install the chainlink-medianpoc binary. go install $(GOFLAGS) ./plugins/cmd/chainlink-medianpoc +.PHONY: install-ocr3-capability +install-ocr3-capability: ## Build & install the chainlink-ocr3-capability binary. + go install $(GOFLAGS) ./plugins/cmd/chainlink-ocr3-capability + .PHONY: docker ## Build the chainlink docker image docker: docker buildx build \ diff --git a/core/scripts/go.mod b/core/scripts/go.mod index c5136dbdb14..2c877299deb 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e00dca85002..7a4faf31ce3 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1169,8 +1169,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 h1:8YWKoBemWvERQp6R6NoGVTVOg/4yuoKaSHdil/ym9uo= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/core/services/job/validate.go b/core/services/job/validate.go index f108031f72e..47c9bb5aba6 100644 --- a/core/services/job/validate.go +++ b/core/services/job/validate.go @@ -27,6 +27,7 @@ var ( Stream: {}, VRF: {}, Webhook: {}, + Workflow: {}, } ) diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 55e026bd114..754f48013bd 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -602,7 +602,7 @@ func (d *Delegate) newServicesGenericPlugin( ps, err2 := relay.NewProviderServer(provider, types.OCR2PluginType(pCfg.ProviderType), d.lggr) if err2 != nil { - return nil, fmt.Errorf("cannot start EVM provider server: %s", err) + return nil, fmt.Errorf("cannot start EVM provider server: %s", err2) } providerClientConn, err2 = ps.GetConn() if err2 != nil { diff --git a/core/services/streams/stream_registry.go b/core/services/streams/stream_registry.go index c4795caa304..bc63e98e288 100644 --- a/core/services/streams/stream_registry.go +++ b/core/services/streams/stream_registry.go @@ -4,7 +4,7 @@ import ( "fmt" "sync" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" diff --git a/go.mod b/go.mod index 1e4b658d84f..396201fdede 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 85b56c9f232..e02add4ee89 100644 --- a/go.sum +++ b/go.sum @@ -1164,8 +1164,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 h1:8YWKoBemWvERQp6R6NoGVTVOg/4yuoKaSHdil/ym9uo= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 1e3567c8902..ccb0810ab50 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 415fee4117e..ed933fab701 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1503,8 +1503,8 @@ github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumv github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9 h1:8YWKoBemWvERQp6R6NoGVTVOg/4yuoKaSHdil/ym9uo= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216130301-0c136fa494a9/go.mod h1:yKWUC5vRyIB+yQdmpOAf2y2A0hJ43uENKVgljk5Ve3g= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/plugins/chainlink.Dockerfile b/plugins/chainlink.Dockerfile index cdfc3ee1356..4d1e2f4e6df 100644 --- a/plugins/chainlink.Dockerfile +++ b/plugins/chainlink.Dockerfile @@ -20,6 +20,9 @@ RUN make install-chainlink # Install medianpoc binary RUN make install-medianpoc +# Install ocr3-capability binary +RUN make install-ocr3-capability + # Link LOOP Plugin source dirs with simple names RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds | xargs -I % ln -s % /chainlink-feeds RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-data-streams | xargs -I % ln -s % /chainlink-data-streams @@ -62,6 +65,7 @@ RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ COPY --from=buildgo /go/bin/chainlink /usr/local/bin/ COPY --from=buildgo /go/bin/chainlink-medianpoc /usr/local/bin/ +COPY --from=buildgo /go/bin/chainlink-ocr3-capability /usr/local/bin/ COPY --from=buildplugins /go/bin/chainlink-feeds /usr/local/bin/ ENV CL_MEDIAN_CMD chainlink-feeds @@ -90,4 +94,4 @@ ENTRYPOINT ["chainlink"] HEALTHCHECK CMD curl -f http://localhost:6688/health || exit 1 -CMD ["local", "node"] \ No newline at end of file +CMD ["local", "node"] diff --git a/plugins/cmd/chainlink-ocr3-capability/main.go b/plugins/cmd/chainlink-ocr3-capability/main.go new file mode 100644 index 00000000000..ac8bb6454f3 --- /dev/null +++ b/plugins/cmd/chainlink-ocr3-capability/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "github.com/hashicorp/go-plugin" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" + ocr3rp "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" +) + +const ( + loggerName = "PluginOCR3Capability" +) + +func main() { + s := loop.MustNewStartedServer(loggerName) + defer s.Stop() + + p := ocr3.NewOCR3(s.Logger, evm.NewEVMEncoder) + defer s.Logger.ErrorIfFn(p.Close, "Failed to close") + + s.MustRegister(p) + + stop := make(chan struct{}) + defer close(stop) + + plugin.Serve(&plugin.ServeConfig{ + HandshakeConfig: reportingplugins.ReportingPluginHandshakeConfig(), + Plugins: map[string]plugin.Plugin{ + ocr3rp.PluginServiceName: &ocr3rp.GRPCService[types.PluginProvider]{ + PluginServer: p, + BrokerConfig: loop.BrokerConfig{ + Logger: s.Logger, + StopCh: stop, + GRPCOpts: s.GRPCOpts, + }, + }, + }, + GRPCServer: s.GRPCOpts.NewServer, + }) +} From 768511641463f041f161175230eb9f3af11a2ddd Mon Sep 17 00:00:00 2001 From: Ryan Hall Date: Fri, 16 Feb 2024 17:03:58 -0300 Subject: [PATCH 47/98] Auto 8888 properly account for l 1 gas overhead for l 2 chains op scroll arb (#11983) * AUTO-8804: added a chain specific module for automation * add modules * create specific modules for different chains * implement modules * addressed some feedbacks * update tests * generate wrappers * fix foundry * run yarn prettier:write * remove unnecessary import * remove unnecessary checks * update gas overheads to pass tests * regen wrappers * fix sonarcube issues * address some comments * adjust gas overheads * prettier * remove only * adjust gas overhead again * dont use const * rebase to latest and add chainmodule getter * refactor gas overhead usage * Cleanup and rename variables * add chain module overhead calculation * inline max overhead function * remove underfunded upkeep check * simplify max link payment * minor improvements * cleanup maxLinkPayment * Revert "cleanup maxLinkPayment" This reverts commit 1048b7cd609df54fdbe2d4b7022fff35eb85b54d. * fixc small issues * fix some tests, adjust overheads, regen wrappers * run prettier * fix tests * add some todos * update comments * regen master interface * regen wrappers and update tests * improve tests * add per signer transmit overhead * fix conditional overhead test * fix overhead tests * Fix batching tests * refactor linkForGas in tests * Divide l1 fee according to performdata weight * format tests * add test for l1 split * adjust comment * update comment * format tests * iformat tests * add tests for reorg protection flag * update go wrappers * remove i keeper registry 2.2 wrapper * Polish minBalance test * formatting * refine constants * update * udpate wrappers --------- Co-authored-by: FelixFan1992 Co-authored-by: lei shi Co-authored-by: Akshay Aggarwal --- .../automation/dev/chains/ArbitrumModule.sol | 11 + .../automation/dev/chains/ChainModuleBase.sol | 9 + .../automation/dev/chains/OptimismModule.sol | 12 + .../automation/dev/chains/ScrollModule.sol | 12 + .../v2_2/IAutomationRegistryMaster.sol | 9 +- .../dev/interfaces/v2_2/IChainModule.sol | 14 +- .../dev/v2_2/AutomationRegistry2_2.sol | 76 +- .../dev/v2_2/AutomationRegistryBase2_2.sol | 152 ++-- .../dev/v2_2/AutomationRegistryLogicA2_2.sol | 10 +- .../dev/v2_2/AutomationRegistryLogicB2_2.sol | 19 +- contracts/src/v0.8/tests/MockChainModule.sol | 28 - .../automation/AutomationRegistry2_2.test.ts | 736 +++++++++++------- ...utomation_registry_logic_a_wrapper_2_2.go} | 6 +- ...utomation_registry_logic_b_wrapper_2_2.go} | 68 +- .../automation_registry_wrapper_2_2.go} | 6 +- ...automation_registry_master_wrapper_2_2.go} | 66 +- ...rapper-dependency-versions-do-not-edit.txt | 8 +- core/gethwrappers/go_generate.go | 8 +- 18 files changed, 757 insertions(+), 493 deletions(-) delete mode 100644 contracts/src/v0.8/tests/MockChainModule.sol rename core/gethwrappers/generated/{keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go => automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go} (73%) rename core/gethwrappers/generated/{keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go => automation_registry_logic_b_wrapper_2_2/automation_registry_logic_b_wrapper_2_2.go} (74%) rename core/gethwrappers/generated/{keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go => automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go} (79%) rename core/gethwrappers/generated/{i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go => i_automation_registry_master_wrapper_2_2/i_automation_registry_master_wrapper_2_2.go} (85%) diff --git a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol index 62e9ff9ea1c..1bb4b45efc5 100644 --- a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol +++ b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol @@ -34,6 +34,17 @@ contract ArbitrumModule is ChainModuleBase { function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { (, uint256 perL1CalldataUnit, , , , ) = ARB_GAS.getPricesInWei(); + // TODO: Verify this is an accurate estimate return perL1CalldataUnit * dataSize * 16; } + + function getGasOverhead() + external + view + override + returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) + { + // TODO: Calculate + return (0, 0); + } } diff --git a/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol b/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol index f8685e651f4..f7e5b7b2ab2 100644 --- a/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol +++ b/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol @@ -22,4 +22,13 @@ contract ChainModuleBase is IChainModule { function getMaxL1Fee(uint256) external view virtual returns (uint256) { return 0; } + + function getGasOverhead() + external + view + virtual + returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) + { + return (0, 0); + } } diff --git a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol b/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol index 7f26440c154..0d6bc651683 100644 --- a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol +++ b/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol @@ -14,6 +14,7 @@ contract OptimismModule is ChainModuleBase { OVM_GasPriceOracle private constant OVM_GASPRICEORACLE = OVM_GasPriceOracle(OVM_GASPRICEORACLE_ADDR); function getCurrentL1Fee() external view override returns (uint256) { + // TODO: Verify this is accurate calculation with appropriate padding return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(msg.data, OP_L1_DATA_FEE_PADDING)); } @@ -21,6 +22,17 @@ contract OptimismModule is ChainModuleBase { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. bytes memory txCallData = new bytes(4 * dataSize); + // TODO: Verify this is an accurate estimate return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(txCallData, OP_L1_DATA_FEE_PADDING)); } + + function getGasOverhead() + external + view + override + returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) + { + // TODO: Calculate + return (0, 0); + } } diff --git a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol b/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol index a2f585dd381..7029448637c 100644 --- a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol +++ b/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol @@ -16,6 +16,7 @@ contract ScrollModule is ChainModuleBase { IScrollL1GasPriceOracle private constant SCROLL_ORACLE = IScrollL1GasPriceOracle(SCROLL_ORACLE_ADDR); function getCurrentL1Fee() external view override returns (uint256) { + // TODO: Verify this is accurate calculation with appropriate padding return SCROLL_ORACLE.getL1Fee(bytes.concat(msg.data, SCROLL_L1_FEE_DATA_PADDING)); } @@ -23,7 +24,18 @@ contract ScrollModule is ChainModuleBase { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. // this is the same as OP. + // TODO: Verify this is an accurate estimate bytes memory txCallData = new bytes(4 * dataSize); return SCROLL_ORACLE.getL1Fee(bytes.concat(txCallData, SCROLL_L1_FEE_DATA_PADDING)); } + + function getGasOverhead() + external + view + override + returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) + { + // TODO: Calculate + return (0, 0); + } } diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol index 2c0d8f05297..a2d73bbd807 100644 --- a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol +++ b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol @@ -1,4 +1,4 @@ -// abi-checksum: 0x71da69c27646c421cbde8ef39597eb47197351f8c89dee37447b35d8ad1d572e +// abi-checksum: 0xfc319f2ddde95d2e0226c913b9e417495effc4c8c847d01fe07e3de68ea8839c // SPDX-License-Identifier: MIT // !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !! pragma solidity ^0.8.4; @@ -16,7 +16,6 @@ interface IAutomationRegistryMaster { error IncorrectNumberOfSignatures(); error IncorrectNumberOfSigners(); error IndexOutOfRange(); - error InsufficientFunds(); error InvalidDataLength(); error InvalidPayee(); error InvalidRecipient(); @@ -107,7 +106,6 @@ interface IAutomationRegistryMaster { event UpkeepRegistered(uint256 indexed id, uint32 performGas, address admin); event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); event UpkeepUnpaused(uint256 indexed id); - fallback() external; function acceptOwnership() external; function fallbackTo() external view returns (address); @@ -238,6 +236,8 @@ interface IAutomationRegistryMaster { address[] memory transmitters, uint8 f ); + function getTransmitCalldataFixedBytesOverhead() external pure returns (uint256); + function getTransmitCalldataPerSignerBytesOverhead() external pure returns (uint256); function getTransmitterInfo( address query ) external view returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee); @@ -250,7 +250,6 @@ interface IAutomationRegistryMaster { function pauseUpkeep(uint256 id) external; function recoverFunds() external; function setAdminPrivilegeConfig(address admin, bytes memory newPrivilegeConfig) external; - function setChainSpecificModule(address newModule) external; function setPayees(address[] memory payees) external; function setPeerRegistryMigrationPermission(address peer, uint8 permission) external; function setUpkeepCheckData(uint256 id, bytes memory newCheckData) external; @@ -336,5 +335,5 @@ interface AutomationRegistryBase2_2 { // THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON: /* -[{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MaxCheckDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MaxPerformDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"PaymentGreaterThanAllLINK","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"OwnerFundsWithdrawn","type":"event"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkNativeFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkNativeFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.State","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct AutomationRegistryBase2_2.UpkeepInfo","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IChainModule","name":"newModule","type":"address"}],"name":"setChainSpecificModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepTranscoderVersion","outputs":[{"internalType":"enum UpkeepFormat","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwnerFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MaxCheckDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MaxPerformDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"PaymentGreaterThanAllLINK","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"OwnerFundsWithdrawn","type":"event"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_2","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_2.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkNativeFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkNativeFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct AutomationRegistryBase2_2.State","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct AutomationRegistryBase2_2.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitCalldataFixedBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransmitCalldataPerSignerBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_2.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct AutomationRegistryBase2_2.UpkeepInfo","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_2.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepTranscoderVersion","outputs":[{"internalType":"enum UpkeepFormat","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwnerFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] */ diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol index dd5613fbf36..e3a4b32c9b1 100644 --- a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol +++ b/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol @@ -10,10 +10,20 @@ interface IChainModule { // retrieve the L1 data fee for a L2 transaction. it should return 0 for L1 chains and // L2 chains which don't have L1 fee component. it uses msg.data to estimate L1 data so - // it must be used with a transaction. + // it must be used with a transaction. Return value in wei. function getCurrentL1Fee() external view returns (uint256); // retrieve the L1 data fee for a L2 simulation. it should return 0 for L1 chains and - // L2 chains which don't have L1 fee component. + // L2 chains which don't have L1 fee component. Return value in wei. function getMaxL1Fee(uint256 dataSize) external view returns (uint256); + + // Returns an upper bound on execution gas cost for one invocation of blockNumber(), + // one invocation of blockHash() and one invocation of getCurrentL1Fee(). + // Returns two values, first value indicates a fixed cost and the second value is + // the cost per msg.data byte (As some chain module's getCurrentL1Fee execution cost + // scales with calldata size) + function getGasOverhead() + external + view + returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead); } diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol index f988787d574..7b37a5eba2c 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol @@ -57,6 +57,16 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain Chainable(address(logicA)) {} + /** + * @notice holds the variables used in the transmit function, necessary to avoid stack too deep errors + */ + struct TransmitVars { + uint16 numUpkeepsPassedChecks; + uint256 totalCalldataWeight; + uint96 totalReimbursement; + uint96 totalPremium; + } + // ================================================================ // | ACTIONS | // ================================================================ @@ -96,21 +106,20 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain function _handleReport(HotVars memory hotVars, Report memory report, uint256 gasOverhead) private { UpkeepTransmitInfo[] memory upkeepTransmitInfo = new UpkeepTransmitInfo[](report.upkeepIds.length); - uint16 numUpkeepsPassedChecks; + TransmitVars memory transmitVars = TransmitVars({ + numUpkeepsPassedChecks: 0, + totalCalldataWeight: 0, + totalReimbursement: 0, + totalPremium: 0 + }); uint256 blocknumber = hotVars.chainModule.blockNumber(); + uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(); + for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; upkeepTransmitInfo[i].triggerType = _getTriggerType(report.upkeepIds[i]); - upkeepTransmitInfo[i].maxLinkPayment = _getMaxLinkPayment( - hotVars, - upkeepTransmitInfo[i].triggerType, - uint32(report.gasLimits[i]), - uint32(report.performDatas[i].length), - report.fastGasWei, - report.linkNative, - true - ); + (upkeepTransmitInfo[i].earlyChecksPassed, upkeepTransmitInfo[i].dedupID) = _prePerformChecks( report.upkeepIds[i], blocknumber, @@ -120,7 +129,7 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain ); if (upkeepTransmitInfo[i].earlyChecksPassed) { - numUpkeepsPassedChecks += 1; + transmitVars.numUpkeepsPassedChecks += 1; } else { continue; } @@ -132,6 +141,14 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain report.performDatas[i] ); + // To split L1 fee across the upkeeps, assign a weight to this upkeep based on the length + // of the perform data and calldata overhead + upkeepTransmitInfo[i].calldataWeight = + report.performDatas[i].length + + TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + + (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); + transmitVars.totalCalldataWeight += upkeepTransmitInfo[i].calldataWeight; + // Deduct that gasUsed by upkeep from our running counter gasOverhead -= upkeepTransmitInfo[i].gasUsed; @@ -139,59 +156,46 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain _updateTriggerMarker(report.upkeepIds[i], blocknumber, upkeepTransmitInfo[i]); } // No upkeeps to be performed in this report - if (numUpkeepsPassedChecks == 0) { + if (transmitVars.numUpkeepsPassedChecks == 0) { return; } // This is the overall gas overhead that will be split across performed upkeeps - // Take upper bound of 16 gas per callData bytes, which is approximated to be reportLength - // Rest of msg.data is accounted for in accounting overheads - // NOTE in process of changing accounting, so pre-emptively changed reportLength to msg.data.length - gasOverhead = - (gasOverhead - gasleft() + 16 * msg.data.length) + - ACCOUNTING_FIXED_GAS_OVERHEAD + - (ACCOUNTING_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)); - gasOverhead = gasOverhead / numUpkeepsPassedChecks + ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD; + // Take upper bound of 16 gas per callData bytes + gasOverhead = (gasOverhead - gasleft()) + (16 * msg.data.length) + ACCOUNTING_FIXED_GAS_OVERHEAD; + gasOverhead = gasOverhead / transmitVars.numUpkeepsPassedChecks + ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD; - uint96 totalReimbursement; - uint96 totalPremium; { uint96 reimbursement; uint96 premium; for (uint256 i = 0; i < report.upkeepIds.length; i++) { if (upkeepTransmitInfo[i].earlyChecksPassed) { - upkeepTransmitInfo[i].gasOverhead = _getCappedGasOverhead( - gasOverhead, - upkeepTransmitInfo[i].triggerType, - uint32(report.performDatas[i].length), - hotVars.f - ); - (reimbursement, premium) = _postPerformPayment( hotVars, report.upkeepIds[i], - upkeepTransmitInfo[i], + upkeepTransmitInfo[i].gasUsed, report.fastGasWei, report.linkNative, - numUpkeepsPassedChecks + gasOverhead, + (l1Fee * upkeepTransmitInfo[i].calldataWeight) / transmitVars.totalCalldataWeight ); - totalPremium += premium; - totalReimbursement += reimbursement; + transmitVars.totalPremium += premium; + transmitVars.totalReimbursement += reimbursement; emit UpkeepPerformed( report.upkeepIds[i], upkeepTransmitInfo[i].performSuccess, reimbursement + premium, upkeepTransmitInfo[i].gasUsed, - upkeepTransmitInfo[i].gasOverhead, + gasOverhead, report.triggers[i] ); } } } // record payments - s_transmitters[msg.sender].balance += totalReimbursement; - s_hotVars.totalPremium += totalPremium; + s_transmitters[msg.sender].balance += transmitVars.totalReimbursement; + s_hotVars.totalPremium += transmitVars.totalPremium; } /** diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol index 976c8dff80d..a198daef4f1 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol @@ -45,14 +45,26 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { UpkeepFormat internal constant UPKEEP_TRANSCODER_VERSION_BASE = UpkeepFormat.V1; uint8 internal constant UPKEEP_VERSION_BASE = 3; - uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 90_000; // Used in maxPayment estimation, and in capping overheads during actual payment - uint256 internal constant REGISTRY_LOG_OVERHEAD = 110_400; // Used only in maxPayment estimation, and in capping overheads during actual payment. - uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 20; // Used only in maxPayment estimation, and in capping overheads during actual payment. Value scales with performData length. - uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 7_500; // Used only in maxPayment estimation, and in capping overheads during actual payment. Value scales with f. - - uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 28_100; // Used in actual payment. Fixed overhead per tx - uint256 internal constant ACCOUNTING_PER_SIGNER_GAS_OVERHEAD = 1_100; // Used in actual payment. overhead per signer - uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 7_200; // Used in actual payment. overhead per upkeep performed + // Next block of constants are only used in maxPayment estimation during checkUpkeep simulation + // These values are calibrated using hardhat tests which simulates various cases and verifies that + // the variables result in accurate estimation + uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 60_000; // Fixed gas overhead for conditional upkeeps + uint256 internal constant REGISTRY_LOG_OVERHEAD = 85_000; // Fixed gas overhead for log upkeeps + uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 5_600; // Value scales with f + uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 24; // Per perform data byte overhead + + // The overhead (in bytes) in addition to perform data for upkeep sent in calldata + // This includes overhead for all struct encoding as well as report signatures + // There is a fixed component and a per signer component. This is calculated exactly by doing abi encoding + uint256 internal constant TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD = 932; + uint256 internal constant TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD = 64; + + // Next block of constants are used in actual payment calculation. We calculate the exact gas used within the + // tx itself, but since payment processing itself takes gas, and it needs the overhead as input, we use fixed constants + // to account for gas used in payment processing. These values are calibrated using hardhat tests which simulates various cases and verifies that + // the variables result in accurate estimation + uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 22_000; // Fixed overhead per tx + uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 7_000; // Overhead per upkeep performed in batch LinkTokenInterface internal immutable i_link; AggregatorV3Interface internal immutable i_linkNativeFeed; @@ -104,7 +116,6 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { error IncorrectNumberOfSignatures(); error IncorrectNumberOfSigners(); error IndexOutOfRange(); - error InsufficientFunds(); error InvalidDataLength(); error InvalidTrigger(); error InvalidPayee(); @@ -236,9 +247,7 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { * @member registrars addresses of the registrar contracts * @member upkeepPrivilegeManager address which can set privilege for upkeeps * @member reorgProtectionEnabled if this registry enables re-org protection checks - * @member chainSpecificModule the chain specific module * @member chainModule the chain specific module - * @member reorgProtectionEnabled if this registry will enable re-org protection checks */ struct OnchainConfig { uint32 paymentPremiumPPB; @@ -387,21 +396,19 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { * @dev This struct is used to maintain run time information about an upkeep in transmit function * @member upkeep the upkeep struct * @member earlyChecksPassed whether the upkeep passed early checks before perform - * @member maxLinkPayment the max amount this upkeep could pay for work * @member performSuccess whether the perform was successful * @member triggerType the type of trigger * @member gasUsed gasUsed by this upkeep in perform - * @member gasOverhead gasOverhead for this upkeep + * @member calldataWeight weight assigned to this upkeep for its contribution to calldata. It is used to split L1 fee * @member dedupID unique ID used to dedup an upkeep/trigger combo */ struct UpkeepTransmitInfo { Upkeep upkeep; bool earlyChecksPassed; - uint96 maxLinkPayment; bool performSuccess; Trigger triggerType; uint256 gasUsed; - uint256 gasOverhead; + uint256 calldataWeight; bytes32 dedupID; } @@ -592,18 +599,18 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { * @dev calculates LINK paid for gas spent plus a configure premium percentage * @param gasLimit the amount of gas used * @param gasOverhead the amount of gas overhead + * @param l1CostWei the amount to be charged for L1 fee in wei * @param fastGasWei the fast gas price * @param linkNative the exchange ratio between LINK and Native token - * @param numBatchedUpkeeps the number of upkeeps in this batch. Used to divide the L1 cost * @param isExecution if this is triggered by a perform upkeep function */ function _calculatePaymentAmount( HotVars memory hotVars, uint256 gasLimit, uint256 gasOverhead, + uint256 l1CostWei, uint256 fastGasWei, uint256 linkNative, - uint16 numBatchedUpkeeps, bool isExecution ) internal view returns (uint96, uint96) { uint256 gasWei = fastGasWei * hotVars.gasCeilingMultiplier; @@ -611,17 +618,6 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { if (isExecution && tx.gasprice < gasWei) { gasWei = tx.gasprice; } - - uint256 l1CostWei = 0; - if (isExecution) { - l1CostWei = hotVars.chainModule.getCurrentL1Fee(); - } else { - // if it's not performing upkeeps, use gas ceiling multiplier to estimate the upper bound - l1CostWei = hotVars.gasCeilingMultiplier * hotVars.chainModule.getMaxL1Fee(s_storage.maxPerformDataSize); - } - // Divide l1CostWei among all batched upkeeps. Spare change from division is not charged - l1CostWei = l1CostWei / numBatchedUpkeeps; - uint256 gasPayment = ((gasWei * (gasLimit + gasOverhead) + l1CostWei) * 1e18) / linkNative; uint256 premium = (((gasWei * gasLimit) + l1CostWei) * 1e9 * hotVars.paymentPremiumPPB) / linkNative + @@ -633,50 +629,48 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { } /** - * @dev calculates the max LINK payment for an upkeep + * @dev calculates the max LINK payment for an upkeep. Called during checkUpkeep simulation and assumes + * maximum gas overhead, L1 fee */ function _getMaxLinkPayment( HotVars memory hotVars, Trigger triggerType, uint32 performGas, - uint32 performDataLength, uint256 fastGasWei, - uint256 linkNative, - bool isExecution // Whether this is an actual perform execution or just a simulation + uint256 linkNative ) internal view returns (uint96) { - uint256 gasOverhead = _getMaxGasOverhead(triggerType, performDataLength, hotVars.f); + uint256 maxGasOverhead; + if (triggerType == Trigger.CONDITION) { + maxGasOverhead = REGISTRY_CONDITIONAL_OVERHEAD; + } else if (triggerType == Trigger.LOG) { + maxGasOverhead = REGISTRY_LOG_OVERHEAD; + } else { + revert InvalidTriggerType(); + } + uint256 maxCalldataSize = s_storage.maxPerformDataSize + + TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + + (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); + (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) = s_hotVars.chainModule.getGasOverhead(); + maxGasOverhead += + (REGISTRY_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)) + + ((REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD + chainModulePerByteOverhead) * maxCalldataSize) + + chainModuleFixedOverhead; + + uint256 maxL1Fee = hotVars.gasCeilingMultiplier * hotVars.chainModule.getMaxL1Fee(maxCalldataSize); + (uint96 reimbursement, uint96 premium) = _calculatePaymentAmount( hotVars, performGas, - gasOverhead, + maxGasOverhead, + maxL1Fee, fastGasWei, linkNative, - 1, // Consider only 1 upkeep in batch to get maxPayment - isExecution + false //isExecution ); return reimbursement + premium; } - /** - * @dev returns the max gas overhead that can be charged for an upkeep - */ - function _getMaxGasOverhead(Trigger triggerType, uint32 performDataLength, uint8 f) internal pure returns (uint256) { - // performData causes additional overhead in report length and memory operations - uint256 baseOverhead; - if (triggerType == Trigger.CONDITION) { - baseOverhead = REGISTRY_CONDITIONAL_OVERHEAD; - } else if (triggerType == Trigger.LOG) { - baseOverhead = REGISTRY_LOG_OVERHEAD; - } else { - revert InvalidTriggerType(); - } - return - baseOverhead + - (REGISTRY_PER_SIGNER_GAS_OVERHEAD * (f + 1)) + - (REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD * performDataLength); - } - /** * @dev move a transmitter's balance from total pool to withdrawable balance */ @@ -772,11 +766,6 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { emit CancelledUpkeepReport(upkeepId, rawTrigger); return (false, dedupID); } - if (transmitInfo.upkeep.balance < transmitInfo.maxLinkPayment) { - // Can happen due to fluctuations in gas / link prices - emit InsufficientFundsUpkeepReport(upkeepId, rawTrigger); - return (false, dedupID); - } return (true, dedupID); } @@ -902,45 +891,42 @@ abstract contract AutomationRegistryBase2_2 is ConfirmedOwner { function _postPerformPayment( HotVars memory hotVars, uint256 upkeepId, - UpkeepTransmitInfo memory upkeepTransmitInfo, + uint256 gasUsed, uint256 fastGasWei, uint256 linkNative, - uint16 numBatchedUpkeeps + uint256 gasOverhead, + uint256 l1Fee ) internal returns (uint96 gasReimbursement, uint96 premium) { (gasReimbursement, premium) = _calculatePaymentAmount( hotVars, - upkeepTransmitInfo.gasUsed, - upkeepTransmitInfo.gasOverhead, + gasUsed, + gasOverhead, + l1Fee, fastGasWei, linkNative, - numBatchedUpkeeps, - true + true // isExecution ); + uint96 balance = s_upkeep[upkeepId].balance; uint96 payment = gasReimbursement + premium; + + // this shouldn't happen, but in rare edge cases, we charge the full balance in case the user + // can't cover the amount owed + if (balance < gasReimbursement) { + payment = balance; + gasReimbursement = balance; + premium = 0; + } else if (balance < payment) { + payment = balance; + premium = payment - gasReimbursement; + } + s_upkeep[upkeepId].balance -= payment; s_upkeep[upkeepId].amountSpent += payment; return (gasReimbursement, premium); } - /** - * @dev Caps the gas overhead by the constant overhead used within initial payment checks in order to - * prevent a revert in payment processing. - */ - function _getCappedGasOverhead( - uint256 calculatedGasOverhead, - Trigger triggerType, - uint32 performDataLength, - uint8 f - ) internal pure returns (uint256 cappedGasOverhead) { - cappedGasOverhead = _getMaxGasOverhead(triggerType, performDataLength, f); - if (calculatedGasOverhead < cappedGasOverhead) { - return calculatedGasOverhead; - } - return cappedGasOverhead; - } - /** * @dev ensures the upkeep is not cancelled and the caller is the upkeep admin */ diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol index 4663c172e67..645394e254f 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol @@ -71,15 +71,7 @@ contract AutomationRegistryLogicA2_2 is AutomationRegistryBase2_2, Chainable { if (upkeep.paused) return (false, bytes(""), UpkeepFailureReason.UPKEEP_PAUSED, 0, upkeep.performGas, 0, 0); (fastGasWei, linkNative) = _getFeedData(hotVars); - uint96 maxLinkPayment = _getMaxLinkPayment( - hotVars, - triggerType, - upkeep.performGas, - s_storage.maxPerformDataSize, - fastGasWei, - linkNative, - false - ); + uint96 maxLinkPayment = _getMaxLinkPayment(hotVars, triggerType, upkeep.performGas, fastGasWei, linkNative); if (upkeep.balance < maxLinkPayment) { return (false, bytes(""), UpkeepFailureReason.INSUFFICIENT_BALANCE, 0, upkeep.performGas, 0, 0); } diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol index d7e1edf7bc8..b18f6b66b2f 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol @@ -171,14 +171,6 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { // | OWNER / MANAGER ACTIONS | // ================================================================ - /** - * @notice sets the chain specific module - */ - function setChainSpecificModule(IChainModule newModule) external onlyOwner { - s_hotVars.chainModule = newModule; - emit ChainSpecificModuleUpdated(address(newModule)); - } - /** * @notice sets the privilege config for an upkeep */ @@ -285,6 +277,14 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { return REGISTRY_PER_SIGNER_GAS_OVERHEAD; } + function getTransmitCalldataFixedBytesOverhead() external pure returns (uint256) { + return TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD; + } + + function getTransmitCalldataPerSignerBytesOverhead() external pure returns (uint256) { + return TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD; + } + function getCancellationDelay() external pure returns (uint256) { return CANCELLATION_DELAY; } @@ -499,8 +499,7 @@ contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { function getMaxPaymentForGas(Trigger triggerType, uint32 gasLimit) public view returns (uint96 maxPayment) { HotVars memory hotVars = s_hotVars; (uint256 fastGasWei, uint256 linkNative) = _getFeedData(hotVars); - return - _getMaxLinkPayment(hotVars, triggerType, gasLimit, s_storage.maxPerformDataSize, fastGasWei, linkNative, false); + return _getMaxLinkPayment(hotVars, triggerType, gasLimit, fastGasWei, linkNative); } /** diff --git a/contracts/src/v0.8/tests/MockChainModule.sol b/contracts/src/v0.8/tests/MockChainModule.sol deleted file mode 100644 index 192e86e9a88..00000000000 --- a/contracts/src/v0.8/tests/MockChainModule.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.16; - -import {IChainModule} from "../automation/dev/interfaces/v2_2/IChainModule.sol"; - -contract MockChainModule is IChainModule { - //uint256 internal blockNum; - - function blockNumber() external view returns (uint256) { - return 1256; - } - - function blockHash(uint256 blocknumber) external view returns (bytes32) { - require(1000 >= blocknumber, "block too old"); - - return keccak256(abi.encode(blocknumber)); - } - - function getCurrentL1Fee() external view returns (uint256) { - return 0; - } - - // retrieve the L1 data fee for a L2 simulation. it should return 0 for L1 chains and - // L2 chains which don't have L1 fee component. - function getMaxL1Fee(uint256 dataSize) external view returns (uint256) { - return 0; - } -} diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts index 8d022ddfe64..ef6fe6616ab 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts @@ -37,11 +37,10 @@ import { ChainModuleBase } from '../../../typechain/ChainModuleBase' import { ArbitrumModule } from '../../../typechain/ArbitrumModule' import { OptimismModule } from '../../../typechain/OptimismModule' import { UpkeepTranscoder } from '../../../typechain/UpkeepTranscoder' -import { UpkeepAutoFunder } from '../../../typechain' +import { IChainModule, UpkeepAutoFunder } from '../../../typechain' import { CancelledUpkeepReportEvent, IAutomationRegistryMaster as IAutomationRegistry, - InsufficientFundsUpkeepReportEvent, ReorgedUpkeepReportEvent, StaleUpkeepReportEvent, UpkeepPerformedEvent, @@ -89,11 +88,16 @@ let registryConditionalOverhead: BigNumber let registryLogOverhead: BigNumber let registryPerSignerGasOverhead: BigNumber let registryPerPerformByteGasOverhead: BigNumber +let registryTransmitCalldataFixedBytesOverhead: BigNumber +let registryTransmitCalldataPerSignerBytesOverhead: BigNumber let cancellationDelay: number // This is the margin for gas that we test for. Gas charged should always be greater // than total gas used in tx but should not increase beyond this margin -const gasCalculationMargin = BigNumber.from(8000) +const gasCalculationMargin = BigNumber.from(5000) +// This is the margin for gas overhead estimation in checkUpkeep. The estimated gas +// overhead should be larger than actual gas overhead but should not increase beyond this margin +const gasEstimationMargin = BigNumber.from(5000) const linkEth = BigNumber.from(5000000000000000) // 1 Link = 0.005 Eth const gasWei = BigNumber.from(1000000000) // 1 gwei @@ -111,7 +115,7 @@ const emptyBytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000' const transmitGasOverhead = 1_000_000 -const checkGasOverhead = 400_000 + 3_500 // 3_500 for the overhead to call chain module +const checkGasOverhead = 500_000 const stalenessSeconds = BigNumber.from(43820) const gasCeilingMultiplier = BigNumber.from(2) @@ -355,26 +359,6 @@ const parseStaleUpkeepReportLogs = (receipt: ContractReceipt) => { return parsedLogs } -const parseInsufficientFundsUpkeepReportLogs = (receipt: ContractReceipt) => { - const parsedLogs = [] - for (const rawLog of receipt.logs) { - try { - const log = registry.interface.parseLog(rawLog) - if ( - log.name == - registry.interface.events[ - 'InsufficientFundsUpkeepReport(uint256,bytes)' - ].name - ) { - parsedLogs.push(log as unknown as InsufficientFundsUpkeepReportEvent) - } - } catch { - continue - } - } - return parsedLogs -} - const parseCancelledUpkeepReportLogs = (receipt: ContractReceipt) => { const parsedLogs = [] for (const rawLog of receipt.logs) { @@ -532,6 +516,9 @@ describe('AutomationRegistry2_2', () => { .slice(10) }) + // This function is similar to registry's _calculatePaymentAmount + // It uses global fastGasWei, linkEth, and assumes isExecution = false (gasFee = fastGasWei*multiplier) + // rest of the parameters are the same const linkForGas = ( upkeepGasSpent: BigNumber, gasOverhead: BigNumber, @@ -539,11 +526,8 @@ describe('AutomationRegistry2_2', () => { premiumPPB: BigNumber, flatFee: BigNumber, l1CostWei?: BigNumber, - numUpkeepsBatch?: BigNumber, ) => { l1CostWei = l1CostWei === undefined ? BigNumber.from(0) : l1CostWei - numUpkeepsBatch = - numUpkeepsBatch === undefined ? BigNumber.from(1) : numUpkeepsBatch const gasSpent = gasOverhead.add(BigNumber.from(upkeepGasSpent)) const base = gasWei @@ -551,17 +535,13 @@ describe('AutomationRegistry2_2', () => { .mul(gasSpent) .mul(linkDivisibility) .div(linkEth) - const l1Fee = l1CostWei - .mul(gasMultiplier) - .div(numUpkeepsBatch) - .mul(linkDivisibility) - .div(linkEth) + const l1Fee = l1CostWei.mul(linkDivisibility).div(linkEth) const gasPayment = base.add(l1Fee) const premium = gasWei .mul(gasMultiplier) .mul(upkeepGasSpent) - .add(l1CostWei.mul(gasMultiplier).div(numUpkeepsBatch)) + .add(l1CostWei) .mul(linkDivisibility) .div(linkEth) .mul(premiumPPB) @@ -570,15 +550,15 @@ describe('AutomationRegistry2_2', () => { return { total: gasPayment.add(premium), - gasPaymemnt: gasPayment, + gasPayment, premium, } } const verifyMaxPayment = async ( registry: IAutomationRegistry, - chainModuleAddress: string, - l1CostWei?: BigNumber, + chainModule: IChainModule, + maxl1CostWeWithoutMultiplier?: BigNumber, ) => { type TestCase = { name: string @@ -613,12 +593,36 @@ describe('AutomationRegistry2_2', () => { ] const fPlusOne = BigNumber.from(f + 1) + const chainModuleOverheads = await chainModule.getGasOverhead() const totalConditionalOverhead = registryConditionalOverhead .add(registryPerSignerGasOverhead.mul(fPlusOne)) - .add(registryPerPerformByteGasOverhead.mul(maxPerformDataSize)) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul(fPlusOne), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) + const totalLogOverhead = registryLogOverhead .add(registryPerSignerGasOverhead.mul(fPlusOne)) - .add(registryPerPerformByteGasOverhead.mul(maxPerformDataSize)) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul(fPlusOne), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) for (const test of tests) { await registry.connect(owner).setConfig( @@ -641,7 +645,7 @@ describe('AutomationRegistry2_2', () => { transcoder: transcoder.address, registrars: [], upkeepPrivilegeManager: upkeepManager, - chainModule: chainModuleAddress, + chainModule: chainModule.address, reorgProtectionEnabled: true, }), offchainVersion, @@ -659,7 +663,7 @@ describe('AutomationRegistry2_2', () => { BigNumber.from(test.multiplier), BigNumber.from(test.premium), BigNumber.from(test.flatFee), - l1CostWei, + maxl1CostWeWithoutMultiplier?.mul(BigNumber.from(test.multiplier)), ).total, ) @@ -671,7 +675,7 @@ describe('AutomationRegistry2_2', () => { BigNumber.from(test.multiplier), BigNumber.from(test.premium), BigNumber.from(test.flatFee), - l1CostWei, + maxl1CostWeWithoutMultiplier?.mul(BigNumber.from(test.multiplier)), ).total, ) } @@ -713,7 +717,7 @@ describe('AutomationRegistry2_2', () => { gasLimit?: BigNumberish gasPrice?: BigNumberish performGas?: BigNumberish - performData?: string + performDatas?: string[] checkBlockNum?: number checkBlockHash?: string logBlockHash?: BytesLike @@ -733,7 +737,7 @@ describe('AutomationRegistry2_2', () => { const config = { numSigners: f + 1, startingSignerIndex: 0, - performData: '0x', + performDatas: undefined, performGas, checkBlockNum: latestBlock.number, checkBlockHash: latestBlock.hash, @@ -769,7 +773,7 @@ describe('AutomationRegistry2_2', () => { Id: upkeepIds[i], performGas: config.performGas, trigger, - performData: config.performData, + performData: config.performDatas ? config.performDatas[i] : '0x', }) } @@ -977,6 +981,10 @@ describe('AutomationRegistry2_2', () => { registryPerSignerGasOverhead = await registry.getPerSignerGasOverhead() registryPerPerformByteGasOverhead = await registry.getPerPerformByteGasOverhead() + registryTransmitCalldataFixedBytesOverhead = + await registry.getTransmitCalldataFixedBytesOverhead() + registryTransmitCalldataPerSignerBytesOverhead = + await registry.getTransmitCalldataPerSignerBytesOverhead() cancellationDelay = (await registry.getCancellationDelay()).toNumber() await registry.connect(owner).setConfig(...baseConfig) @@ -1150,33 +1158,16 @@ describe('AutomationRegistry2_2', () => { assert.equal(cancelledUpkeepReportLogs.length, 1) }) - it('returns early when upkeep has insufficient funds', async () => { + it('performs even when the upkeep has insufficient funds and the upkeep pays out all the remaining balance', async () => { + // add very little fund to this upkeep + await registry.connect(admin).addFunds(upkeepId, BigNumber.from(10)) const tx = await getTransmitTx(registry, keeper1, [upkeepId]) const receipt = await tx.wait() - const insufficientFundsUpkeepReportLogs = - parseInsufficientFundsUpkeepReportLogs(receipt) - // exactly 1 InsufficientFundsUpkeepReportLogs log should be emitted - assert.equal(insufficientFundsUpkeepReportLogs.length, 1) - }) - - it('permits retrying log triggers after funds are added', async () => { - const txHash = ethers.utils.randomBytes(32) - let tx = await getTransmitTx(registry, keeper1, [logUpkeepId], { - txHash, - logIndex: 0, - }) - let receipt = await tx.wait() - const insufficientFundsLogs = - parseInsufficientFundsUpkeepReportLogs(receipt) - assert.equal(insufficientFundsLogs.length, 1) - registry.connect(admin).addFunds(logUpkeepId, toWei('100')) - tx = await getTransmitTx(registry, keeper1, [logUpkeepId], { - txHash, - logIndex: 0, - }) - receipt = await tx.wait() - const performedLogs = parseUpkeepPerformedLogs(receipt) - assert.equal(performedLogs.length, 1) + // the upkeep is underfunded in transmit but still performed + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(upkeepPerformedLogs.length, 1) + const balance = (await registry.getUpkeep(upkeepId)).balance + assert.equal(balance.toNumber(), 0) }) context('When the upkeep is funded', async () => { @@ -1330,6 +1321,81 @@ describe('AutomationRegistry2_2', () => { } }) + it('allows bypassing reorg protection with reorgProtectionEnabled false config', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + let newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number - 1, + checkBlockHash: latestBlock.hash, // should be latestBlock.parentHash + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows very old trigger block numbers when bypassing reorg protection with reorgProtectionEnabled config', async () => { + let newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + for (let i = 0; i < 256; i++) { + await ethers.provider.send('evm_mine', []) + } + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + const old = await ethers.provider.getBlock(latestBlock.number - 256) + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: old.number, + checkBlockHash: old.hash, + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + it('allows very old trigger block numbers when bypassing reorg protection with empty blockhash', async () => { // mine enough blocks so that blockhash(1) is unavailable for (let i = 0; i <= 256; i++) { @@ -1392,6 +1458,56 @@ describe('AutomationRegistry2_2', () => { } }) + it('returns early when future block number is provided as trigger, irrespective of reorgProtectionEnabled config', async () => { + let newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + + // Should fail when blockhash is empty + let tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: emptyBytes32, + }) + let receipt = await tx.wait() + let reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + + // Should also fail when blockhash is not empty + tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: latestBlock.hash, + }) + receipt = await tx.wait() + reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + it('returns early when upkeep is cancelled and cancellation delay has gone', async () => { const latestBlockReport = await makeLatestBlockReport([upkeepId]) await registry.connect(admin).cancelUpkeep(upkeepId) @@ -1456,7 +1572,7 @@ describe('AutomationRegistry2_2', () => { await mock.setCanPerform(true) const tx = await getTransmitTx(registry, keeper1, [upkeepId], { - performData: randomBytes, + performDatas: [randomBytes], }) const receipt = await tx.wait() @@ -1591,7 +1707,7 @@ describe('AutomationRegistry2_2', () => { gasCeilingMultiplier, paymentPremiumPPB, flatFeeMicroLink, - l1CostWeiArb.div(gasCeilingMultiplier), // Dividing by gasCeilingMultiplier as it gets multiplied later + l1CostWeiArb, ).total.toString(), totalPayment.toString(), ) @@ -1763,7 +1879,7 @@ describe('AutomationRegistry2_2', () => { await getTransmitTx(registry, keeper1, [testUpkeepId], { gasLimit: maxPerformGas.add(transmitGasOverhead), numSigners: 11, - performData, + performDatas: [performData], }) // Should not revert }, ) @@ -1884,7 +2000,7 @@ describe('AutomationRegistry2_2', () => { }, ) - describe.skip('Gas benchmarking conditional upkeeps [ @skip-coverage ]', function () { + describe('Gas benchmarking conditional upkeeps [ @skip-coverage ]', function () { const fs = [1, 10] fs.forEach(function (newF) { it( @@ -1904,6 +2020,8 @@ describe('AutomationRegistry2_2', () => { const upkeepSuccessArray = [true, false] const performGasArray = [5000, performGas] const performDataArray = ['0x', longBytes] + const chainModuleOverheads = + await chainModuleBase.getGasOverhead() for (const i in upkeepSuccessArray) { for (const j in performGasArray) { @@ -1926,7 +2044,7 @@ describe('AutomationRegistry2_2', () => { ) tx = await getTransmitTx(registry, keeper1, [upkeepId], { numSigners: newF + 1, - performData, + performDatas: [performData], }) const receipt = await tx.wait() const upkeepPerformedLogs = @@ -1939,9 +2057,30 @@ describe('AutomationRegistry2_2', () => { const chargedGasOverhead = upkeepPerformedLog.args.gasOverhead const actualGasOverhead = receipt.gasUsed.sub(upkeepGasUsed) + const estimatedGasOverhead = registryConditionalOverhead + .add( + registryPerSignerGasOverhead.mul( + BigNumber.from(newF + 1), + ), + ) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + BigNumber.from(performData.length / 2 - 1) + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(newF + 1), + ), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) assert.isTrue(upkeepGasUsed.gt(BigNumber.from('0'))) assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(actualGasOverhead.gt(BigNumber.from('0'))) console.log( 'Gas Benchmarking conditional upkeeps:', @@ -1953,51 +2092,58 @@ describe('AutomationRegistry2_2', () => { performData.length / 2 - 1, 'sig verification ( f =', newF, - '): calculated overhead: ', + '): estimated overhead: ', + estimatedGasOverhead.toString(), + ' charged overhead: ', chargedGasOverhead.toString(), ' actual overhead: ', actualGasOverhead.toString(), - ' margin over gasUsed: ', + ' calculation margin over gasUsed: ', chargedGasOverhead.sub(actualGasOverhead).toString(), + ' estimation margin over gasUsed: ', + estimatedGasOverhead.sub(actualGasOverhead).toString(), ) - // Overhead should not get capped - const gasOverheadCap = registryConditionalOverhead - .add( - registryPerSignerGasOverhead.mul( - BigNumber.from(newF + 1), - ), - ) - .add( - BigNumber.from( - registryPerPerformByteGasOverhead.toNumber() * - performData.length, - ), - ) - const gasCapMinusOverhead = - gasOverheadCap.sub(chargedGasOverhead) - assert.isTrue( - gasCapMinusOverhead.gt(BigNumber.from(0)), - 'Gas overhead got capped. Verify gas overhead variables in test match those in the registry. To not have the overheads capped increase REGISTRY_GAS_OVERHEAD by atleast ' + - gasCapMinusOverhead.toString(), - ) - // total gas charged should be greater than tx gas but within gasCalculationMargin + // The actual gas overhead should be less than charged gas overhead, but not by a lot + // The charged gas overhead is controlled by ACCOUNTING_FIXED_GAS_OVERHEAD and + // ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD, and their correct values should be set to + // satisfy constraints in multiple places assert.isTrue( chargedGasOverhead.gt(actualGasOverhead), - 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by atleast ' + + 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD) by at least ' + actualGasOverhead.sub(chargedGasOverhead).toString(), ) - assert.isTrue( chargedGasOverhead .sub(actualGasOverhead) .lt(gasCalculationMargin), - ), - 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by atleast ' + + 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by at least ' + chargedGasOverhead - .sub(chargedGasOverhead) + .sub(actualGasOverhead) .sub(gasCalculationMargin) - .toString() + .toString(), + ) + + // The estimated overhead during checkUpkeep should be close to the actual overhead in transaction + // It should be greater than the actual overhead but not by a lot + // The estimated overhead is controlled by variables + // REGISTRY_CONDITIONAL_OVERHEAD, REGISTRY_LOG_OVERHEAD, REGISTRY_PER_SIGNER_GAS_OVERHEAD + // REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD + assert.isTrue( + estimatedGasOverhead.gt(actualGasOverhead), + 'Gas overhead estimated in check upkeep is too low, increase estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead.sub(chargedGasOverhead).toString(), + ) + assert.isTrue( + estimatedGasOverhead + .sub(actualGasOverhead) + .lt(gasEstimationMargin), + 'Gas overhead estimated is too high, decrease estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead + .sub(actualGasOverhead) + .sub(gasEstimationMargin) + .toString(), + ) } } } @@ -2006,7 +2152,7 @@ describe('AutomationRegistry2_2', () => { }) }) - describe.skip('Gas benchmarking log upkeeps [ @skip-coverage ]', function () { + describe('Gas benchmarking log upkeeps [ @skip-coverage ]', function () { const fs = [1, 10] fs.forEach(function (newF) { it( @@ -2030,20 +2176,39 @@ describe('AutomationRegistry2_2', () => { ) tx = await getTransmitTx(registry, keeper1, [logUpkeepId], { numSigners: newF + 1, - performData, + performDatas: [performData], }) const receipt = await tx.wait() const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) // exactly 1 Upkeep Performed should be emitted assert.equal(upkeepPerformedLogs.length, 1) const upkeepPerformedLog = upkeepPerformedLogs[0] + const chainModuleOverheads = + await chainModuleBase.getGasOverhead() const upkeepGasUsed = upkeepPerformedLog.args.gasUsed const chargedGasOverhead = upkeepPerformedLog.args.gasOverhead const actualGasOverhead = receipt.gasUsed.sub(upkeepGasUsed) + const estimatedGasOverhead = registryLogOverhead + .add(registryPerSignerGasOverhead.mul(BigNumber.from(newF + 1))) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + BigNumber.from(performData.length / 2 - 1) + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(newF + 1), + ), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) assert.isTrue(upkeepGasUsed.gt(BigNumber.from('0'))) assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(actualGasOverhead.gt(BigNumber.from('0'))) console.log( 'Gas Benchmarking log upkeeps:', @@ -2055,46 +2220,49 @@ describe('AutomationRegistry2_2', () => { performData.length / 2 - 1, 'sig verification ( f =', newF, - '): calculated overhead: ', + '): estimated overhead: ', + estimatedGasOverhead.toString(), + ' charged overhead: ', chargedGasOverhead.toString(), ' actual overhead: ', actualGasOverhead.toString(), - ' margin over gasUsed: ', + ' calculation margin over gasUsed: ', chargedGasOverhead.sub(actualGasOverhead).toString(), + ' estimation margin over gasUsed: ', + estimatedGasOverhead.sub(actualGasOverhead).toString(), ) - // Overhead should not get capped - const gasOverheadCap = registryLogOverhead - .add(registryPerSignerGasOverhead.mul(BigNumber.from(newF + 1))) - .add( - BigNumber.from( - registryPerPerformByteGasOverhead.toNumber() * - performData.length, - ), - ) - const gasCapMinusOverhead = gasOverheadCap.sub(chargedGasOverhead) - assert.isTrue( - gasCapMinusOverhead.gt(BigNumber.from(0)), - 'Gas overhead got capped. Verify gas overhead variables in test match those in the registry. To not have the overheads capped increase REGISTRY_GAS_OVERHEAD by atleast ' + - gasCapMinusOverhead.toString(), - ) - // total gas charged should be greater than tx gas but within gasCalculationMargin assert.isTrue( chargedGasOverhead.gt(actualGasOverhead), - 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by atleast ' + + 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD) by at least ' + actualGasOverhead.sub(chargedGasOverhead).toString(), ) - assert.isTrue( chargedGasOverhead .sub(actualGasOverhead) .lt(gasCalculationMargin), - ), - 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by atleast ' + + 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by at least ' + chargedGasOverhead - .sub(chargedGasOverhead) + .sub(actualGasOverhead) .sub(gasCalculationMargin) - .toString() + .toString(), + ) + + assert.isTrue( + estimatedGasOverhead.gt(actualGasOverhead), + 'Gas overhead estimated in check upkeep is too low, increase estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead.sub(chargedGasOverhead).toString(), + ) + assert.isTrue( + estimatedGasOverhead + .sub(actualGasOverhead) + .lt(gasEstimationMargin), + 'Gas overhead estimated is too high, decrease estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead + .sub(actualGasOverhead) + .sub(gasEstimationMargin) + .toString(), + ) }, ) }) @@ -2102,7 +2270,7 @@ describe('AutomationRegistry2_2', () => { }) }) - describe.skip('#transmit with upkeep batches [ @skip-coverage ]', function () { + describe('#transmit with upkeep batches [ @skip-coverage ]', function () { const numPassingConditionalUpkeepsArray = [0, 1, 5] const numPassingLogUpkeepsArray = [0, 1, 5] const numFailingUpkeepsArray = [0, 3] @@ -2169,6 +2337,14 @@ describe('AutomationRegistry2_2', () => { }), ) + // cancel upkeeps so they will fail in the transmit process + // must call the cancel upkeep as the owner to avoid the CANCELLATION_DELAY + for (let ldx = 0; ldx < failingUpkeepIds.length; ldx++) { + await registry + .connect(owner) + .cancelUpkeep(failingUpkeepIds[ldx]) + } + const tx = await getTransmitTx( registry, keeper1, @@ -2184,10 +2360,10 @@ describe('AutomationRegistry2_2', () => { upkeepPerformedLogs.length, numPassingConditionalUpkeeps + numPassingLogUpkeeps, ) - const insufficientFundsLogs = - parseInsufficientFundsUpkeepReportLogs(receipt) + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) // exactly numFailingUpkeeps Upkeep Performed should be emitted - assert.equal(insufficientFundsLogs.length, numFailingUpkeeps) + assert.equal(cancelledUpkeepReportLogs.length, numFailingUpkeeps) const keeperAfter = await registry.getTransmitterInfo( await keeper1.getAddress(), @@ -2304,8 +2480,8 @@ describe('AutomationRegistry2_2', () => { } for (let i = 0; i < numFailingUpkeeps; i++) { - // InsufficientFunds log should be emitted - const id = insufficientFundsLogs[i].args.id + // CancelledUpkeep log should be emitted + const id = cancelledUpkeepReportLogs[i].args.id expect(id).to.equal(failingUpkeepIds[i]) // Balance and amount spent should be same @@ -2373,6 +2549,14 @@ describe('AutomationRegistry2_2', () => { await tx.wait() + // cancel upkeeps so they will fail in the transmit process + // must call the cancel upkeep as the owner to avoid the CANCELLATION_DELAY + for (let ldx = 0; ldx < failingUpkeepIds.length; ldx++) { + await registry + .connect(owner) + .cancelUpkeep(failingUpkeepIds[ldx]) + } + // Do the actual thing tx = await getTransmitTx( @@ -2391,81 +2575,47 @@ describe('AutomationRegistry2_2', () => { numPassingConditionalUpkeeps + numPassingLogUpkeeps, ) - const gasConditionalOverheadCap = registryConditionalOverhead.add( - registryPerSignerGasOverhead.mul(BigNumber.from(f + 1)), - ) - const gasLogOverheadCap = registryLogOverhead.add( - registryPerSignerGasOverhead.mul(BigNumber.from(f + 1)), - ) - - const overheadCanGetCapped = - numFailingUpkeeps > 0 && - numPassingConditionalUpkeeps <= 1 && - numPassingLogUpkeeps <= 1 - // Can happen if there are failing upkeeps and only 1 successful upkeep of each type - let netGasUsedPlusOverhead = BigNumber.from('0') - + let netGasUsedPlusChargedOverhead = BigNumber.from('0') for (let i = 0; i < numPassingConditionalUpkeeps; i++) { const gasUsed = upkeepPerformedLogs[i].args.gasUsed - const gasOverhead = upkeepPerformedLogs[i].args.gasOverhead + const chargedGasOverhead = + upkeepPerformedLogs[i].args.gasOverhead assert.isTrue(gasUsed.gt(BigNumber.from('0'))) - assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) - - // Overhead should not exceed capped - assert.isTrue(gasOverhead.lte(gasConditionalOverheadCap)) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) - // Overhead should be same for every upkeep since they have equal performData, hence same caps + // Overhead should be same for every upkeep assert.isTrue( - gasOverhead.eq(upkeepPerformedLogs[0].args.gasOverhead), + chargedGasOverhead.eq( + upkeepPerformedLogs[0].args.gasOverhead, + ), ) - - netGasUsedPlusOverhead = netGasUsedPlusOverhead + netGasUsedPlusChargedOverhead = netGasUsedPlusChargedOverhead .add(gasUsed) - .add(gasOverhead) + .add(chargedGasOverhead) } + for (let i = 0; i < numPassingLogUpkeeps; i++) { const gasUsed = upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args .gasUsed - const gasOverhead = + const chargedGasOverhead = upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args .gasOverhead assert.isTrue(gasUsed.gt(BigNumber.from('0'))) - assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) - - // Overhead should not exceed capped - assert.isTrue(gasOverhead.lte(gasLogOverheadCap)) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) - // Overhead should be same for every upkeep since they have equal performData, hence same caps + // Overhead should be same for every upkeep assert.isTrue( - gasOverhead.eq( + chargedGasOverhead.eq( upkeepPerformedLogs[numPassingConditionalUpkeeps].args .gasOverhead, ), ) - - netGasUsedPlusOverhead = netGasUsedPlusOverhead + netGasUsedPlusChargedOverhead = netGasUsedPlusChargedOverhead .add(gasUsed) - .add(gasOverhead) - } - - const overheadsGotCapped = - (numPassingConditionalUpkeeps > 0 && - upkeepPerformedLogs[0].args.gasOverhead.eq( - gasConditionalOverheadCap, - )) || - (numPassingLogUpkeeps > 0 && - upkeepPerformedLogs[ - numPassingConditionalUpkeeps - ].args.gasOverhead.eq(gasLogOverheadCap)) - // Should only get capped in certain scenarios - if (overheadsGotCapped) { - assert.isTrue( - overheadCanGetCapped, - 'Gas overhead got capped. Verify gas overhead variables in test match those in the registry. To not have the overheads capped increase REGISTRY_GAS_OVERHEAD', - ) + .add(chargedGasOverhead) } console.log( @@ -2476,33 +2626,27 @@ describe('AutomationRegistry2_2', () => { 'failedUpkeeps:', numFailingUpkeeps, '): ', - 'overheadsGotCapped', - overheadsGotCapped, numPassingConditionalUpkeeps > 0 - ? 'calculated conditional overhead' + ? 'charged conditional overhead' : '', numPassingConditionalUpkeeps > 0 ? upkeepPerformedLogs[0].args.gasOverhead.toString() : '', - numPassingLogUpkeeps > 0 ? 'calculated log overhead' : '', + numPassingLogUpkeeps > 0 ? 'charged log overhead' : '', numPassingLogUpkeeps > 0 ? upkeepPerformedLogs[ numPassingConditionalUpkeeps ].args.gasOverhead.toString() : '', ' margin over gasUsed', - netGasUsedPlusOverhead.sub(receipt.gasUsed).toString(), + netGasUsedPlusChargedOverhead.sub(receipt.gasUsed).toString(), ) - // If overheads dont get capped then total gas charged should be greater than tx gas - // We don't check whether the net is within gasMargin as the margin changes with numFailedUpkeeps - // Which is ok, as long as individual gas overhead is capped - if (!overheadsGotCapped) { - assert.isTrue( - netGasUsedPlusOverhead.gt(receipt.gasUsed), - 'Gas overhead is too low, increase ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD', - ) - } + // The total gas charged should be greater than tx gas + assert.isTrue( + netGasUsedPlusChargedOverhead.gt(receipt.gasUsed), + 'Charged gas overhead is too low for batch upkeeps, increase ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD', + ) }, ) } @@ -2544,9 +2688,13 @@ describe('AutomationRegistry2_2', () => { }) }) - it('splits l2 payment among performed upkeeps', async () => { + it('splits l2 payment among performed upkeeps according to perform data weight', async () => { const numUpkeeps = 7 const upkeepIds: BigNumber[] = [] + const performDataSizes = [0, 10, 1000, 50, 33, 69, 420] + const performDatas: string[] = [] + const upkeepCalldataWeights: BigNumber[] = [] + let totalCalldataWeight = BigNumber.from('0') // Same as MockArbGasInfo.sol const l1CostWeiArb = BigNumber.from(1000000) @@ -2562,41 +2710,54 @@ describe('AutomationRegistry2_2', () => { // Add funds to passing upkeeps await arbRegistry.connect(owner).addFunds(testUpkeepId, toWei('100')) + + // Generate performData + let pd = '0x' + for (let j = 0; j < performDataSizes[i]; j++) { + pd += '11' + } + performDatas.push(pd) + const w = BigNumber.from(performDataSizes[i]) + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ) + upkeepCalldataWeights.push(w) + totalCalldataWeight = totalCalldataWeight.add(w) } // Do the thing - const tx = await getTransmitTx( - arbRegistry, - keeper1, - upkeepIds, - - { gasPrice: gasWei.mul('5') }, // High gas price so that it gets capped - ) + const tx = await getTransmitTx(arbRegistry, keeper1, upkeepIds, { + gasPrice: gasWei.mul('5'), // High gas price so that it gets capped + performDatas, + }) const receipt = await tx.wait() const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) // exactly numPassingUpkeeps Upkeep Performed should be emitted assert.equal(upkeepPerformedLogs.length, numUpkeeps) - // Verify the payment calculation in upkeepPerformed[0] - const upkeepPerformedLog = upkeepPerformedLogs[0] + for (let i = 0; i < numUpkeeps; i++) { + const upkeepPerformedLog = upkeepPerformedLogs[i] - const gasUsed = upkeepPerformedLog.args.gasUsed - const gasOverhead = upkeepPerformedLog.args.gasOverhead - const totalPayment = upkeepPerformedLog.args.totalPayment + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment - assert.equal( - linkForGas( - gasUsed, - gasOverhead, - gasCeilingMultiplier, - paymentPremiumPPB, - flatFeeMicroLink, - l1CostWeiArb.div(gasCeilingMultiplier), // Dividing by gasCeilingMultiplier as it gets multiplied later - BigNumber.from(numUpkeeps), - ).total.toString(), - totalPayment.toString(), - ) + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + gasCeilingMultiplier, + paymentPremiumPPB, + flatFeeMicroLink, + l1CostWeiArb.mul(upkeepCalldataWeights[i]).div(totalCalldataWeight), + ).total.toString(), + totalPayment.toString(), + ) + } }) }) @@ -2714,70 +2875,45 @@ describe('AutomationRegistry2_2', () => { }) it('uses maxPerformData size in checkUpkeep but actual performDataSize in transmit', async () => { - const tx1 = await registry - .connect(owner) - [ - 'registerUpkeep(address,uint32,address,bytes,bytes)' - ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') - const upkeepID1 = await getUpkeepID(tx1) - const tx2 = await registry + const tx = await registry .connect(owner) [ 'registerUpkeep(address,uint32,address,bytes,bytes)' ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') - const upkeepID2 = await getUpkeepID(tx2) + const upkeepID = await getUpkeepID(tx) await mock.setCanCheck(true) await mock.setCanPerform(true) - // upkeep 1 is underfunded, 2 is fully funded - const minBalance1 = ( - await registry.getMinBalanceForUpkeep(upkeepID1) - ).sub(1) - const minBalance2 = await registry.getMinBalanceForUpkeep(upkeepID2) - await registry.connect(owner).addFunds(upkeepID1, minBalance1) - await registry.connect(owner).addFunds(upkeepID2, minBalance2) + // upkeep is underfunded by 1 wei + const minBalance1 = (await registry.getMinBalanceForUpkeep(upkeepID)).sub( + 1, + ) + await registry.connect(owner).addFunds(upkeepID, minBalance1) - // upkeep 1 check should return false, 2 should return true + // upkeep check should return false, 2 should return true let checkUpkeepResult = await registry .connect(zeroAddress) - .callStatic['checkUpkeep(uint256)'](upkeepID1) + .callStatic['checkUpkeep(uint256)'](upkeepID) assert.equal(checkUpkeepResult.upkeepNeeded, false) assert.equal( checkUpkeepResult.upkeepFailureReason, UpkeepFailureReason.INSUFFICIENT_BALANCE, ) - checkUpkeepResult = await registry - .connect(zeroAddress) - .callStatic['checkUpkeep(uint256)'](upkeepID2) - assert.equal(checkUpkeepResult.upkeepNeeded, true) - - // upkeep 1 perform should return with insufficient balance using max performData size + // however upkeep should perform and pay all the remaining balance let maxPerformData = '0x' for (let i = 0; i < maxPerformDataSize.toNumber(); i++) { maxPerformData += '11' } - const tx = await getTransmitTx(registry, keeper1, [upkeepID1], { + const tx2 = await getTransmitTx(registry, keeper1, [upkeepID], { gasPrice: gasWei.mul(gasCeilingMultiplier), - performData: maxPerformData, + performDatas: [maxPerformData], }) - const receipt = await tx.wait() - const insufficientFundsUpkeepReportLogs = - parseInsufficientFundsUpkeepReportLogs(receipt) - // exactly 1 InsufficientFundsUpkeepReportLogs log should be emitted - assert.equal(insufficientFundsUpkeepReportLogs.length, 1) - - // upkeep 1 perform should succeed with empty performData - await getTransmitTx(registry, keeper1, [upkeepID1], { - gasPrice: gasWei.mul(gasCeilingMultiplier), - }) - // upkeep 2 perform should succeed with max performData size - await getTransmitTx(registry, keeper1, [upkeepID2], { - gasPrice: gasWei.mul(gasCeilingMultiplier), - performData: maxPerformData, - }) + const receipt = await tx2.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(upkeepPerformedLogs.length, 1) }) }) @@ -3280,27 +3416,66 @@ describe('AutomationRegistry2_2', () => { }) describe('#getMaxPaymentForGas', () => { - const arbL1PriceinWei = BigNumber.from(1000) // Same as MockArbGasInfo.sol - const l1CostWeiArb = arbL1PriceinWei.mul(16).mul(maxPerformDataSize) - const l1CostWeiOpt = BigNumber.from(2000000) // Same as MockOVMGasPriceOracle.sol + let maxl1CostWeiArbWithoutMultiplier: BigNumber + let maxl1CostWeiOptWithoutMultiplier: BigNumber + + beforeEach(async () => { + const arbL1PriceinWei = BigNumber.from(1000) // Same as MockArbGasInfo.sol + maxl1CostWeiArbWithoutMultiplier = arbL1PriceinWei + .mul(16) + .mul( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ), + ) + maxl1CostWeiOptWithoutMultiplier = BigNumber.from(2000000) // Same as MockOVMGasPriceOracle.sol + }) + itMaybe('calculates the max fee appropriately', async () => { - await verifyMaxPayment(registry, chainModuleBase.address) + await verifyMaxPayment(registry, chainModuleBase) }) itMaybe('calculates the max fee appropriately for Arbitrum', async () => { - await verifyMaxPayment(arbRegistry, arbitrumModule.address, l1CostWeiArb) + await verifyMaxPayment( + arbRegistry, + arbitrumModule, + maxl1CostWeiArbWithoutMultiplier, + ) }) itMaybe('calculates the max fee appropriately for Optimism', async () => { - await verifyMaxPayment(opRegistry, optimismModule.address, l1CostWeiOpt) + await verifyMaxPayment( + opRegistry, + optimismModule, + maxl1CostWeiOptWithoutMultiplier, + ) }) it('uses the fallback gas price if the feed has issues', async () => { + const chainModuleOverheads = await chainModuleBase.getGasOverhead() const expectedFallbackMaxPayment = linkForGas( performGas, registryConditionalOverhead .add(registryPerSignerGasOverhead.mul(f + 1)) - .add(maxPerformDataSize.mul(registryPerPerformByteGasOverhead)), + .add( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ) + .mul( + registryPerPerformByteGasOverhead.add( + chainModuleOverheads.chainModulePerByteOverhead, + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead), gasCeilingMultiplier.mul('2'), // fallbackGasPrice is 2x gas price paymentPremiumPPB, flatFeeMicroLink, @@ -3354,11 +3529,26 @@ describe('AutomationRegistry2_2', () => { }) it('uses the fallback link price if the feed has issues', async () => { + const chainModuleOverheads = await chainModuleBase.getGasOverhead() const expectedFallbackMaxPayment = linkForGas( performGas, registryConditionalOverhead .add(registryPerSignerGasOverhead.mul(f + 1)) - .add(maxPerformDataSize.mul(registryPerPerformByteGasOverhead)), + .add( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ) + .mul( + registryPerPerformByteGasOverhead.add( + chainModuleOverheads.chainModulePerByteOverhead, + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead), gasCeilingMultiplier.mul('2'), // fallbackLinkPrice is 1/2 link price, so multiply by 2 paymentPremiumPPB, flatFeeMicroLink, diff --git a/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go similarity index 73% rename from core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go rename to core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go index 942459c7eda..9d0abfc6252 100644 --- a/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_2/keeper_registry_logic_a_wrapper_2_2.go +++ b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package keeper_registry_logic_a_wrapper_2_2 +package automation_registry_logic_a_wrapper_2_2 import ( "errors" @@ -31,8 +31,8 @@ var ( ) var AutomationRegistryLogicAMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b5060405162005e7538038062005e758339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051615a386200043d6000396000818161010e01526101a90152600061313b0152600081816103e101526120130152600061332401526000613408015260008181611e5501526124210152615a386000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b620001653660046200401b565b62000313565b6040519081526020015b60405180910390f35b620001956200018f36600462004101565b6200068d565b60405162000175949392919062004229565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b620001526200020036600462004266565b62000931565b6200016b62000217366004620042b6565b62000999565b620002346200022e36600462004101565b620009ff565b60405162000175979695949392919062004369565b6200015262001162565b6200015262000264366004620043bb565b62001265565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a36600462004448565b62001ed6565b62000152620002b1366004620044ab565b6200225e565b62000152620002c8366004620044da565b620024f1565b62000195620002df366004620045b0565b6200293c565b62000152620002f636600462004627565b62002a02565b620002346200030d366004620044da565b62002a1a565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200034757506200034560093362002a58565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d98662002a8c565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003da7565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002d389050565b6015805474010000000000000000000000000000000000000000900463ffffffff169060146200054f8362004676565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c892919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d878760405162000604929190620046e5565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063e9190620046fb565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf485084604051620006789190620046fb565b60405180910390a25098975050505050505050565b600060606000806200069e62003123565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007de91906200471d565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff16896040516200082091906200473d565b60006040518083038160008787f1925050503d806000811462000860576040519150601f19603f3d011682016040523d82523d6000602084013e62000865565b606091505b50915091505a6200087790856200475b565b935081620008a257600060405180602001604052806000815250600796509650965050505062000928565b80806020019051810190620008b89190620047cc565b909750955086620008e657600060405180602001604052806000815250600496509650965050505062000928565b601654865164010000000090910463ffffffff1610156200092457600060405180602001604052806000815250600596509650965050505062000928565b5050505b92959194509250565b6200093c8362003195565b6000838152601b6020526040902062000957828483620048c1565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098c929190620046e5565b60405180910390a2505050565b6000620009f388888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a1562003123565b600062000a228a6200324b565b905060006012604051806101600160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160189054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201601b9054906101000a900461ffff1661ffff1661ffff16815260200160008201601d9054906101000a900460ff1660ff1660ff16815260200160008201601e9054906101000a900460ff1615151515815260200160008201601f9054906101000a900460ff161515151581526020016001820160009054906101000a900460ff161515151581526020016001820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160e001511562000db7576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001156565b604081015163ffffffff9081161462000e08576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001156565b80511562000e4e576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001156565b62000e598262003301565b602083015160165492975090955060009162000e8b918591879190640100000000900463ffffffff168a8a87620034f3565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000ef5576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001156565b600062000f048e868f62003544565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f5c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f8291906200471d565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168460405162000fc491906200473d565b60006040518083038160008787f1925050503d806000811462001004576040519150601f19603f3d011682016040523d82523d6000602084013e62001009565b606091505b50915091505a6200101b908c6200475b565b9a50816200109b5760165481516801000000000000000090910463ffffffff1610156200107857505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200115692505050565b602090940151939b5060039a505063ffffffff9092169650620011569350505050565b80806020019051810190620010b19190620047cc565b909e509c508d620010f257505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200115692505050565b6016548d5164010000000090910463ffffffff1610156200114357505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200115692505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff163314620011e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012a457620012a4620041be565b14158015620012f05750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012ed57620012ed620041be565b14155b1562001328576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001388576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003620013c4576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff8111156200141b576200141b62003ea2565b60405190808252806020026020018201604052801562001445578160200160208202803683370190505b50905060008667ffffffffffffffff81111562001466576200146662003ea2565b604051908082528060200260200182016040528015620014ed57816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181620014855790505b50905060008767ffffffffffffffff8111156200150e576200150e62003ea2565b6040519080825280602002602001820160405280156200154357816020015b60608152602001906001900390816200152d5790505b50905060008867ffffffffffffffff81111562001564576200156462003ea2565b6040519080825280602002602001820160405280156200159957816020015b6060815260200190600190039081620015835790505b50905060008967ffffffffffffffff811115620015ba57620015ba62003ea2565b604051908082528060200260200182016040528015620015ef57816020015b6060815260200190600190039081620015d95790505b50905060005b8a81101562001bd3578b8b82818110620016135762001613620049e9565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a50909850620016f290508962003195565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200176257600080fd5b505af115801562001777573d6000803e3d6000fd5b5050505087858281518110620017915762001791620049e9565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868281518110620017e557620017e5620049e9565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a81526007909152604090208054620018249062004819565b80601f0160208091040260200160405190810160405280929190818152602001828054620018529062004819565b8015620018a35780601f106200187757610100808354040283529160200191620018a3565b820191906000526020600020905b8154815290600101906020018083116200188557829003601f168201915b5050505050848281518110620018bd57620018bd620049e9565b6020026020010181905250601b60008a81526020019081526020016000208054620018e89062004819565b80601f0160208091040260200160405190810160405280929190818152602001828054620019169062004819565b8015620019675780601f106200193b5761010080835404028352916020019162001967565b820191906000526020600020905b8154815290600101906020018083116200194957829003601f168201915b5050505050838281518110620019815762001981620049e9565b6020026020010181905250601c60008a81526020019081526020016000208054620019ac9062004819565b80601f0160208091040260200160405190810160405280929190818152602001828054620019da9062004819565b801562001a2b5780601f10620019ff5761010080835404028352916020019162001a2b565b820191906000526020600020905b81548152906001019060200180831162001a0d57829003601f168201915b505050505082828151811062001a455762001a45620049e9565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a70919062004a18565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001ae6919062003db5565b6000898152601b6020526040812062001aff9162003db5565b6000898152601c6020526040812062001b189162003db5565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b5960028a62003766565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001bca8162004a2e565b915050620015f5565b508560195462001be491906200475b565b60195560008b8b868167ffffffffffffffff81111562001c085762001c0862003ea2565b60405190808252806020026020018201604052801562001c32578160200160208202803683370190505b508988888860405160200162001c5098979695949392919062004bd4565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6014600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001d0c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d32919062004ca4565b866040518463ffffffff1660e01b815260040162001d539392919062004cc9565b600060405180830381865afa15801562001d71573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001db9919081019062004cf0565b6040518263ffffffff1660e01b815260040162001dd79190620046fb565b600060405180830381600087803b15801562001df257600080fd5b505af115801562001e07573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001ea1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ec7919062004d29565b50505050505050505050505050565b6002336000908152601a602052604090205460ff16600381111562001eff5762001eff620041be565b1415801562001f3557506003336000908152601a602052604090205460ff16600381111562001f325762001f32620041be565b14155b1562001f6d576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f83888a018a62004f21565b965096509650965096509650965060005b87518110156200225257600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001fcb5762001fcb620049e9565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020df57858181518110620020085762002008620049e9565b6020026020010151307f0000000000000000000000000000000000000000000000000000000000000000604051620020409062003da7565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f0801580156200208a573d6000803e3d6000fd5b50878281518110620020a057620020a0620049e9565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62002197888281518110620020f857620020f8620049e9565b6020026020010151888381518110620021155762002115620049e9565b6020026020010151878481518110620021325762002132620049e9565b60200260200101518785815181106200214f576200214f620049e9565b60200260200101518786815181106200216c576200216c620049e9565b6020026020010151878781518110620021895762002189620049e9565b602002602001015162002d38565b878181518110620021ac57620021ac620049e9565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620021ea57620021ea620049e9565b602002602001015160a0015133604051620022359291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620022498162004a2e565b91505062001f94565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c082015291146200235c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a001516200236e919062005052565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601954620023d69184169062004a18565b6019556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af115801562002480573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620024a6919062004d29565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff6101008204811695830195909552650100000000008104851693820184905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004831660c08201529291141590620025da60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490506000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200267d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026a391906200507a565b9050828015620026c75750818015620026c5575080846040015163ffffffff16115b155b15620026ff576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115801562002732575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b156200276a576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8162002780576200277d60328262004a18565b90505b6000858152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620027dc9060029087906200376616565b5060145460808501516bffffffffffffffffffffffff91821691600091168211156200284557608086015162002813908362005094565b90508560a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562002845575060a08501515b808660a0015162002857919062005094565b600088815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601554620028bf9183911662005052565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169088907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a350505050505050565b600060606000806000634b56a42e60e01b8888886040516024016200296493929190620050bc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050620029ef89826200068d565b929c919b50995090975095505050505050565b62002a0c62003774565b62002a1781620037f7565b50565b60006060600080600080600062002a418860405180602001604052806000815250620009ff565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166385df51fd60018473ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002b25573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b4b91906200507a565b62002b5791906200475b565b6040518263ffffffff1660e01b815260040162002b7691815260200190565b602060405180830381865afa15801562002b94573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002bba91906200507a565b601554604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002cc6578382828151811062002c825762002c82620049e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002cbd8162004a2e565b91505062002c62565b5084600181111562002cdc5762002cdc620041be565b60f81b81600f8151811062002cf55762002cf5620049e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002d2f81620050f0565b95945050505050565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff161562002d98576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654835163ffffffff909116101562002dde576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002e1c5750601554602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002e54576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002ebe576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691891691909117905560079091529020620030b1848262005133565b508460a001516bffffffffffffffffffffffff16601954620030d4919062004a18565b6019556000868152601b60205260409020620030f1838262005133565b506000868152601c602052604090206200310c828262005133565b506200311a600287620038ee565b50505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161462003193576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314620031f3576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161462002a17576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620032e0577fff000000000000000000000000000000000000000000000000000000000000008216838260208110620032945762003294620049e9565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620032cb57506000949350505050565b80620032d78162004a2e565b91505062003252565b5081600f1a6001811115620032f957620032f9620041be565b949350505050565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200338e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620033b4919062005275565b5094509092505050600081131580620033cc57508142105b80620033f15750828015620033f15750620033e882426200475b565b8463ffffffff16105b156200340257601754955062003406565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562003472573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003498919062005275565b5094509092505050600081131580620034b057508142105b80620034d55750828015620034d55750620034cc82426200475b565b8463ffffffff16105b15620034e6576018549450620034ea565b8094505b50505050915091565b6000806200350788878b60c00151620038fc565b9050600080620035248b8a63ffffffff16858a8a60018b62003992565b909250905062003535818362005052565b9b9a5050505050505050505050565b606060008360018111156200355d576200355d620041be565b036200362a576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620035a5916024016200536d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506200375f565b6001836001811115620036415762003641620041be565b036200372d576000828060200190518101906200365f9190620053e4565b6000868152600760205260409081902090519192507f40691db40000000000000000000000000000000000000000000000000000000091620036a6918491602401620054f8565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506200375f9050565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9392505050565b600062002a83838362003c4a565b60005473ffffffffffffffffffffffffffffffffffffffff16331462003193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620011e0565b3373ffffffffffffffffffffffffffffffffffffffff82160362003878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620011e0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600062002a83838362003d55565b60008080856001811115620039155762003915620041be565b0362003926575062015f9062003949565b60018560018111156200393d576200393d620041be565b036200372d57506201af405b6200395c63ffffffff85166014620055c0565b62003969846001620055da565b6200397a9060ff16611d4c620055c0565b62003986908362004a18565b62002d2f919062004a18565b60008060008960a0015161ffff1687620039ad9190620055c0565b9050838015620039bc5750803a105b15620039c557503a5b6000841562003a4d578a610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa15801562003a1f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003a4591906200507a565b905062003b0e565b6101408b01516016546040517f1254414000000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff90911690631254414090602401602060405180830381865afa15801562003ad0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003af691906200507a565b8b60a0015161ffff1662003b0b9190620055c0565b90505b62003b1e61ffff871682620055f6565b90506000878262003b308c8e62004a18565b62003b3c9086620055c0565b62003b48919062004a18565b62003b5c90670de0b6b3a7640000620055c0565b62003b689190620055f6565b905060008c6040015163ffffffff1664e8d4a5100062003b899190620055c0565b898e6020015163ffffffff16858f8862003ba49190620055c0565b62003bb0919062004a18565b62003bc090633b9aca00620055c0565b62003bcc9190620055c0565b62003bd89190620055f6565b62003be4919062004a18565b90506b033b2e3c9fd0803ce800000062003bff828462004a18565b111562003c38576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000818152600183016020526040812054801562003d4357600062003c716001836200475b565b855490915060009062003c87906001906200475b565b905081811462003cf357600086600001828154811062003cab5762003cab620049e9565b906000526020600020015490508087600001848154811062003cd15762003cd1620049e9565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003d075762003d0762005632565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062002a86565b600091505062002a86565b5092915050565b600081815260018301602052604081205462003d9e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562002a86565b50600062002a86565b6103ca806200566283390190565b50805462003dc39062004819565b6000825580601f1062003dd4575050565b601f01602090049060005260206000209081019062002a1791905b8082111562003e05576000815560010162003def565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462002a1757600080fd5b803563ffffffff8116811462003e4157600080fd5b919050565b80356002811062003e4157600080fd5b60008083601f84011262003e6957600080fd5b50813567ffffffffffffffff81111562003e8257600080fd5b60208301915083602082850101111562003e9b57600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171562003ef75762003ef762003ea2565b60405290565b604051610100810167ffffffffffffffff8111828210171562003ef75762003ef762003ea2565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562003f6e5762003f6e62003ea2565b604052919050565b600067ffffffffffffffff82111562003f935762003f9362003ea2565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262003fd157600080fd5b813562003fe862003fe28262003f76565b62003f24565b81815284602083860101111562003ffe57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200403857600080fd5b8835620040458162003e09565b97506200405560208a0162003e2c565b96506040890135620040678162003e09565b95506200407760608a0162003e46565b9450608089013567ffffffffffffffff808211156200409557600080fd5b620040a38c838d0162003e56565b909650945060a08b0135915080821115620040bd57600080fd5b620040cb8c838d0162003fbf565b935060c08b0135915080821115620040e257600080fd5b50620040f18b828c0162003fbf565b9150509295985092959890939650565b600080604083850312156200411557600080fd5b82359150602083013567ffffffffffffffff8111156200413457600080fd5b620041428582860162003fbf565b9150509250929050565b60005b83811015620041695781810151838201526020016200414f565b50506000910152565b600081518084526200418c8160208601602086016200414c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a811062004225577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b841515815260806020820152600062004246608083018662004172565b9050620042576040830185620041ed565b82606083015295945050505050565b6000806000604084860312156200427c57600080fd5b83359250602084013567ffffffffffffffff8111156200429b57600080fd5b620042a98682870162003e56565b9497909650939450505050565b600080600080600080600060a0888a031215620042d257600080fd5b8735620042df8162003e09565b9650620042ef6020890162003e2c565b95506040880135620043018162003e09565b9450606088013567ffffffffffffffff808211156200431f57600080fd5b6200432d8b838c0162003e56565b909650945060808a01359150808211156200434757600080fd5b50620043568a828b0162003e56565b989b979a50959850939692959293505050565b871515815260e0602082015260006200438660e083018962004172565b9050620043976040830188620041ed565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080600060408486031215620043d157600080fd5b833567ffffffffffffffff80821115620043ea57600080fd5b818601915086601f830112620043ff57600080fd5b8135818111156200440f57600080fd5b8760208260051b85010111156200442557600080fd5b602092830195509350508401356200443d8162003e09565b809150509250925092565b600080602083850312156200445c57600080fd5b823567ffffffffffffffff8111156200447457600080fd5b620044828582860162003e56565b90969095509350505050565b80356bffffffffffffffffffffffff8116811462003e4157600080fd5b60008060408385031215620044bf57600080fd5b82359150620044d1602084016200448e565b90509250929050565b600060208284031215620044ed57600080fd5b5035919050565b600067ffffffffffffffff82111562004511576200451162003ea2565b5060051b60200190565b600082601f8301126200452d57600080fd5b813560206200454062003fe283620044f4565b82815260059290921b840181019181810190868411156200456057600080fd5b8286015b84811015620045a557803567ffffffffffffffff811115620045865760008081fd5b620045968986838b010162003fbf565b84525091830191830162004564565b509695505050505050565b60008060008060608587031215620045c757600080fd5b84359350602085013567ffffffffffffffff80821115620045e757600080fd5b620045f5888389016200451b565b945060408701359150808211156200460c57600080fd5b506200461b8782880162003e56565b95989497509550505050565b6000602082840312156200463a57600080fd5b81356200375f8162003e09565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff80831681810362004692576200469262004647565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000620032f96020830184866200469c565b60208152600062002a83602083018462004172565b805162003e418162003e09565b6000602082840312156200473057600080fd5b81516200375f8162003e09565b60008251620047518184602087016200414c565b9190910192915050565b8181038181111562002a865762002a8662004647565b801515811462002a1757600080fd5b600082601f8301126200479257600080fd5b8151620047a362003fe28262003f76565b818152846020838601011115620047b957600080fd5b620032f98260208301602087016200414c565b60008060408385031215620047e057600080fd5b8251620047ed8162004771565b602084015190925067ffffffffffffffff8111156200480b57600080fd5b620041428582860162004780565b600181811c908216806200482e57607f821691505b60208210810362004868577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115620048bc57600081815260208120601f850160051c81016020861015620048975750805b601f850160051c820191505b81811015620048b857828155600101620048a3565b5050505b505050565b67ffffffffffffffff831115620048dc57620048dc62003ea2565b620048f483620048ed835462004819565b836200486e565b6000601f841160018114620049495760008515620049125750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355620049e2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156200499a578685013582556020948501946001909201910162004978565b5086821015620049d6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111562002a865762002a8662004647565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004a625762004a6262004647565b5060010190565b600081518084526020808501945080840160005b8381101562004b285781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004b03828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004a7d565b509495945050505050565b600081518084526020808501945080840160005b8381101562004b2857815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004b47565b600081518084526020808501808196508360051b8101915082860160005b8581101562004bc757828403895262004bb484835162004172565b9885019893509084019060010162004b99565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004c1157600080fd5b8960051b808c8386013783018381038201602085015262004c358282018b62004a69565b915050828103604084015262004c4c818962004b33565b9050828103606084015262004c62818862004b33565b9050828103608084015262004c78818762004b7b565b905082810360a084015262004c8e818662004b7b565b905082810360c084015262003535818562004b7b565b60006020828403121562004cb757600080fd5b815160ff811681146200375f57600080fd5b60ff8416815260ff8316602082015260606040820152600062002d2f606083018462004172565b60006020828403121562004d0357600080fd5b815167ffffffffffffffff81111562004d1b57600080fd5b620032f98482850162004780565b60006020828403121562004d3c57600080fd5b81516200375f8162004771565b600082601f83011262004d5b57600080fd5b8135602062004d6e62003fe283620044f4565b82815260059290921b8401810191818101908684111562004d8e57600080fd5b8286015b84811015620045a5578035835291830191830162004d92565b600082601f83011262004dbd57600080fd5b8135602062004dd062003fe283620044f4565b82815260e0928302850182019282820191908785111562004df057600080fd5b8387015b8581101562004ea75781818a03121562004e0e5760008081fd5b62004e1862003ed1565b813562004e258162004771565b815262004e3482870162003e2c565b86820152604062004e4781840162003e2c565b9082015260608281013562004e5c8162003e09565b90820152608062004e6f8382016200448e565b9082015260a062004e828382016200448e565b9082015260c062004e9583820162003e2c565b90820152845292840192810162004df4565b5090979650505050505050565b600082601f83011262004ec657600080fd5b8135602062004ed962003fe283620044f4565b82815260059290921b8401810191818101908684111562004ef957600080fd5b8286015b84811015620045a557803562004f138162003e09565b835291830191830162004efd565b600080600080600080600060e0888a03121562004f3d57600080fd5b873567ffffffffffffffff8082111562004f5657600080fd5b62004f648b838c0162004d49565b985060208a013591508082111562004f7b57600080fd5b62004f898b838c0162004dab565b975060408a013591508082111562004fa057600080fd5b62004fae8b838c0162004eb4565b965060608a013591508082111562004fc557600080fd5b62004fd38b838c0162004eb4565b955060808a013591508082111562004fea57600080fd5b62004ff88b838c016200451b565b945060a08a01359150808211156200500f57600080fd5b6200501d8b838c016200451b565b935060c08a01359150808211156200503457600080fd5b50620050438a828b016200451b565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003d4e5762003d4e62004647565b6000602082840312156200508d57600080fd5b5051919050565b6bffffffffffffffffffffffff82811682821603908082111562003d4e5762003d4e62004647565b604081526000620050d1604083018662004b7b565b8281036020840152620050e68185876200469c565b9695505050505050565b8051602080830151919081101562004868577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff81111562005150576200515062003ea2565b620051688162005161845462004819565b846200486e565b602080601f831160018114620051be5760008415620051875750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555620048b8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156200520d57888601518255948401946001909101908401620051ec565b50858210156200524a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff8116811462003e4157600080fd5b600080600080600060a086880312156200528e57600080fd5b62005299866200525a565b9450602086015193506040860151925060608601519150620052be608087016200525a565b90509295509295909350565b60008154620052d98162004819565b808552602060018381168015620052f95760018114620053325762005362565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955062005362565b866000528260002060005b858110156200535a5781548a82018601529083019084016200533d565b890184019650505b505050505092915050565b60208152600062002a836020830184620052ca565b600082601f8301126200539457600080fd5b81516020620053a762003fe283620044f4565b82815260059290921b84018101918181019086841115620053c757600080fd5b8286015b84811015620045a55780518352918301918301620053cb565b600060208284031215620053f757600080fd5b815167ffffffffffffffff808211156200541057600080fd5b9083019061010082860312156200542657600080fd5b6200543062003efd565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200546a60a0840162004710565b60a082015260c0830151828111156200548257600080fd5b620054908782860162005382565b60c08301525060e083015182811115620054a957600080fd5b620054b78782860162004780565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004b2857815187529582019590820190600101620054da565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c08401516101008081850152506200556b610140840182620054c6565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084830301610120850152620055a9828262004172565b915050828103602084015262002d2f8185620052ca565b808202811582820484141762002a865762002a8662004647565b60ff818116838216019081111562002a865762002a8662004647565b6000826200562d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b5060405162005ee738038062005ee78339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051615aaa6200043d6000396000818161010e01526101a9015260006131260152600081816103e10152611ffe0152600061330f015260006133f3015260008181611e40015261240c0152615aaa6000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b6200016536600462004045565b62000313565b6040519081526020015b60405180910390f35b620001956200018f3660046200412b565b6200068d565b60405162000175949392919062004253565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b620001526200020036600462004290565b62000931565b6200016b62000217366004620042e0565b62000999565b620002346200022e3660046200412b565b620009ff565b60405162000175979695949392919062004393565b620001526200114d565b6200015262000264366004620043e5565b62001250565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a36600462004472565b62001ec1565b62000152620002b1366004620044d5565b62002249565b62000152620002c836600462004504565b620024dc565b62000195620002df366004620045da565b62002927565b62000152620002f636600462004651565b620029ed565b620002346200030d36600462004504565b62002a05565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200034757506200034560093362002a43565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d98662002a77565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003dd1565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002d239050565b6015805474010000000000000000000000000000000000000000900463ffffffff169060146200054f83620046a0565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c892919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8787604051620006049291906200470f565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063e919062004725565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508460405162000678919062004725565b60405180910390a25098975050505050505050565b600060606000806200069e6200310e565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007de919062004747565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168960405162000820919062004767565b60006040518083038160008787f1925050503d806000811462000860576040519150601f19603f3d011682016040523d82523d6000602084013e62000865565b606091505b50915091505a62000877908562004785565b935081620008a257600060405180602001604052806000815250600796509650965050505062000928565b80806020019051810190620008b89190620047f6565b909750955086620008e657600060405180602001604052806000815250600496509650965050505062000928565b601654865164010000000090910463ffffffff1610156200092457600060405180602001604052806000815250600596509650965050505062000928565b5050505b92959194509250565b6200093c8362003180565b6000838152601b6020526040902062000957828483620048eb565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098c9291906200470f565b60405180910390a2505050565b6000620009f388888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a156200310e565b600062000a228a62003236565b905060006012604051806101600160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160189054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201601b9054906101000a900461ffff1661ffff1661ffff16815260200160008201601d9054906101000a900460ff1660ff1660ff16815260200160008201601e9054906101000a900460ff1615151515815260200160008201601f9054906101000a900460ff161515151581526020016001820160009054906101000a900460ff161515151581526020016001820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160e001511562000db7576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b604081015163ffffffff9081161462000e08576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b80511562000e4e576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b62000e5982620032ec565b8095508196505050600062000e76838584602001518989620034de565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000ee0576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001141565b600062000eef8e868f62003793565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f47573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f6d919062004747565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168460405162000faf919062004767565b60006040518083038160008787f1925050503d806000811462000fef576040519150601f19603f3d011682016040523d82523d6000602084013e62000ff4565b606091505b50915091505a62001006908c62004785565b9a5081620010865760165481516801000000000000000090910463ffffffff1610156200106357505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200114192505050565b602090940151939b5060039a505063ffffffff9092169650620011419350505050565b808060200190518101906200109c9190620047f6565b909e509c508d620010dd57505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200114192505050565b6016548d5164010000000090910463ffffffff1610156200112e57505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200114192505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff163314620011d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff1660038111156200128f576200128f620041e8565b14158015620012db5750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012d857620012d8620041e8565b14155b1562001313576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001373576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003620013af576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff81111562001406576200140662003ecc565b60405190808252806020026020018201604052801562001430578160200160208202803683370190505b50905060008667ffffffffffffffff81111562001451576200145162003ecc565b604051908082528060200260200182016040528015620014d857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181620014705790505b50905060008767ffffffffffffffff811115620014f957620014f962003ecc565b6040519080825280602002602001820160405280156200152e57816020015b6060815260200190600190039081620015185790505b50905060008867ffffffffffffffff8111156200154f576200154f62003ecc565b6040519080825280602002602001820160405280156200158457816020015b60608152602001906001900390816200156e5790505b50905060008967ffffffffffffffff811115620015a557620015a562003ecc565b604051908082528060200260200182016040528015620015da57816020015b6060815260200190600190039081620015c45790505b50905060005b8a81101562001bbe578b8b82818110620015fe57620015fe62004a13565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a50909850620016dd90508962003180565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200174d57600080fd5b505af115801562001762573d6000803e3d6000fd5b50505050878582815181106200177c576200177c62004a13565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868281518110620017d057620017d062004a13565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a815260079091526040902080546200180f9062004843565b80601f01602080910402602001604051908101604052809291908181526020018280546200183d9062004843565b80156200188e5780601f1062001862576101008083540402835291602001916200188e565b820191906000526020600020905b8154815290600101906020018083116200187057829003601f168201915b5050505050848281518110620018a857620018a862004a13565b6020026020010181905250601b60008a81526020019081526020016000208054620018d39062004843565b80601f0160208091040260200160405190810160405280929190818152602001828054620019019062004843565b8015620019525780601f10620019265761010080835404028352916020019162001952565b820191906000526020600020905b8154815290600101906020018083116200193457829003601f168201915b50505050508382815181106200196c576200196c62004a13565b6020026020010181905250601c60008a81526020019081526020016000208054620019979062004843565b80601f0160208091040260200160405190810160405280929190818152602001828054620019c59062004843565b801562001a165780601f10620019ea5761010080835404028352916020019162001a16565b820191906000526020600020905b815481529060010190602001808311620019f857829003601f168201915b505050505082828151811062001a305762001a3062004a13565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a5b919062004a42565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001ad1919062003ddf565b6000898152601b6020526040812062001aea9162003ddf565b6000898152601c6020526040812062001b039162003ddf565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b4460028a62003983565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001bb58162004a58565b915050620015e0565b508560195462001bcf919062004785565b60195560008b8b868167ffffffffffffffff81111562001bf35762001bf362003ecc565b60405190808252806020026020018201604052801562001c1d578160200160208202803683370190505b508988888860405160200162001c3b98979695949392919062004c1f565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6014600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001cf7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d1d919062004cfe565b866040518463ffffffff1660e01b815260040162001d3e9392919062004d23565b600060405180830381865afa15801562001d5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001da4919081019062004d4a565b6040518263ffffffff1660e01b815260040162001dc2919062004725565b600060405180830381600087803b15801562001ddd57600080fd5b505af115801562001df2573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001e8c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001eb2919062004d83565b50505050505050505050505050565b6002336000908152601a602052604090205460ff16600381111562001eea5762001eea620041e8565b1415801562001f2057506003336000908152601a602052604090205460ff16600381111562001f1d5762001f1d620041e8565b14155b1562001f58576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f6e888a018a62004f6e565b965096509650965096509650965060005b87518110156200223d57600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001fb65762001fb662004a13565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020ca5785818151811062001ff35762001ff362004a13565b6020026020010151307f00000000000000000000000000000000000000000000000000000000000000006040516200202b9062003dd1565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562002075573d6000803e3d6000fd5b508782815181106200208b576200208b62004a13565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62002182888281518110620020e357620020e362004a13565b602002602001015188838151811062002100576200210062004a13565b60200260200101518784815181106200211d576200211d62004a13565b60200260200101518785815181106200213a576200213a62004a13565b602002602001015187868151811062002157576200215762004a13565b602002602001015187878151811062002174576200217462004a13565b602002602001015162002d23565b87818151811062002197576200219762004a13565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620021d557620021d562004a13565b602002602001015160a0015133604051620022209291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620022348162004a58565b91505062001f7f565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c0820152911462002347576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a001516200235991906200509f565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601954620023c19184169062004a42565b6019556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156200246b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002491919062004d83565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff6101008204811695830195909552650100000000008104851693820184905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004831660c08201529291141590620025c560005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490506000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002668573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200268e9190620050c7565b9050828015620026b25750818015620026b0575080846040015163ffffffff16115b155b15620026ea576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811580156200271d575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562002755576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816200276b576200276860328262004a42565b90505b6000858152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620027c79060029087906200398316565b5060145460808501516bffffffffffffffffffffffff918216916000911682111562002830576080860151620027fe9083620050e1565b90508560a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562002830575060a08501515b808660a00151620028429190620050e1565b600088815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601554620028aa918391166200509f565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169088907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a350505050505050565b600060606000806000634b56a42e60e01b8888886040516024016200294f9392919062005109565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050620029da89826200068d565b929c919b50995090975095505050505050565b620029f762003991565b62002a028162003a14565b50565b60006060600080600080600062002a2c8860405180602001604052806000815250620009ff565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166385df51fd60018473ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002b10573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b369190620050c7565b62002b42919062004785565b6040518263ffffffff1660e01b815260040162002b6191815260200190565b602060405180830381865afa15801562002b7f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002ba59190620050c7565b601554604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002cb1578382828151811062002c6d5762002c6d62004a13565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002ca88162004a58565b91505062002c4d565b5084600181111562002cc75762002cc7620041e8565b60f81b81600f8151811062002ce05762002ce062004a13565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002d1a816200513d565b95945050505050565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff161562002d83576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654835163ffffffff909116101562002dc9576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002e075750601554602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002e3f576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002ea9576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff000000000000000000000000000000000000000016918916919091179055600790915290206200309c848262005180565b508460a001516bffffffffffffffffffffffff16601954620030bf919062004a42565b6019556000868152601b60205260409020620030dc838262005180565b506000868152601c60205260409020620030f7828262005180565b506200310560028762003b0b565b50505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146200317e576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314620031de576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161462002a02576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620032cb577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106200327f576200327f62004a13565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620032b657506000949350505050565b80620032c28162004a58565b9150506200323d565b5081600f1a6001811115620032e457620032e4620041e8565b949350505050565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562003379573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200339f9190620052c2565b5094509092505050600081131580620033b757508142105b80620033dc5750828015620033dc5750620033d3824262004785565b8463ffffffff16105b15620033ed576017549550620033f1565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200345d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620034839190620052c2565b50945090925050506000811315806200349b57508142105b80620034c05750828015620034c05750620034b7824262004785565b8463ffffffff16105b15620034d1576018549450620034d5565b8094505b50505050915091565b60008080866001811115620034f757620034f7620041e8565b0362003507575061ea6062003561565b60018660018111156200351e576200351e620041e8565b036200352f575062014c0862003561565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008760c00151600162003576919062005317565b620035869060ff16604062005333565b601654620035a6906103a490640100000000900463ffffffff1662004a42565b620035b2919062004a42565b601354604080517fde9ee35e00000000000000000000000000000000000000000000000000000000815281519394506000938493610100900473ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa15801562003629573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200364f91906200534d565b909250905081836200366383601862004a42565b6200366f919062005333565b60c08c01516200368190600162005317565b620036929060ff166115e062005333565b6200369e919062004a42565b620036aa919062004a42565b620036b6908562004a42565b935060008a610140015173ffffffffffffffffffffffffffffffffffffffff166312544140856040518263ffffffff1660e01b8152600401620036fb91815260200190565b602060405180830381865afa15801562003719573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200373f9190620050c7565b8b60a0015161ffff1662003754919062005333565b9050600080620037718d8c63ffffffff1689868e8e600062003b19565b90925090506200378281836200509f565b9d9c50505050505050505050505050565b60606000836001811115620037ac57620037ac620041e8565b0362003879576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620037f49160240162005415565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506200397c565b6001836001811115620038905762003890620041e8565b036200352f57600082806020019051810190620038ae91906200548c565b6000868152600760205260409081902090519192507f40691db40000000000000000000000000000000000000000000000000000000091620038f5918491602401620055a0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506200397c9050565b9392505050565b600062002a6e838362003c74565b60005473ffffffffffffffffffffffffffffffffffffffff1633146200317e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620011cb565b3373ffffffffffffffffffffffffffffffffffffffff82160362003a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620011cb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600062002a6e838362003d7f565b60008060008960a0015161ffff168662003b34919062005333565b905083801562003b435750803a105b1562003b4c57503a5b6000858862003b5c8b8d62004a42565b62003b68908562005333565b62003b74919062004a42565b62003b8890670de0b6b3a764000062005333565b62003b94919062005668565b905060008b6040015163ffffffff1664e8d4a5100062003bb5919062005333565b60208d0151889063ffffffff168b62003bcf8f8862005333565b62003bdb919062004a42565b62003beb90633b9aca0062005333565b62003bf7919062005333565b62003c03919062005668565b62003c0f919062004a42565b90506b033b2e3c9fd0803ce800000062003c2a828462004a42565b111562003c63576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b6000818152600183016020526040812054801562003d6d57600062003c9b60018362004785565b855490915060009062003cb19060019062004785565b905081811462003d1d57600086600001828154811062003cd55762003cd562004a13565b906000526020600020015490508087600001848154811062003cfb5762003cfb62004a13565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003d315762003d31620056a4565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062002a71565b600091505062002a71565b5092915050565b600081815260018301602052604081205462003dc85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562002a71565b50600062002a71565b6103ca80620056d483390190565b50805462003ded9062004843565b6000825580601f1062003dfe575050565b601f01602090049060005260206000209081019062002a0291905b8082111562003e2f576000815560010162003e19565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462002a0257600080fd5b803563ffffffff8116811462003e6b57600080fd5b919050565b80356002811062003e6b57600080fd5b60008083601f84011262003e9357600080fd5b50813567ffffffffffffffff81111562003eac57600080fd5b60208301915083602082850101111562003ec557600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171562003f215762003f2162003ecc565b60405290565b604051610100810167ffffffffffffffff8111828210171562003f215762003f2162003ecc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562003f985762003f9862003ecc565b604052919050565b600067ffffffffffffffff82111562003fbd5762003fbd62003ecc565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262003ffb57600080fd5b8135620040126200400c8262003fa0565b62003f4e565b8181528460208386010111156200402857600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200406257600080fd5b88356200406f8162003e33565b97506200407f60208a0162003e56565b96506040890135620040918162003e33565b9550620040a160608a0162003e70565b9450608089013567ffffffffffffffff80821115620040bf57600080fd5b620040cd8c838d0162003e80565b909650945060a08b0135915080821115620040e757600080fd5b620040f58c838d0162003fe9565b935060c08b01359150808211156200410c57600080fd5b506200411b8b828c0162003fe9565b9150509295985092959890939650565b600080604083850312156200413f57600080fd5b82359150602083013567ffffffffffffffff8111156200415e57600080fd5b6200416c8582860162003fe9565b9150509250929050565b60005b838110156200419357818101518382015260200162004179565b50506000910152565b60008151808452620041b681602086016020860162004176565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a81106200424f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b84151581526080602082015260006200427060808301866200419c565b905062004281604083018562004217565b82606083015295945050505050565b600080600060408486031215620042a657600080fd5b83359250602084013567ffffffffffffffff811115620042c557600080fd5b620042d38682870162003e80565b9497909650939450505050565b600080600080600080600060a0888a031215620042fc57600080fd5b8735620043098162003e33565b9650620043196020890162003e56565b955060408801356200432b8162003e33565b9450606088013567ffffffffffffffff808211156200434957600080fd5b620043578b838c0162003e80565b909650945060808a01359150808211156200437157600080fd5b50620043808a828b0162003e80565b989b979a50959850939692959293505050565b871515815260e060208201526000620043b060e08301896200419c565b9050620043c1604083018862004217565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080600060408486031215620043fb57600080fd5b833567ffffffffffffffff808211156200441457600080fd5b818601915086601f8301126200442957600080fd5b8135818111156200443957600080fd5b8760208260051b85010111156200444f57600080fd5b60209283019550935050840135620044678162003e33565b809150509250925092565b600080602083850312156200448657600080fd5b823567ffffffffffffffff8111156200449e57600080fd5b620044ac8582860162003e80565b90969095509350505050565b80356bffffffffffffffffffffffff8116811462003e6b57600080fd5b60008060408385031215620044e957600080fd5b82359150620044fb60208401620044b8565b90509250929050565b6000602082840312156200451757600080fd5b5035919050565b600067ffffffffffffffff8211156200453b576200453b62003ecc565b5060051b60200190565b600082601f8301126200455757600080fd5b813560206200456a6200400c836200451e565b82815260059290921b840181019181810190868411156200458a57600080fd5b8286015b84811015620045cf57803567ffffffffffffffff811115620045b05760008081fd5b620045c08986838b010162003fe9565b8452509183019183016200458e565b509695505050505050565b60008060008060608587031215620045f157600080fd5b84359350602085013567ffffffffffffffff808211156200461157600080fd5b6200461f8883890162004545565b945060408701359150808211156200463657600080fd5b50620046458782880162003e80565b95989497509550505050565b6000602082840312156200466457600080fd5b81356200397c8162003e33565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff808316818103620046bc57620046bc62004671565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000620032e4602083018486620046c6565b60208152600062002a6e60208301846200419c565b805162003e6b8162003e33565b6000602082840312156200475a57600080fd5b81516200397c8162003e33565b600082516200477b81846020870162004176565b9190910192915050565b8181038181111562002a715762002a7162004671565b801515811462002a0257600080fd5b600082601f830112620047bc57600080fd5b8151620047cd6200400c8262003fa0565b818152846020838601011115620047e357600080fd5b620032e482602083016020870162004176565b600080604083850312156200480a57600080fd5b825162004817816200479b565b602084015190925067ffffffffffffffff8111156200483557600080fd5b6200416c85828601620047aa565b600181811c908216806200485857607f821691505b60208210810362004892577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115620048e657600081815260208120601f850160051c81016020861015620048c15750805b601f850160051c820191505b81811015620048e257828155600101620048cd565b5050505b505050565b67ffffffffffffffff83111562004906576200490662003ecc565b6200491e8362004917835462004843565b8362004898565b6000601f8411600181146200497357600085156200493c5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835562004a0c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015620049c45786850135825560209485019460019092019101620049a2565b508682101562004a00577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111562002a715762002a7162004671565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004a8c5762004a8c62004671565b5060010190565b600081518084526020808501945080840160005b8381101562004b525781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004b2d828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004aa7565b509495945050505050565b600081518084526020808501945080840160005b8381101562004b5257815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004b71565b600082825180855260208086019550808260051b84010181860160005b8481101562004c12577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895262004bff8383516200419c565b9884019892509083019060010162004bc2565b5090979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004c5c57600080fd5b8960051b808c8386013783018381038201602085015262004c808282018b62004a93565b915050828103604084015262004c97818962004b5d565b9050828103606084015262004cad818862004b5d565b9050828103608084015262004cc3818762004ba5565b905082810360a084015262004cd9818662004ba5565b905082810360c084015262004cef818562004ba5565b9b9a5050505050505050505050565b60006020828403121562004d1157600080fd5b815160ff811681146200397c57600080fd5b60ff8416815260ff8316602082015260606040820152600062002d1a60608301846200419c565b60006020828403121562004d5d57600080fd5b815167ffffffffffffffff81111562004d7557600080fd5b620032e484828501620047aa565b60006020828403121562004d9657600080fd5b81516200397c816200479b565b600082601f83011262004db557600080fd5b8135602062004dc86200400c836200451e565b82815260059290921b8401810191818101908684111562004de857600080fd5b8286015b84811015620045cf578035835291830191830162004dec565b600082601f83011262004e1757600080fd5b8135602062004e2a6200400c836200451e565b82815260e0928302850182019282820191908785111562004e4a57600080fd5b8387015b8581101562004c125781818a03121562004e685760008081fd5b62004e7262003efb565b813562004e7f816200479b565b815262004e8e82870162003e56565b86820152604062004ea181840162003e56565b9082015260608281013562004eb68162003e33565b90820152608062004ec9838201620044b8565b9082015260a062004edc838201620044b8565b9082015260c062004eef83820162003e56565b90820152845292840192810162004e4e565b600082601f83011262004f1357600080fd5b8135602062004f266200400c836200451e565b82815260059290921b8401810191818101908684111562004f4657600080fd5b8286015b84811015620045cf57803562004f608162003e33565b835291830191830162004f4a565b600080600080600080600060e0888a03121562004f8a57600080fd5b873567ffffffffffffffff8082111562004fa357600080fd5b62004fb18b838c0162004da3565b985060208a013591508082111562004fc857600080fd5b62004fd68b838c0162004e05565b975060408a013591508082111562004fed57600080fd5b62004ffb8b838c0162004f01565b965060608a01359150808211156200501257600080fd5b620050208b838c0162004f01565b955060808a01359150808211156200503757600080fd5b620050458b838c0162004545565b945060a08a01359150808211156200505c57600080fd5b6200506a8b838c0162004545565b935060c08a01359150808211156200508157600080fd5b50620050908a828b0162004545565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003d785762003d7862004671565b600060208284031215620050da57600080fd5b5051919050565b6bffffffffffffffffffffffff82811682821603908082111562003d785762003d7862004671565b6040815260006200511e604083018662004ba5565b828103602084015262005133818587620046c6565b9695505050505050565b8051602080830151919081101562004892577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff8111156200519d576200519d62003ecc565b620051b581620051ae845462004843565b8462004898565b602080601f8311600181146200520b5760008415620051d45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555620048e2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156200525a5788860151825594840194600190910190840162005239565b50858210156200529757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff8116811462003e6b57600080fd5b600080600080600060a08688031215620052db57600080fd5b620052e686620052a7565b94506020860151935060408601519250606086015191506200530b60808701620052a7565b90509295509295909350565b60ff818116838216019081111562002a715762002a7162004671565b808202811582820484141762002a715762002a7162004671565b600080604083850312156200536157600080fd5b505080516020909101519092909150565b60008154620053818162004843565b808552602060018381168015620053a15760018114620053da576200540a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b89010195506200540a565b866000528260002060005b85811015620054025781548a8201860152908301908401620053e5565b890184019650505b505050505092915050565b60208152600062002a6e602083018462005372565b600082601f8301126200543c57600080fd5b815160206200544f6200400c836200451e565b82815260059290921b840181019181810190868411156200546f57600080fd5b8286015b84811015620045cf578051835291830191830162005473565b6000602082840312156200549f57600080fd5b815167ffffffffffffffff80821115620054b857600080fd5b908301906101008286031215620054ce57600080fd5b620054d862003f27565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200551260a084016200473a565b60a082015260c0830151828111156200552a57600080fd5b62005538878286016200542a565b60c08301525060e0830151828111156200555157600080fd5b6200555f87828601620047aa565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004b525781518752958201959082019060010162005582565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c0840151610100808185015250620056136101408401826200556e565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526200565182826200419c565b915050828103602084015262002d1a818562005372565b6000826200569f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", } var AutomationRegistryLogicAABI = AutomationRegistryLogicAMetaData.ABI diff --git a/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_2/automation_registry_logic_b_wrapper_2_2.go similarity index 74% rename from core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go rename to core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_2/automation_registry_logic_b_wrapper_2_2.go index d15bc458774..e936312e5ca 100644 --- a/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_2/keeper_registry_logic_b_wrapper_2_2.go +++ b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_2/automation_registry_logic_b_wrapper_2_2.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package keeper_registry_logic_b_wrapper_2_2 +package automation_registry_logic_b_wrapper_2_2 import ( "errors" @@ -75,8 +75,8 @@ type AutomationRegistryBase22UpkeepInfo struct { } var AutomationRegistryLogicBMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"automationForwarderLogic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowedReadOnlyAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"contractIAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIChainModule\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"setChainSpecificModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"enumUpkeepFormat\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162004dfb38038062004dfb8339810160408190526200003591620001bf565b84848484843380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c481620000f7565b5050506001600160a01b0394851660805292841660a05290831660c052821660e0521661010052506200022f9350505050565b336001600160a01b03821603620001515760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ba57600080fd5b919050565b600080600080600060a08688031215620001d857600080fd5b620001e386620001a2565b9450620001f360208701620001a2565b93506200020360408701620001a2565b92506200021360608701620001a2565b91506200022360808701620001a2565b90509295509295909350565b60805160a05160c05160e05161010051614b56620002a56000396000610716015260006105880152600081816106080152613379015260008181610779015261345301526000818161080701528181611de3015281816120b80152818161252101528181612a340152612ab80152614b566000f3fe608060405234801561001057600080fd5b50600436106103575760003560e01c806379ba5097116101c8578063b10b673c11610104578063ca30e603116100a2578063eb5dcd6c1161007c578063eb5dcd6c14610851578063ed56b3e114610864578063f2fde38b146108d7578063faa3e996146108ea57600080fd5b8063ca30e60314610805578063cd7f71b51461082b578063d76326481461083e57600080fd5b8063b6511a2a116100de578063b6511a2a146107c3578063b657bc9c146107ca578063b79550be146107dd578063c7c3a19a146107e557600080fd5b8063b10b673c14610777578063b121e1471461079d578063b148ab6b146107b057600080fd5b80638dcf0fe711610171578063a710b2211161014b578063a710b2211461073a578063a72aa27e1461074d578063aab9edd614610760578063abc76ae01461076f57600080fd5b80638dcf0fe7146106de5780638ed02bab146106f1578063a08714c01461071457600080fd5b80638456cb59116101a25780638456cb59146106a55780638765ecbe146106ad5780638da5cb5b146106c057600080fd5b806379ba50971461065257806379ea99431461065a5780637d9b97e01461069d57600080fd5b806343cc055c116102975780635425d8ac116102405780636209e1e91161021a5780636209e1e9146105f35780636709d0e514610606578063671d36ed1461062c578063744bfe611461063f57600080fd5b80635425d8ac146105865780635b6aa71c146105cd5780635b7edd6e146105e057600080fd5b80634ca16c52116102715780634ca16c521461054a5780635147cd59146105535780635165f2f51461057357600080fd5b806343cc055c1461050157806344cb70b81461051857806348013d7b1461053b57600080fd5b80631a2af01111610304578063232c1cc5116102de578063232c1cc5146104795780633b9cce59146104805780633f4ba83a14610493578063421d183b1461049b57600080fd5b80631a2af011146103f55780631e01043914610408578063207b65161461046657600080fd5b80631865c57d116103355780631865c57d146103a9578063187256e8146103c257806319d97a94146103d557600080fd5b8063050ee65d1461035c57806306e3b632146103745780630b7d33e614610394575b600080fd5b6201af405b6040519081526020015b60405180910390f35b610387610382366004613da5565b610930565b60405161036b9190613dc7565b6103a76103a2366004613e54565b610a4d565b005b6103b1610b07565b60405161036b959493929190614057565b6103a76103d036600461418e565b610f51565b6103e86103e33660046141cb565b610fc2565b60405161036b9190614248565b6103a761040336600461425b565b611064565b6104496104163660046141cb565b6000908152600460205260409020600101546c0100000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff909116815260200161036b565b6103e86104743660046141cb565b61116a565b6014610361565b6103a761048e366004614280565b611187565b6103a76113dd565b6104ae6104a93660046142f5565b611443565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00161036b565b60135460ff165b604051901515815260200161036b565b6105086105263660046141cb565b60009081526008602052604090205460ff1690565b600060405161036b9190614341565b62015f90610361565b6105666105613660046141cb565b611562565b60405161036b919061435b565b6103a76105813660046141cb565b61156d565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161036b565b6104496105db366004614388565b6116e4565b6103a76105ee3660046142f5565b6118a1565b6103e86106013660046142f5565b611929565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a761063a3660046143c1565b61195d565b6103a761064d36600461425b565b611a37565b6103a7611ede565b6105a86106683660046141cb565b6000908152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6103a7611fe0565b6103a761213b565b6103a76106bb3660046141cb565b6121bc565b60005473ffffffffffffffffffffffffffffffffffffffff166105a8565b6103a76106ec366004613e54565b612336565b601354610100900473ffffffffffffffffffffffffffffffffffffffff166105a8565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a76107483660046143fd565b61238b565b6103a761075b36600461442b565b6125f3565b6040516003815260200161036b565b611d4c610361565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a76107ab3660046142f5565b6126e8565b6103a76107be3660046141cb565b6127e0565b6032610361565b6104496107d83660046141cb565b6129ce565b6103a76129fb565b6107f86107f33660046141cb565b612b57565b60405161036b919061444e565b7f00000000000000000000000000000000000000000000000000000000000000006105a8565b6103a7610839366004613e54565b612f2a565b61044961084c3660046141cb565b612fc1565b6103a761085f3660046143fd565b612fcc565b6108be6108723660046142f5565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff90911660208301520161036b565b6103a76108e53660046142f5565b61312a565b6109236108f83660046142f5565b73ffffffffffffffffffffffffffffffffffffffff166000908152601a602052604090205460ff1690565b60405161036b9190614585565b6060600061093e600261313e565b9050808410610979576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061098584866145c8565b905081811180610993575083155b61099d578061099f565b815b905060006109ad86836145db565b67ffffffffffffffff8111156109c5576109c56145ee565b6040519080825280602002602001820160405280156109ee578160200160208202803683370190505b50905060005b8151811015610a4157610a12610a0a88836145c8565b600290613148565b828281518110610a2457610a2461461d565b602090810291909101015280610a398161464c565b9150506109f4565b50925050505b92915050565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610aae576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152601d60205260409020610ac7828483614726565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae77698383604051610afa929190614841565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c0810191909152604080516101408101825260155463ffffffff7401000000000000000000000000000000000000000082041682526bffffffffffffffffffffffff90811660208301526019549282019290925260125490911660608281019190915290819060009060808101610c40600261313e565b8152601554780100000000000000000000000000000000000000000000000080820463ffffffff9081166020808601919091527c01000000000000000000000000000000000000000000000000000000008404821660408087019190915260115460608088019190915260125474010000000000000000000000000000000000000000810485166080808a01919091527e01000000000000000000000000000000000000000000000000000000000000820460ff16151560a0998a015283516101e0810185526c0100000000000000000000000080840488168252700100000000000000000000000000000000808504891697830197909752808a0488169582019590955296820462ffffff16928701929092527b01000000000000000000000000000000000000000000000000000000900461ffff16908501526014546bffffffffffffffffffffffff8116968501969096529304811660c083015260165480821660e08401526401000000008104821661010084015268010000000000000000900416610120820152601754610140820152601854610160820152910473ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a08101610e0d600961315b565b81526016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16602091820152601254600d80546040805182860281018601909152818152949850899489949293600e937d01000000000000000000000000000000000000000000000000000000000090910460ff16928591830182828015610ed057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ea5575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610f3957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610f0e575b50505050509150945094509450945094509091929394565b610f59613168565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601a6020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115610fb957610fb9614312565b02179055505050565b6000818152601d60205260409020805460609190610fdf90614684565b80601f016020809104026020016040519081016040528092919081815260200182805461100b90614684565b80156110585780601f1061102d57610100808354040283529160200191611058565b820191906000526020600020905b81548152906001019060200180831161103b57829003601f168201915b50505050509050919050565b61106d826131eb565b3373ffffffffffffffffffffffffffffffffffffffff8216036110bc576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146111665760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b6000818152601b60205260409020805460609190610fdf90614684565b61118f613168565b600e5481146111ca576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e5481101561139c576000600e82815481106111ec576111ec61461d565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600f909252604083205491935016908585858181106112365761123661461d565b905060200201602081019061124b91906142f5565b905073ffffffffffffffffffffffffffffffffffffffff811615806112de575073ffffffffffffffffffffffffffffffffffffffff8216158015906112bc57508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b80156112de575073ffffffffffffffffffffffffffffffffffffffff81811614155b15611315576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116146113865773ffffffffffffffffffffffffffffffffffffffff8381166000908152600f6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b50505080806113949061464c565b9150506111cd565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516113d19392919061488e565b60405180910390a15050565b6113e5613168565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015282918291829182919082906115095760608201516012546000916114f5916bffffffffffffffffffffffff16614940565b600e549091506115059082614994565b9150505b8151602083015160408401516115209084906149bf565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b166000908152600f6020526040902054929b919a9499509750921694509092505050565b6000610a478261329f565b611576816131eb565b600081815260046020908152604091829020825160e081018452815460ff8116151580835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015290611675576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556116b460028361334a565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e0100000000000000000000000000000000000000000000000000000000000083048116151560e08301527f01000000000000000000000000000000000000000000000000000000000000009092048216151561010080830191909152601354928316151561012083015273ffffffffffffffffffffffffffffffffffffffff920491909116610140820152600090818061186e83613356565b91509150611897838787601460020160049054906101000a900463ffffffff1686866000613534565b9695505050505050565b6118a9613168565b601380547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527fdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad79060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e60205260409020805460609190610fdf90614684565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633146119be576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601e602052604090206119ee828483614726565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d28383604051610afa929190614841565b6012547f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611a97576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff8116611b2d576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481168387015265010000000000820481168386015273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909204821660608401526001909301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c082015286855260059093529220549091163314611c34576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc891906149e4565b816040015163ffffffff161115611d0b576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600460205260409020600101546019546c010000000000000000000000009091046bffffffffffffffffffffffff1690611d4b9082906145db565b60195560008481526004602081905260409182902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff16905590517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116928201929092526bffffffffffffffffffffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5291906149fd565b50604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611fe8613168565b6015546019546bffffffffffffffffffffffff9091169061200a9082906145db565b601955601580547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690556040516bffffffffffffffffffffffff821681527f1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f19060200160405180910390a16040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526bffffffffffffffffffffffff821660248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044015b6020604051808303816000875af1158015612117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116691906149fd565b612143613168565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001611439565b6121c5816131eb565b600081815260046020908152604091829020825160e081018452815460ff8116158015835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c0820152906122c4576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561230660028361357f565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b61233f836131eb565b6000838152601c60205260409020612358828483614726565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508383604051610afa929190614841565b73ffffffffffffffffffffffffffffffffffffffff81166123d8576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054163314612438576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e5460009161245b9185916bffffffffffffffffffffffff169061358b565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff1690556019549091506124c5906bffffffffffffffffffffffff8316906145db565b6019556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526bffffffffffffffffffffffff831660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af115801561256a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258e91906149fd565b5060405133815273ffffffffffffffffffffffffffffffffffffffff808416916bffffffffffffffffffffffff8416918616907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a4505050565b6108fc8163ffffffff161080612628575060155463ffffffff7001000000000000000000000000000000009091048116908216115b1561265f576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612668826131eb565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c910160405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260106020526040902054163314612748576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600f602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556010909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c082015291146128dd576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff16331461293a576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b6000610a476129dc8361329f565b600084815260046020526040902054610100900463ffffffff166116e4565b612a03613168565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab491906149e4565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3360195484612b0191906145db565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff909216600483015260248201526044016120f8565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606083018190526001909101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c0820152919015612cef57816060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cea9190614a1f565b612cf2565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836020015163ffffffff168152602001600760008781526020019081526020016000208054612d4a90614684565b80601f0160208091040260200160405190810160405280929190818152602001828054612d7690614684565b8015612dc35780601f10612d9857610100808354040283529160200191612dc3565b820191906000526020600020905b815481529060010190602001808311612da657829003601f168201915b505050505081526020018360a001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff1667ffffffffffffffff1681526020018360c0015163ffffffff16815260200183608001516bffffffffffffffffffffffff168152602001836000015115158152602001601c60008781526020019081526020016000208054612ea090614684565b80601f0160208091040260200160405190810160405280929190818152602001828054612ecc90614684565b8015612f195780601f10612eee57610100808354040283529160200191612f19565b820191906000526020600020905b815481529060010190602001808311612efc57829003601f168201915b505050505081525092505050919050565b612f33836131eb565b60165463ffffffff16811115612f75576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260409020612f8e828483614726565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8383604051610afa929190614841565b6000610a47826129ce565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f602052604090205416331461302c576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82160361307b576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601060205260409020548116908216146111665773ffffffffffffffffffffffffffffffffffffffff82811660008181526010602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45050565b613132613168565b61313b81613793565b50565b6000610a47825490565b60006131548383613888565b9392505050565b60606000613154836138b2565b60005473ffffffffffffffffffffffffffffffffffffffff1633146131e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611f5b565b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314613248576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161461313b576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f81101561332c577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106132e4576132e461461d565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461331a57506000949350505050565b806133248161464c565b9150506132a6565b5081600f1a600181111561334257613342614312565b949350505050565b6000613154838361390d565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156133e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134069190614a56565b509450909250505060008113158061341d57508142105b8061343e575082801561343e575061343582426145db565b8463ffffffff16105b1561344d576017549550613451565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156134bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134e09190614a56565b50945090925050506000811315806134f757508142105b806135185750828015613518575061350f82426145db565b8463ffffffff16105b1561352757601854945061352b565b8094505b50505050915091565b60008061354688878b60c0015161395c565b90506000806135618b8a63ffffffff16858a8a60018b613a1e565b909250905061357081836149bf565b9b9a5050505050505050505050565b60006131548383613cab565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906137875760008160600151856136239190614940565b905060006136318583614994565b9050808360400181815161364591906149bf565b6bffffffffffffffffffffffff169052506136608582614aa6565b8360600181815161367191906149bf565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611f5b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600082600001828154811061389f5761389f61461d565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561105857602002820191906000526020600020905b8154815260200190600101908083116138ee5750505050509050919050565b600081815260018301602052604081205461395457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a47565b506000610a47565b6000808085600181111561397257613972614312565b03613981575062015f906139d6565b600185600181111561399557613995614312565b036139a457506201af406139d6565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6139e763ffffffff85166014614ad6565b6139f2846001614aed565b613a019060ff16611d4c614ad6565b613a0b90836145c8565b613a1591906145c8565b95945050505050565b60008060008960a0015161ffff1687613a379190614ad6565b9050838015613a455750803a105b15613a4d57503a5b60008415613ad0578a610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015613aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac991906149e4565b9050613b8c565b6101408b01516016546040517f1254414000000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff90911690631254414090602401602060405180830381865afa158015613b52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b7691906149e4565b8b60a0015161ffff16613b899190614ad6565b90505b613b9a61ffff871682614b06565b905060008782613baa8c8e6145c8565b613bb49086614ad6565b613bbe91906145c8565b613bd090670de0b6b3a7640000614ad6565b613bda9190614b06565b905060008c6040015163ffffffff1664e8d4a51000613bf99190614ad6565b898e6020015163ffffffff16858f88613c129190614ad6565b613c1c91906145c8565b613c2a90633b9aca00614ad6565b613c349190614ad6565b613c3e9190614b06565b613c4891906145c8565b90506b033b2e3c9fd0803ce8000000613c6182846145c8565b1115613c99576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b60008181526001830160205260408120548015613d94576000613ccf6001836145db565b8554909150600090613ce3906001906145db565b9050818114613d48576000866000018281548110613d0357613d0361461d565b9060005260206000200154905080876000018481548110613d2657613d2661461d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d5957613d59614b1a565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a47565b6000915050610a47565b5092915050565b60008060408385031215613db857600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613dff57835183529284019291840191600101613de3565b50909695505050505050565b60008083601f840112613e1d57600080fd5b50813567ffffffffffffffff811115613e3557600080fd5b602083019150836020828501011115613e4d57600080fd5b9250929050565b600080600060408486031215613e6957600080fd5b83359250602084013567ffffffffffffffff811115613e8757600080fd5b613e9386828701613e0b565b9497909650939450505050565b600081518084526020808501945080840160005b83811015613ee657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613eb4565b509495945050505050565b805163ffffffff16825260006101e06020830151613f17602086018263ffffffff169052565b506040830151613f2f604086018263ffffffff169052565b506060830151613f46606086018262ffffff169052565b506080830151613f5c608086018261ffff169052565b5060a0830151613f7c60a08601826bffffffffffffffffffffffff169052565b5060c0830151613f9460c086018263ffffffff169052565b5060e0830151613fac60e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a08084015181860183905261402183870182613ea0565b925050506101c08084015161404d8287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c0602088015161408560208501826bffffffffffffffffffffffff169052565b506040880151604084015260608801516140af60608501826bffffffffffffffffffffffff169052565b506080880151608084015260a08801516140d160a085018263ffffffff169052565b5060c08801516140e960c085018263ffffffff169052565b5060e088015160e08401526101008089015161410c8286018263ffffffff169052565b505061012088810151151590840152610140830181905261412f81840188613ef1565b90508281036101608401526141448187613ea0565b90508281036101808401526141598186613ea0565b9150506118976101a083018460ff169052565b73ffffffffffffffffffffffffffffffffffffffff8116811461313b57600080fd5b600080604083850312156141a157600080fd5b82356141ac8161416c565b91506020830135600481106141c057600080fd5b809150509250929050565b6000602082840312156141dd57600080fd5b5035919050565b6000815180845260005b8181101561420a576020818501810151868301820152016141ee565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061315460208301846141e4565b6000806040838503121561426e57600080fd5b8235915060208301356141c08161416c565b6000806020838503121561429357600080fd5b823567ffffffffffffffff808211156142ab57600080fd5b818501915085601f8301126142bf57600080fd5b8135818111156142ce57600080fd5b8660208260051b85010111156142e357600080fd5b60209290920196919550909350505050565b60006020828403121561430757600080fd5b81356131548161416c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061435557614355614312565b91905290565b602081016002831061435557614355614312565b803563ffffffff8116811461438357600080fd5b919050565b6000806040838503121561439b57600080fd5b8235600281106143aa57600080fd5b91506143b86020840161436f565b90509250929050565b6000806000604084860312156143d657600080fd5b83356143e18161416c565b9250602084013567ffffffffffffffff811115613e8757600080fd5b6000806040838503121561441057600080fd5b823561441b8161416c565b915060208301356141c08161416c565b6000806040838503121561443e57600080fd5b823591506143b86020840161436f565b6020815261447560208201835173ffffffffffffffffffffffffffffffffffffffff169052565b6000602083015161448e604084018263ffffffff169052565b5060408301516101408060608501526144ab6101608501836141e4565b915060608501516144cc60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614538818701836bffffffffffffffffffffffff169052565b860151905061012061454d8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183870152905061189783826141e4565b602081016004831061435557614355614312565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4757610a47614599565b81810381811115610a4757610a47614599565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361467d5761467d614599565b5060010190565b600181811c9082168061469857607f821691505b6020821081036146d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561472157600081815260208120601f850160051c810160208610156146fe5750805b601f850160051c820191505b8181101561471d5782815560010161470a565b5050505b505050565b67ffffffffffffffff83111561473e5761473e6145ee565b6147528361474c8354614684565b836146d7565b6000601f8411600181146147a4576000851561476e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561483a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156147f357868501358255602094850194600190920191016147d3565b508682101561482e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b828110156148e557815473ffffffffffffffffffffffffffffffffffffffff16845292840192600191820191016148b3565b505050838103828501528481528590820160005b8681101561493457823561490c8161416c565b73ffffffffffffffffffffffffffffffffffffffff16825291830191908301906001016148f9565b50979650505050505050565b6bffffffffffffffffffffffff828116828216039080821115613d9e57613d9e614599565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff808416806149b3576149b3614965565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115613d9e57613d9e614599565b6000602082840312156149f657600080fd5b5051919050565b600060208284031215614a0f57600080fd5b8151801515811461315457600080fd5b600060208284031215614a3157600080fd5b81516131548161416c565b805169ffffffffffffffffffff8116811461438357600080fd5b600080600080600060a08688031215614a6e57600080fd5b614a7786614a3c565b9450602086015193506040860151925060608601519150614a9a60808701614a3c565b90509295509295909350565b6bffffffffffffffffffffffff818116838216028082169190828114614ace57614ace614599565b505092915050565b8082028115828204841417610a4757610a47614599565b60ff8181168382160190811115610a4757610a47614599565b600082614b1557614b15614965565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"automationForwarderLogic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowedReadOnlyAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"contractIAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.MigrationPermission\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"enumUpkeepFormat\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162004daf38038062004daf8339810160408190526200003591620001bf565b84848484843380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c481620000f7565b5050506001600160a01b0394851660805292841660a05290831660c052821660e0521661010052506200022f9350505050565b336001600160a01b03821603620001515760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ba57600080fd5b919050565b600080600080600060a08688031215620001d857600080fd5b620001e386620001a2565b9450620001f360208701620001a2565b93506200020360408701620001a2565b92506200021360608701620001a2565b91506200022360808701620001a2565b90509295509295909350565b60805160a05160c05160e05161010051614b0a620002a56000396000610715015260006105920152600081816105ff01526132df01526000818161077801526133b901526000818161080601528181611d490152818161201e015281816124870152818161299a0152612a1e0152614b0a6000f3fe608060405234801561001057600080fd5b50600436106103625760003560e01c80637d9b97e0116101c8578063b121e14711610104578063cd7f71b5116100a2578063ed56b3e11161007c578063ed56b3e114610863578063f2fde38b146108d6578063f777ff06146108e9578063faa3e996146108f057600080fd5b8063cd7f71b51461082a578063d76326481461083d578063eb5dcd6c1461085057600080fd5b8063b657bc9c116100de578063b657bc9c146107c9578063b79550be146107dc578063c7c3a19a146107e4578063ca30e6031461080457600080fd5b8063b121e1471461079c578063b148ab6b146107af578063b6511a2a146107c257600080fd5b80639e0a99ed11610171578063a72aa27e1161014b578063a72aa27e1461074c578063aab9edd61461075f578063abc76ae01461076e578063b10b673c1461077657600080fd5b80639e0a99ed1461070b578063a08714c014610713578063a710b2211461073957600080fd5b80638da5cb5b116101a25780638da5cb5b146106b75780638dcf0fe7146106d55780638ed02bab146106e857600080fd5b80637d9b97e0146106945780638456cb591461069c5780638765ecbe146106a457600080fd5b806343cc055c116102a25780635b6aa71c11610240578063671d36ed1161021a578063671d36ed14610623578063744bfe611461063657806379ba50971461064957806379ea99431461065157600080fd5b80635b6aa71c146105d75780636209e1e9146105ea5780636709d0e5146105fd57600080fd5b80634ca16c521161027c5780634ca16c52146105555780635147cd591461055d5780635165f2f51461057d5780635425d8ac1461059057600080fd5b806343cc055c1461050c57806344cb70b81461052357806348013d7b1461054657600080fd5b80631a2af0111161030f578063232c1cc5116102e9578063232c1cc5146104845780633b9cce591461048b5780633f4ba83a1461049e578063421d183b146104a657600080fd5b80631a2af011146104005780631e01043914610413578063207b65161461047157600080fd5b80631865c57d116103405780631865c57d146103b4578063187256e8146103cd57806319d97a94146103e057600080fd5b8063050ee65d1461036757806306e3b6321461037f5780630b7d33e61461039f575b600080fd5b62014c085b6040519081526020015b60405180910390f35b61039261038d366004613d35565b610936565b6040516103769190613d57565b6103b26103ad366004613de4565b610a53565b005b6103bc610b0d565b604051610376959493929190613fe7565b6103b26103db36600461411e565b610f57565b6103f36103ee36600461415b565b610fc8565b60405161037691906141d8565b6103b261040e3660046141eb565b61106a565b61045461042136600461415b565b6000908152600460205260409020600101546c0100000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff9091168152602001610376565b6103f361047f36600461415b565b611170565b601861036c565b6103b2610499366004614210565b61118d565b6103b26113e3565b6104b96104b4366004614285565b611449565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a001610376565b60135460ff165b6040519015158152602001610376565b61051361053136600461415b565b60009081526008602052604090205460ff1690565b600060405161037691906142d1565b61ea6061036c565b61057061056b36600461415b565b611568565b60405161037691906142eb565b6103b261058b36600461415b565b611573565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610376565b6104546105e5366004614318565b6116ea565b6103f36105f8366004614285565b61188f565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b2610631366004614351565b6118c3565b6103b26106443660046141eb565b61199d565b6103b2611e44565b6105b261065f36600461415b565b6000908152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6103b2611f46565b6103b26120a1565b6103b26106b236600461415b565b612122565b60005473ffffffffffffffffffffffffffffffffffffffff166105b2565b6103b26106e3366004613de4565b61229c565b601354610100900473ffffffffffffffffffffffffffffffffffffffff166105b2565b6103a461036c565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b261074736600461438d565b6122f1565b6103b261075a3660046143bb565b612559565b60405160038152602001610376565b6115e061036c565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b26107aa366004614285565b61264e565b6103b26107bd36600461415b565b612746565b603261036c565b6104546107d736600461415b565b612934565b6103b2612961565b6107f76107f236600461415b565b612abd565b60405161037691906143de565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b2610838366004613de4565b612e90565b61045461084b36600461415b565b612f27565b6103b261085e36600461438d565b612f32565b6108bd610871366004614285565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff909116602083015201610376565b6103b26108e4366004614285565b613090565b604061036c565b6109296108fe366004614285565b73ffffffffffffffffffffffffffffffffffffffff166000908152601a602052604090205460ff1690565b6040516103769190614515565b6060600061094460026130a4565b905080841061097f576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061098b8486614558565b905081811180610999575083155b6109a357806109a5565b815b905060006109b3868361456b565b67ffffffffffffffff8111156109cb576109cb61457e565b6040519080825280602002602001820160405280156109f4578160200160208202803683370190505b50905060005b8151811015610a4757610a18610a108883614558565b6002906130ae565b828281518110610a2a57610a2a6145ad565b602090810291909101015280610a3f816145dc565b9150506109fa565b50925050505b92915050565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610ab4576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152601d60205260409020610acd8284836146b6565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae77698383604051610b009291906147d1565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c0810191909152604080516101408101825260155463ffffffff7401000000000000000000000000000000000000000082041682526bffffffffffffffffffffffff90811660208301526019549282019290925260125490911660608281019190915290819060009060808101610c4660026130a4565b8152601554780100000000000000000000000000000000000000000000000080820463ffffffff9081166020808601919091527c01000000000000000000000000000000000000000000000000000000008404821660408087019190915260115460608088019190915260125474010000000000000000000000000000000000000000810485166080808a01919091527e01000000000000000000000000000000000000000000000000000000000000820460ff16151560a0998a015283516101e0810185526c0100000000000000000000000080840488168252700100000000000000000000000000000000808504891697830197909752808a0488169582019590955296820462ffffff16928701929092527b01000000000000000000000000000000000000000000000000000000900461ffff16908501526014546bffffffffffffffffffffffff8116968501969096529304811660c083015260165480821660e08401526401000000008104821661010084015268010000000000000000900416610120820152601754610140820152601854610160820152910473ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a08101610e1360096130c1565b81526016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16602091820152601254600d80546040805182860281018601909152818152949850899489949293600e937d01000000000000000000000000000000000000000000000000000000000090910460ff16928591830182828015610ed657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610eab575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610f3f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610f14575b50505050509150945094509450945094509091929394565b610f5f6130ce565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601a6020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115610fbf57610fbf6142a2565b02179055505050565b6000818152601d60205260409020805460609190610fe590614614565b80601f016020809104026020016040519081016040528092919081815260200182805461101190614614565b801561105e5780601f106110335761010080835404028352916020019161105e565b820191906000526020600020905b81548152906001019060200180831161104157829003601f168201915b50505050509050919050565b61107382613151565b3373ffffffffffffffffffffffffffffffffffffffff8216036110c2576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff82811691161461116c5760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b6000818152601b60205260409020805460609190610fe590614614565b6111956130ce565b600e5481146111d0576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e548110156113a2576000600e82815481106111f2576111f26145ad565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600f9092526040832054919350169085858581811061123c5761123c6145ad565b90506020020160208101906112519190614285565b905073ffffffffffffffffffffffffffffffffffffffff811615806112e4575073ffffffffffffffffffffffffffffffffffffffff8216158015906112c257508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b80156112e4575073ffffffffffffffffffffffffffffffffffffffff81811614155b1561131b576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181161461138c5773ffffffffffffffffffffffffffffffffffffffff8381166000908152600f6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b505050808061139a906145dc565b9150506111d3565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516113d79392919061481e565b60405180910390a15050565b6113eb6130ce565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152829182918291829190829061150f5760608201516012546000916114fb916bffffffffffffffffffffffff166148d0565b600e5490915061150b9082614924565b9150505b81516020830151604084015161152690849061494f565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b166000908152600f6020526040902054929b919a9499509750921694509092505050565b6000610a4d82613205565b61157c81613151565b600081815260046020908152604091829020825160e081018452815460ff8116151580835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201529061167b576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556116ba6002836132b0565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e0100000000000000000000000000000000000000000000000000000000000083048116151560e08301527f01000000000000000000000000000000000000000000000000000000000000009092048216151561010080830191909152601354928316151561012083015273ffffffffffffffffffffffffffffffffffffffff9204919091166101408201526000908180611874836132bc565b91509150611885838787858561349a565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e60205260409020805460609190610fe590614614565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314611924576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601e602052604090206119548284836146b6565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d28383604051610b009291906147d1565b6012547f0100000000000000000000000000000000000000000000000000000000000000900460ff16156119fd576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff8116611a93576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481168387015265010000000000820481168386015273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909204821660608401526001909301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c082015286855260059093529220549091163314611b9a576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2e9190614974565b816040015163ffffffff161115611c71576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600460205260409020600101546019546c010000000000000000000000009091046bffffffffffffffffffffffff1690611cb190829061456b565b60195560008481526004602081905260409182902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff16905590517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116928201929092526bffffffffffffffffffffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611d94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db8919061498d565b50604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611f4e6130ce565b6015546019546bffffffffffffffffffffffff90911690611f7090829061456b565b601955601580547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690556040516bffffffffffffffffffffffff821681527f1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f19060200160405180910390a16040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526bffffffffffffffffffffffff821660248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044015b6020604051808303816000875af115801561207d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116c919061498d565b6120a96130ce565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200161143f565b61212b81613151565b600081815260046020908152604091829020825160e081018452815460ff8116158015835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201529061222a576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561226c600283613722565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b6122a583613151565b6000838152601c602052604090206122be8284836146b6565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508383604051610b009291906147d1565b73ffffffffffffffffffffffffffffffffffffffff811661233e576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f602052604090205416331461239e576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546000916123c19185916bffffffffffffffffffffffff169061372e565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905560195490915061242b906bffffffffffffffffffffffff83169061456b565b6019556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526bffffffffffffffffffffffff831660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156124d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f4919061498d565b5060405133815273ffffffffffffffffffffffffffffffffffffffff808416916bffffffffffffffffffffffff8416918616907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a4505050565b6108fc8163ffffffff16108061258e575060155463ffffffff7001000000000000000000000000000000009091048116908216115b156125c5576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125ce82613151565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c910160405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601060205260409020541633146126ae576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600f602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556010909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c08201529114612843576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146128a0576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b6000610a4d61294283613205565b600084815260046020526040902054610100900463ffffffff166116ea565b6129696130ce565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156129f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1a9190614974565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3360195484612a67919061456b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260440161205e565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606083018190526001909101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c0820152919015612c5557816060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5091906149af565b612c58565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836020015163ffffffff168152602001600760008781526020019081526020016000208054612cb090614614565b80601f0160208091040260200160405190810160405280929190818152602001828054612cdc90614614565b8015612d295780601f10612cfe57610100808354040283529160200191612d29565b820191906000526020600020905b815481529060010190602001808311612d0c57829003601f168201915b505050505081526020018360a001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff1667ffffffffffffffff1681526020018360c0015163ffffffff16815260200183608001516bffffffffffffffffffffffff168152602001836000015115158152602001601c60008781526020019081526020016000208054612e0690614614565b80601f0160208091040260200160405190810160405280929190818152602001828054612e3290614614565b8015612e7f5780601f10612e5457610100808354040283529160200191612e7f565b820191906000526020600020905b815481529060010190602001808311612e6257829003601f168201915b505050505081525092505050919050565b612e9983613151565b60165463ffffffff16811115612edb576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260409020612ef48284836146b6565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8383604051610b009291906147d1565b6000610a4d82612934565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054163314612f92576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612fe1576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526010602052604090205481169082161461116c5773ffffffffffffffffffffffffffffffffffffffff82811660008181526010602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45050565b6130986130ce565b6130a181613936565b50565b6000610a4d825490565b60006130ba8383613a2b565b9392505050565b606060006130ba83613a55565b60005473ffffffffffffffffffffffffffffffffffffffff16331461314f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611ec1565b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146131ae576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff908116146130a1576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015613292577fff00000000000000000000000000000000000000000000000000000000000000821683826020811061324a5761324a6145ad565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461328057506000949350505050565b8061328a816145dc565b91505061320c565b5081600f1a60018111156132a8576132a86142a2565b949350505050565b60006130ba8383613ab0565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613348573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336c91906149e6565b509450909250505060008113158061338357508142105b806133a457508280156133a4575061339b824261456b565b8463ffffffff16105b156133b35760175495506133b7565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613422573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344691906149e6565b509450909250505060008113158061345d57508142105b8061347e575082801561347e5750613475824261456b565b8463ffffffff16105b1561348d576018549450613491565b8094505b50505050915091565b600080808660018111156134b0576134b06142a2565b036134be575061ea60613513565b60018660018111156134d2576134d26142a2565b036134e1575062014c08613513565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008760c0015160016135269190614a36565b6135349060ff166040614a4f565b601654613552906103a490640100000000900463ffffffff16614558565b61355c9190614558565b601354604080517fde9ee35e00000000000000000000000000000000000000000000000000000000815281519394506000938493610100900473ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa1580156135d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135f69190614a66565b90925090508183613608836018614558565b6136129190614a4f565b60c08c0151613622906001614a36565b6136319060ff166115e0614a4f565b61363b9190614558565b6136459190614558565b61364f9085614558565b935060008a610140015173ffffffffffffffffffffffffffffffffffffffff166312544140856040518263ffffffff1660e01b815260040161369391815260200190565b602060405180830381865afa1580156136b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d49190614974565b8b60a0015161ffff166136e79190614a4f565b90506000806137028d8c63ffffffff1689868e8e6000613aff565b9092509050613711818361494f565b9d9c50505050505050505050505050565b60006130ba8383613c3b565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e010000000000000000000000000000900490911660608201529061392a5760008160600151856137c691906148d0565b905060006137d48583614924565b905080836040018181516137e8919061494f565b6bffffffffffffffffffffffff169052506138038582614a8a565b83606001818151613814919061494f565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036139b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611ec1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a4257613a426145ad565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561105e57602002820191906000526020600020905b815481526020019060010190808311613a915750505050509050919050565b6000818152600183016020526040812054613af757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a4d565b506000610a4d565b60008060008960a0015161ffff1686613b189190614a4f565b9050838015613b265750803a105b15613b2e57503a5b60008588613b3c8b8d614558565b613b469085614a4f565b613b509190614558565b613b6290670de0b6b3a7640000614a4f565b613b6c9190614aba565b905060008b6040015163ffffffff1664e8d4a51000613b8b9190614a4f565b60208d0151889063ffffffff168b613ba38f88614a4f565b613bad9190614558565b613bbb90633b9aca00614a4f565b613bc59190614a4f565b613bcf9190614aba565b613bd99190614558565b90506b033b2e3c9fd0803ce8000000613bf28284614558565b1115613c2a576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b60008181526001830160205260408120548015613d24576000613c5f60018361456b565b8554909150600090613c739060019061456b565b9050818114613cd8576000866000018281548110613c9357613c936145ad565b9060005260206000200154905080876000018481548110613cb657613cb66145ad565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613ce957613ce9614ace565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a4d565b6000915050610a4d565b5092915050565b60008060408385031215613d4857600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613d8f57835183529284019291840191600101613d73565b50909695505050505050565b60008083601f840112613dad57600080fd5b50813567ffffffffffffffff811115613dc557600080fd5b602083019150836020828501011115613ddd57600080fd5b9250929050565b600080600060408486031215613df957600080fd5b83359250602084013567ffffffffffffffff811115613e1757600080fd5b613e2386828701613d9b565b9497909650939450505050565b600081518084526020808501945080840160005b83811015613e7657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e44565b509495945050505050565b805163ffffffff16825260006101e06020830151613ea7602086018263ffffffff169052565b506040830151613ebf604086018263ffffffff169052565b506060830151613ed6606086018262ffffff169052565b506080830151613eec608086018261ffff169052565b5060a0830151613f0c60a08601826bffffffffffffffffffffffff169052565b5060c0830151613f2460c086018263ffffffff169052565b5060e0830151613f3c60e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a080840151818601839052613fb183870182613e30565b925050506101c080840151613fdd8287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c0602088015161401560208501826bffffffffffffffffffffffff169052565b5060408801516040840152606088015161403f60608501826bffffffffffffffffffffffff169052565b506080880151608084015260a088015161406160a085018263ffffffff169052565b5060c088015161407960c085018263ffffffff169052565b5060e088015160e08401526101008089015161409c8286018263ffffffff169052565b50506101208881015115159084015261014083018190526140bf81840188613e81565b90508281036101608401526140d48187613e30565b90508281036101808401526140e98186613e30565b9150506118856101a083018460ff169052565b73ffffffffffffffffffffffffffffffffffffffff811681146130a157600080fd5b6000806040838503121561413157600080fd5b823561413c816140fc565b915060208301356004811061415057600080fd5b809150509250929050565b60006020828403121561416d57600080fd5b5035919050565b6000815180845260005b8181101561419a5760208185018101518683018201520161417e565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006130ba6020830184614174565b600080604083850312156141fe57600080fd5b823591506020830135614150816140fc565b6000806020838503121561422357600080fd5b823567ffffffffffffffff8082111561423b57600080fd5b818501915085601f83011261424f57600080fd5b81358181111561425e57600080fd5b8660208260051b850101111561427357600080fd5b60209290920196919550909350505050565b60006020828403121561429757600080fd5b81356130ba816140fc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106142e5576142e56142a2565b91905290565b60208101600283106142e5576142e56142a2565b803563ffffffff8116811461431357600080fd5b919050565b6000806040838503121561432b57600080fd5b82356002811061433a57600080fd5b9150614348602084016142ff565b90509250929050565b60008060006040848603121561436657600080fd5b8335614371816140fc565b9250602084013567ffffffffffffffff811115613e1757600080fd5b600080604083850312156143a057600080fd5b82356143ab816140fc565b91506020830135614150816140fc565b600080604083850312156143ce57600080fd5b82359150614348602084016142ff565b6020815261440560208201835173ffffffffffffffffffffffffffffffffffffffff169052565b6000602083015161441e604084018263ffffffff169052565b50604083015161014080606085015261443b610160850183614174565b9150606085015161445c60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e08501516101006144c8818701836bffffffffffffffffffffffff169052565b86015190506101206144dd8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018387015290506118858382614174565b60208101600483106142e5576142e56142a2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4d57610a4d614529565b81810381811115610a4d57610a4d614529565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361460d5761460d614529565b5060010190565b600181811c9082168061462857607f821691505b602082108103614661577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156146b157600081815260208120601f850160051c8101602086101561468e5750805b601f850160051c820191505b818110156146ad5782815560010161469a565b5050505b505050565b67ffffffffffffffff8311156146ce576146ce61457e565b6146e2836146dc8354614614565b83614667565b6000601f84116001811461473457600085156146fe5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556147ca565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156147835786850135825560209485019460019092019101614763565b50868210156147be577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b8281101561487557815473ffffffffffffffffffffffffffffffffffffffff1684529284019260019182019101614843565b505050838103828501528481528590820160005b868110156148c457823561489c816140fc565b73ffffffffffffffffffffffffffffffffffffffff1682529183019190830190600101614889565b50979650505050505050565b6bffffffffffffffffffffffff828116828216039080821115613d2e57613d2e614529565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff80841680614943576149436148f5565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115613d2e57613d2e614529565b60006020828403121561498657600080fd5b5051919050565b60006020828403121561499f57600080fd5b815180151581146130ba57600080fd5b6000602082840312156149c157600080fd5b81516130ba816140fc565b805169ffffffffffffffffffff8116811461431357600080fd5b600080600080600060a086880312156149fe57600080fd5b614a07866149cc565b9450602086015193506040860151925060608601519150614a2a608087016149cc565b90509295509295909350565b60ff8181168382160190811115610a4d57610a4d614529565b8082028115828204841417610a4d57610a4d614529565b60008060408385031215614a7957600080fd5b505080516020909101519092909150565b6bffffffffffffffffffffffff818116838216028082169190828114614ab257614ab2614529565b505092915050565b600082614ac957614ac96148f5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var AutomationRegistryLogicBABI = AutomationRegistryLogicBMetaData.ABI @@ -718,6 +718,50 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetState return _AutomationRegistryLogicB.Contract.GetState(&_AutomationRegistryLogicB.CallOpts) } +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getTransmitCalldataFixedBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataFixedBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataFixedBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getTransmitCalldataPerSignerBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) { @@ -1011,18 +1055,6 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetA return _AutomationRegistryLogicB.Contract.SetAdminPrivilegeConfig(&_AutomationRegistryLogicB.TransactOpts, admin, newPrivilegeConfig) } -func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) { - return _AutomationRegistryLogicB.contract.Transact(opts, "setChainSpecificModule", newModule) -} - -func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { - return _AutomationRegistryLogicB.Contract.SetChainSpecificModule(&_AutomationRegistryLogicB.TransactOpts, newModule) -} - -func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { - return _AutomationRegistryLogicB.Contract.SetChainSpecificModule(&_AutomationRegistryLogicB.TransactOpts, newModule) -} - func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) { return _AutomationRegistryLogicB.contract.Transact(opts, "setPayees", payees) } @@ -5637,6 +5669,10 @@ type AutomationRegistryLogicBInterface interface { error) + GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) @@ -5671,8 +5707,6 @@ type AutomationRegistryLogicBInterface interface { SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) - SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) - SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) SetPeerRegistryMigrationPermission(opts *bind.TransactOpts, peer common.Address, permission uint8) (*types.Transaction, error) diff --git a/core/gethwrappers/generated/keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go b/core/gethwrappers/generated/automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go similarity index 79% rename from core/gethwrappers/generated/keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go rename to core/gethwrappers/generated/automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go index 0e0ec33fe81..229096b1517 100644 --- a/core/gethwrappers/generated/keeper_registry_wrapper_2_2/keeper_registry_wrapper_2_2.go +++ b/core/gethwrappers/generated/automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package keeper_registry_wrapper_2_2 +package automation_registry_wrapper_2_2 import ( "errors" @@ -51,8 +51,8 @@ type AutomationRegistryBase22OnchainConfig struct { } var AutomationRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b506040516200534d3803806200534d8339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051614f28620004256000396000818160d6015261016f01526000611b29015260005050600050506000505060006104330152614f286000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e3d0e7121161005b578063e3d0e712146102e0578063f2fde38b146102f3578063f75f6b1114610306576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102cd576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e322e30000000000000000081525081565b6040516101649190613c24565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610319565b61020e60155460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613cb2565b61041b565b610275610270366004613d0e565b610637565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527401000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102db366004613d9f565b6107ad565b6101196102ee366004614070565b610ae8565b61011961030136600461413d565b610b11565b610119610314366004614341565b610b25565b60015473ffffffffffffffffffffffffffffffffffffffff16331461039f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461048a576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104c4576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104d2828401846143d0565b60008181526004602052604090205490915065010000000000900463ffffffff9081161461052c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600101546105679085906c0100000000000000000000000090046bffffffffffffffffffffffff16614418565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556019546105d290859061443d565b6019556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b600080610642611b11565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff16156106a1576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f890185900485028101850190955287855290936107a0938990899081908401838280828437600092019190915250611b8292505050565b9097909650945050505050565b60005a60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e010000000000000000000000000000000000000000000000000000000000008304811615801560e08401527f01000000000000000000000000000000000000000000000000000000000000009093048116151561010080840191909152601354918216151561012084015273ffffffffffffffffffffffffffffffffffffffff910416610140820152919250610963576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff166109ac576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a35146109e8576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08101516109f890600161447f565b60ff1686141580610a095750858414155b15610a40576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a508a8a8a8a8a8a8a8a611dab565b6000610a5c8a8a612014565b905060208b0135600881901c63ffffffff16610a798484876120cf565b836060015163ffffffff168163ffffffff161115610ad957601280547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b610b0986868686806020019051810190610b02919061453e565b8686610b25565b505050505050565b610b196129ca565b610b2281612a4b565b50565b610b2d6129ca565b601f86511115610b69576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff16600003610ba6576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518651141580610bc55750610bbd8460036146c0565b60ff16865111155b15610bfc576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546bffffffffffffffffffffffff9091169060005b816bffffffffffffffffffffffff16811015610c7e57610c6b600e8281548110610c4257610c42614450565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612b40565b5080610c76816146dc565b915050610c16565b5060008060005b836bffffffffffffffffffffffff16811015610d8757600d8181548110610cae57610cae614450565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff90921694509082908110610ce957610ce9614450565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055915080610d7f816146dc565b915050610c85565b50610d94600d6000613b03565b610da0600e6000613b03565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c5181101561120957600c60008e8381518110610de557610de5614450565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615610e50576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110610e7a57610e7a614450565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610ecf576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f8481518110610f0057610f00614450565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110610fa857610fa8614450565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611018576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506110d3576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905580611201816146dc565b915050610dc6565b50508a5161121f9150600d9060208d0190613b21565b50885161123390600e9060208c0190613b21565b50604051806101600160405280856bffffffffffffffffffffffff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001600063ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020018960ff1681526020016012600001601e9054906101000a900460ff16151581526020016012600001601f9054906101000a900460ff161515815260200188610200015115158152602001886101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601260008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160186101000a81548162ffffff021916908362ffffff16021790555060a082015181600001601b6101000a81548161ffff021916908361ffff16021790555060c082015181600001601d6101000a81548160ff021916908360ff16021790555060e082015181600001601e6101000a81548160ff02191690831515021790555061010082015181600001601f6101000a81548160ff0219169083151502179055506101208201518160010160006101000a81548160ff0219169083151502179055506101408201518160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601460010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601460010160149054906101000a900463ffffffff1663ffffffff168152602001601460010160189054906101000a900463ffffffff1663ffffffff1681526020016014600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160178190555086610160015160188190555060006014600101601c9054906101000a900463ffffffff169050876101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f89190614714565b601580547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891611973918591780100000000000000000000000000000000000000000000000090041661472d565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000886040516020016119a4919061479b565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601554909150611a0d90469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612d48565b60115560005b611a1d6009612df2565b811015611a4d57611a3a611a32600983612dfc565b600990612e0f565b5080611a45816146dc565b915050611a13565b5060005b896101a0015151811015611aa457611a918a6101a001518281518110611a7957611a79614450565b60200260200101516009612e3190919063ffffffff16565b5080611a9c816146dc565b915050611a51565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601460010160189054906101000a900463ffffffff168f8f8f878f8f604051611afb9998979695949392919061493f565b60405180910390a1505050505050505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611b80576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081907f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611be7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090611c63908590602401613c24565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d1690611d3690879087906004016149d5565b60408051808303816000875af1158015611d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7891906149ee565b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60008787604051611dbd929190614a1c565b604051908190038120611dd4918b90602001614a2c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015611fab57600185878360208110611e4057611e40614450565b611e4d91901a601b61447f565b8c8c85818110611e5f57611e5f614450565b905060200201358b8b86818110611e7857611e78614450565b9050602002013560405160008152602001604052604051611eb5949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611ed7573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050611f85576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080611fa3906146dc565b915050611e23565b50827e01010101010101010101010101010101010101010101010101010101010101841614612006576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61204d6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061205b83850185614b1d565b604081015151606082015151919250908114158061207e57508082608001515114155b8061208e5750808260a001515114155b156120c5576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b600082604001515167ffffffffffffffff8111156120ef576120ef613e56565b6040519080825280602002602001820160405280156121b357816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161210d5790505b50905060008085610140015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222d9190614714565b905060005b85604001515181101561267757600460008760400151838151811061225957612259614450565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c0820152845185908390811061233e5761233e614450565b6020026020010151600001819052506123738660400151828151811061236657612366614450565b6020026020010151612e53565b84828151811061238557612385614450565b60200260200101516080019060018111156123a2576123a2614c0a565b908160018111156123b5576123b5614c0a565b81525050612429878583815181106123cf576123cf614450565b602002602001015160800151886060015184815181106123f1576123f1614450565b60200260200101518960a00151858151811061240f5761240f614450565b6020026020010151518a600001518b602001516001612efe565b84828151811061243b5761243b614450565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250506124c98660400151828151811061248257612482614450565b602002602001015183886080015184815181106124a1576124a1614450565b60200260200101518785815181106124bb576124bb614450565b60200260200101518b612f49565b8583815181106124db576124db614450565b60200260200101516020018684815181106124f8576124f8614450565b602002602001015160e001828152508215151515815250505083818151811061252357612523614450565b602002602001015160200151156125465761253f600184614c39565b925061254b565b612665565b6125b184828151811061256057612560614450565b602002602001015160000151606001518760600151838151811061258657612586614450565b60200260200101518860a0015184815181106125a4576125a4614450565b6020026020010151611b82565b8583815181106125c3576125c3614450565b60200260200101516060018684815181106125e0576125e0614450565b602002602001015160a001828152508215151515815250505083818151811061260b5761260b614450565b602002602001015160a00151856126229190614c54565b94506126658660400151828151811061263d5761263d614450565b60200260200101518386848151811061265857612658614450565b60200260200101516130c8565b8061266f816146dc565b915050612232565b508161ffff1660000361268c57505050505050565b60c086015161269c90600161447f565b6126ab9060ff1661044c614c67565b616dc46126b9366010614c67565b5a6126c49088614c54565b6126ce919061443d565b6126d8919061443d565b6126e2919061443d565b9350611c206126f561ffff841686614cad565b6126ff919061443d565b935060008060008060005b8960400151518110156129005787818151811061272957612729614450565b602002602001015160200151156128ee576127858989838151811061275057612750614450565b6020026020010151608001518c60a00151848151811061277257612772614450565b6020026020010151518e60c001516131cd565b88828151811061279757612797614450565b602002602001015160c00181815250506127f38b8b6040015183815181106127c1576127c1614450565b60200260200101518a84815181106127db576127db614450565b60200260200101518d600001518e602001518c6131ed565b90935091506128028285614418565b935061280e8386614418565b945087818151811061282257612822614450565b60200260200101516060015115158a60400151828151811061284657612846614450565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b848661287b9190614418565b8b858151811061288d5761288d614450565b602002602001015160a001518c86815181106128ab576128ab614450565b602002602001015160c001518f6080015187815181106128cd576128cd614450565b60200260200101516040516128e59493929190614cc1565b60405180910390a35b806128f8816146dc565b91505061270a565b5050336000908152600b6020526040902080548492506002906129389084906201000090046bffffffffffffffffffffffff16614418565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160008282829054906101000a90046bffffffffffffffffffffffff166129929190614418565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610396565b3373ffffffffffffffffffffffffffffffffffffffff821603612aca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610396565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612d3c576000816060015185612bd89190614cfe565b90506000612be68583614d23565b90508083604001818151612bfa9190614418565b6bffffffffffffffffffffffff16905250612c158582614d4e565b83606001818151612c269190614418565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000808a8a8a8a8a8a8a8a8a604051602001612d6c99989796959493929190614d7e565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b60006120c9825490565b6000612e0883836132e0565b9392505050565b6000612e088373ffffffffffffffffffffffffffffffffffffffff841661330a565b6000612e088373ffffffffffffffffffffffffffffffffffffffff8416613404565b6000818160045b600f811015612ee0577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612e9857612e98614450565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612ece57506000949350505050565b80612ed8816146dc565b915050612e5a565b5081600f1a6001811115612ef657612ef6614c0a565b949350505050565b600080612f1088878b60c00151613453565b9050600080612f2b8b8a63ffffffff16858a8a60018b6134df565b9092509050612f3a8183614418565b9b9a5050505050505050505050565b600080808085608001516001811115612f6457612f64614c0a565b03612f8a57612f76888888888861376c565b612f85576000925090506130be565b613002565b600185608001516001811115612fa257612fa2614c0a565b03612fd0576000612fb5898989886138f5565b9250905080612fca57506000925090506130be565b50613002565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516040015163ffffffff16871061305757877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516130449190613c24565b60405180910390a26000925090506130be565b84604001516bffffffffffffffffffffffff16856000015160a001516bffffffffffffffffffffffff1610156130b757877f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02876040516130449190613c24565b6001925090505b9550959350505050565b6000816080015160018111156130e0576130e0614c0a565b0361314457600083815260046020526040902060010180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff851602179055505050565b60018160800151600181111561315c5761315c614c0a565b036131c85760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60006131da848484613453565b905080851015612ef65750929392505050565b600080613208888760a001518860c0015188888860016134df565b909250905060006132198284614418565b600089815260046020526040902060010180549192508291600c9061325d9084906c0100000000000000000000000090046bffffffffffffffffffffffff16614cfe565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a8152600460205260408120600101805485945090926132a691859116614418565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b60008260000182815481106132f7576132f7614450565b9060005260206000200154905092915050565b600081815260018301602052604081205480156133f357600061332e600183614c54565b855490915060009061334290600190614c54565b90508181146133a757600086600001828154811061336257613362614450565b906000526020600020015490508087600001848154811061338557613385614450565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806133b8576133b8614e13565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506120c9565b60009150506120c9565b5092915050565b600081815260018301602052604081205461344b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556120c9565b5060006120c9565b6000808085600181111561346957613469614c0a565b03613478575062015f90613497565b600185600181111561348c5761348c614c0a565b03612fd057506201af405b6134a863ffffffff85166014614c67565b6134b384600161447f565b6134c29060ff16611d4c614c67565b6134cc908361443d565b6134d6919061443d565b95945050505050565b60008060008960a0015161ffff16876134f89190614c67565b90508380156135065750803a105b1561350e57503a5b60008415613591578a610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015613566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358a9190614714565b905061364d565b6101408b01516016546040517f1254414000000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff90911690631254414090602401602060405180830381865afa158015613613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136379190614714565b8b60a0015161ffff1661364a9190614c67565b90505b61365b61ffff871682614cad565b90506000878261366b8c8e61443d565b6136759086614c67565b61367f919061443d565b61369190670de0b6b3a7640000614c67565b61369b9190614cad565b905060008c6040015163ffffffff1664e8d4a510006136ba9190614c67565b898e6020015163ffffffff16858f886136d39190614c67565b6136dd919061443d565b6136eb90633b9aca00614c67565b6136f59190614c67565b6136ff9190614cad565b613709919061443d565b90506b033b2e3c9fd0803ce8000000613722828461443d565b111561375a576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b600080848060200190518101906137839190614e42565b845160c00151815191925063ffffffff908116911610156137e057867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516137ce9190613c24565b60405180910390a260009150506134d6565b82610120015180156138a157506020810151158015906138a15750602081015161014084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561387a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389e9190614714565b14155b806138b35750805163ffffffff168611155b156138e857867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516137ce9190613c24565b5060019695505050505050565b60008060008480602001905181019061390e9190614e9a565b905060008782600001518360200151846040015160405160200161397094939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508461012001518015613a4c5750608082015115801590613a4c5750608082015161014086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a499190614714565b14155b80613a61575086826060015163ffffffff1610155b15613aab57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc30187604051613a969190613c24565b60405180910390a2600093509150613afa9050565b60008181526008602052604090205460ff1615613af257877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e887604051613a969190613c24565b600193509150505b94509492505050565b5080546000825590600052602060002090810190610b229190613bab565b828054828255906000526020600020908101928215613b9b579160200282015b82811115613b9b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613b41565b50613ba7929150613bab565b5090565b5b80821115613ba75760008155600101613bac565b6000815180845260005b81811015613be657602081850181015186830182015201613bca565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612e086020830184613bc0565b73ffffffffffffffffffffffffffffffffffffffff81168114610b2257600080fd5b8035613c6481613c37565b919050565b60008083601f840112613c7b57600080fd5b50813567ffffffffffffffff811115613c9357600080fd5b602083019150836020828501011115613cab57600080fd5b9250929050565b60008060008060608587031215613cc857600080fd5b8435613cd381613c37565b935060208501359250604085013567ffffffffffffffff811115613cf657600080fd5b613d0287828801613c69565b95989497509550505050565b600080600060408486031215613d2357600080fd5b83359250602084013567ffffffffffffffff811115613d4157600080fd5b613d4d86828701613c69565b9497909650939450505050565b60008083601f840112613d6c57600080fd5b50813567ffffffffffffffff811115613d8457600080fd5b6020830191508360208260051b8501011115613cab57600080fd5b60008060008060008060008060e0898b031215613dbb57600080fd5b606089018a811115613dcc57600080fd5b8998503567ffffffffffffffff80821115613de657600080fd5b613df28c838d01613c69565b909950975060808b0135915080821115613e0b57600080fd5b613e178c838d01613d5a565b909750955060a08b0135915080821115613e3057600080fd5b50613e3d8b828c01613d5a565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610220810167ffffffffffffffff81118282101715613ea957613ea9613e56565b60405290565b60405160c0810167ffffffffffffffff81118282101715613ea957613ea9613e56565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f1957613f19613e56565b604052919050565b600067ffffffffffffffff821115613f3b57613f3b613e56565b5060051b60200190565b600082601f830112613f5657600080fd5b81356020613f6b613f6683613f21565b613ed2565b82815260059290921b84018101918181019086841115613f8a57600080fd5b8286015b84811015613fae578035613fa181613c37565b8352918301918301613f8e565b509695505050505050565b803560ff81168114613c6457600080fd5b600082601f830112613fdb57600080fd5b813567ffffffffffffffff811115613ff557613ff5613e56565b61402660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613ed2565b81815284602083860101111561403b57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613c6457600080fd5b60008060008060008060c0878903121561408957600080fd5b863567ffffffffffffffff808211156140a157600080fd5b6140ad8a838b01613f45565b975060208901359150808211156140c357600080fd5b6140cf8a838b01613f45565b96506140dd60408a01613fb9565b955060608901359150808211156140f357600080fd5b6140ff8a838b01613fca565b945061410d60808a01614058565b935060a089013591508082111561412357600080fd5b5061413089828a01613fca565b9150509295509295509295565b60006020828403121561414f57600080fd5b8135612e0881613c37565b63ffffffff81168114610b2257600080fd5b8035613c648161415a565b62ffffff81168114610b2257600080fd5b8035613c6481614177565b61ffff81168114610b2257600080fd5b8035613c6481614193565b6bffffffffffffffffffffffff81168114610b2257600080fd5b8035613c64816141ae565b8015158114610b2257600080fd5b8035613c64816141d3565b600061022082840312156141ff57600080fd5b614207613e85565b90506142128261416c565b81526142206020830161416c565b60208201526142316040830161416c565b604082015261424260608301614188565b6060820152614253608083016141a3565b608082015261426460a083016141c8565b60a082015261427560c0830161416c565b60c082015261428660e0830161416c565b60e082015261010061429981840161416c565b908201526101206142ab83820161416c565b90820152610140828101359082015261016080830135908201526101806142d3818401613c59565b908201526101a08281013567ffffffffffffffff8111156142f357600080fd5b6142ff85828601613f45565b8284015250506101c0614313818401613c59565b908201526101e0614325838201613c59565b908201526102006143378382016141e1565b9082015292915050565b60008060008060008060c0878903121561435a57600080fd5b863567ffffffffffffffff8082111561437257600080fd5b61437e8a838b01613f45565b9750602089013591508082111561439457600080fd5b6143a08a838b01613f45565b96506143ae60408a01613fb9565b955060608901359150808211156143c457600080fd5b6140ff8a838b016141ec565b6000602082840312156143e257600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156133fd576133fd6143e9565b808201808211156120c9576120c96143e9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff81811683821601908111156120c9576120c96143e9565b8051613c648161415a565b8051613c6481614177565b8051613c6481614193565b8051613c64816141ae565b8051613c6481613c37565b600082601f8301126144e057600080fd5b815160206144f0613f6683613f21565b82815260059290921b8401810191818101908684111561450f57600080fd5b8286015b84811015613fae57805161452681613c37565b8352918301918301614513565b8051613c64816141d3565b60006020828403121561455057600080fd5b815167ffffffffffffffff8082111561456857600080fd5b90830190610220828603121561457d57600080fd5b614585613e85565b61458e83614498565b815261459c60208401614498565b60208201526145ad60408401614498565b60408201526145be606084016144a3565b60608201526145cf608084016144ae565b60808201526145e060a084016144b9565b60a08201526145f160c08401614498565b60c082015261460260e08401614498565b60e0820152610100614615818501614498565b90820152610120614627848201614498565b908201526101408381015190820152610160808401519082015261018061464f8185016144c4565b908201526101a0838101518381111561466757600080fd5b614673888287016144cf565b8284015250506101c091506146898284016144c4565b828201526101e0915061469d8284016144c4565b8282015261020091506146b1828401614533565b91810191909152949350505050565b60ff81811683821602908116908181146133fd576133fd6143e9565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361470d5761470d6143e9565b5060010190565b60006020828403121561472657600080fd5b5051919050565b63ffffffff8181168382160190808211156133fd576133fd6143e9565b600081518084526020808501945080840160005b8381101561479057815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161475e565b509495945050505050565b602081526147b260208201835163ffffffff169052565b600060208301516147cb604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006148448185018363ffffffff169052565b840151905061012061485d8482018363ffffffff169052565b84015190506101406148768482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06148b98185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506102206101c081818601526148d961024086018461474a565b908601519092506101e06149048682018373ffffffffffffffffffffffffffffffffffffffff169052565b860151905061020061492d8682018373ffffffffffffffffffffffffffffffffffffffff169052565b90950151151593019290925250919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261496f8184018a61474a565b90508281036080840152614983818961474a565b905060ff871660a084015282810360c08401526149a08187613bc0565b905067ffffffffffffffff851660e08401528281036101008401526149c58185613bc0565b9c9b505050505050505050505050565b828152604060208201526000612ef66040830184613bc0565b60008060408385031215614a0157600080fd5b8251614a0c816141d3565b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614a5357600080fd5b81356020614a63613f6683613f21565b82815260059290921b84018101918181019086841115614a8257600080fd5b8286015b84811015613fae5780358352918301918301614a86565b600082601f830112614aae57600080fd5b81356020614abe613f6683613f21565b82815260059290921b84018101918181019086841115614add57600080fd5b8286015b84811015613fae57803567ffffffffffffffff811115614b015760008081fd5b614b0f8986838b0101613fca565b845250918301918301614ae1565b600060208284031215614b2f57600080fd5b813567ffffffffffffffff80821115614b4757600080fd5b9083019060c08286031215614b5b57600080fd5b614b63613eaf565b8235815260208301356020820152604083013582811115614b8357600080fd5b614b8f87828601614a42565b604083015250606083013582811115614ba757600080fd5b614bb387828601614a42565b606083015250608083013582811115614bcb57600080fd5b614bd787828601614a9d565b60808301525060a083013582811115614bef57600080fd5b614bfb87828601614a9d565b60a08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156133fd576133fd6143e9565b818103818111156120c9576120c96143e9565b80820281158282048414176120c9576120c96143e9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614cbc57614cbc614c7e565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000614cf46080830184613bc0565b9695505050505050565b6bffffffffffffffffffffffff8281168282160390808211156133fd576133fd6143e9565b60006bffffffffffffffffffffffff80841680614d4257614d42614c7e565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114614d7657614d766143e9565b505092915050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614dc58285018b61474a565b91508382036080850152614dd9828a61474a565b915060ff881660a085015283820360c0850152614df68288613bc0565b90861660e085015283810361010085015290506149c58185613bc0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215614e5457600080fd5b6040516040810181811067ffffffffffffffff82111715614e7757614e77613e56565b6040528251614e858161415a565b81526020928301519281019290925250919050565b600060a08284031215614eac57600080fd5b60405160a0810181811067ffffffffffffffff82111715614ecf57614ecf613e56565b806040525082518152602083015160208201526040830151614ef08161415a565b60408201526060830151614f038161415a565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b50604051620051bb380380620051bb8339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051614d96620004256000396000818160d6015261016f01526000611b29015260005050600050506000505060006104330152614d966000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e3d0e7121161005b578063e3d0e712146102e0578063f2fde38b146102f3578063f75f6b1114610306576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102cd576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e322e30000000000000000081525081565b6040516101649190613a92565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610319565b61020e60155460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613b20565b61041b565b610275610270366004613b7c565b610637565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527401000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102db366004613c0d565b6107ad565b6101196102ee366004613ede565b610ae8565b610119610301366004613fab565b610b11565b6101196103143660046141af565b610b25565b60015473ffffffffffffffffffffffffffffffffffffffff16331461039f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461048a576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104c4576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104d28284018461423e565b60008181526004602052604090205490915065010000000000900463ffffffff9081161461052c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600101546105679085906c0100000000000000000000000090046bffffffffffffffffffffffff16614286565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556019546105d29085906142ab565b6019556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b600080610642611b11565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff16156106a1576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f890185900485028101850190955287855290936107a0938990899081908401838280828437600092019190915250611b8292505050565b9097909650945050505050565b60005a60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e010000000000000000000000000000000000000000000000000000000000008304811615801560e08401527f01000000000000000000000000000000000000000000000000000000000000009093048116151561010080840191909152601354918216151561012084015273ffffffffffffffffffffffffffffffffffffffff910416610140820152919250610963576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff166109ac576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a35146109e8576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08101516109f89060016142ed565b60ff1686141580610a095750858414155b15610a40576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a508a8a8a8a8a8a8a8a611dab565b6000610a5c8a8a612014565b905060208b0135600881901c63ffffffff16610a798484876120cf565b836060015163ffffffff168163ffffffff161115610ad957601280547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b610b0986868686806020019051810190610b0291906143ac565b8686610b25565b505050505050565b610b19612a4e565b610b2281612acf565b50565b610b2d612a4e565b601f86511115610b69576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff16600003610ba6576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518651141580610bc55750610bbd84600361452e565b60ff16865111155b15610bfc576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546bffffffffffffffffffffffff9091169060005b816bffffffffffffffffffffffff16811015610c7e57610c6b600e8281548110610c4257610c426142be565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612bc4565b5080610c768161454a565b915050610c16565b5060008060005b836bffffffffffffffffffffffff16811015610d8757600d8181548110610cae57610cae6142be565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff90921694509082908110610ce957610ce96142be565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055915080610d7f8161454a565b915050610c85565b50610d94600d6000613971565b610da0600e6000613971565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c5181101561120957600c60008e8381518110610de557610de56142be565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615610e50576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110610e7a57610e7a6142be565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610ecf576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f8481518110610f0057610f006142be565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110610fa857610fa86142be565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611018576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506110d3576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806112018161454a565b915050610dc6565b50508a5161121f9150600d9060208d019061398f565b50885161123390600e9060208c019061398f565b50604051806101600160405280856bffffffffffffffffffffffff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001600063ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020018960ff1681526020016012600001601e9054906101000a900460ff16151581526020016012600001601f9054906101000a900460ff161515815260200188610200015115158152602001886101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601260008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160186101000a81548162ffffff021916908362ffffff16021790555060a082015181600001601b6101000a81548161ffff021916908361ffff16021790555060c082015181600001601d6101000a81548160ff021916908360ff16021790555060e082015181600001601e6101000a81548160ff02191690831515021790555061010082015181600001601f6101000a81548160ff0219169083151502179055506101208201518160010160006101000a81548160ff0219169083151502179055506101408201518160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601460010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601460010160149054906101000a900463ffffffff1663ffffffff168152602001601460010160189054906101000a900463ffffffff1663ffffffff1681526020016014600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160178190555086610160015160188190555060006014600101601c9054906101000a900463ffffffff169050876101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f89190614582565b601580547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891611973918591780100000000000000000000000000000000000000000000000090041661459b565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000886040516020016119a49190614609565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601554909150611a0d90469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612dcc565b60115560005b611a1d6009612e76565b811015611a4d57611a3a611a32600983612e80565b600990612e93565b5080611a458161454a565b915050611a13565b5060005b896101a0015151811015611aa457611a918a6101a001518281518110611a7957611a796142be565b60200260200101516009612eb590919063ffffffff16565b5080611a9c8161454a565b915050611a51565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601460010160189054906101000a900463ffffffff168f8f8f878f8f604051611afb999897969594939291906147ad565b60405180910390a1505050505050505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611b80576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081907f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611be7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090611c63908590602401613a92565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d1690611d369087908790600401614843565b60408051808303816000875af1158015611d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d78919061485c565b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60008787604051611dbd92919061488a565b604051908190038120611dd4918b9060200161489a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015611fab57600185878360208110611e4057611e406142be565b611e4d91901a601b6142ed565b8c8c85818110611e5f57611e5f6142be565b905060200201358b8b86818110611e7857611e786142be565b9050602002013560405160008152602001604052604051611eb5949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611ed7573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050611f85576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080611fa39061454a565b915050611e23565b50827e01010101010101010101010101010101010101010101010101010101010101841614612006576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61204d6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061205b8385018561498b565b604081015151606082015151919250908114158061207e57508082608001515114155b8061208e5750808260a001515114155b156120c5576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b600082604001515167ffffffffffffffff8111156120ef576120ef613cc4565b6040519080825280602002602001820160405280156121ab57816020015b604080516101c081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161210d5790505b50905060006040518060800160405280600061ffff1681526020016000815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152509050600085610140015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226d9190614582565b9050600086610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e59190614582565b905060005b866040015151811015612734576004600088604001518381518110612311576123116142be565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015285518690839081106123f6576123f66142be565b60200260200101516000018190525061242b8760400151828151811061241e5761241e6142be565b6020026020010151612ed7565b85828151811061243d5761243d6142be565b602002602001015160600190600181111561245a5761245a614a78565b9081600181111561246d5761246d614a78565b815250506124d18760400151828151811061248a5761248a6142be565b602002602001015184896080015184815181106124a9576124a96142be565b60200260200101518885815181106124c3576124c36142be565b60200260200101518c612f82565b8683815181106124e3576124e36142be565b6020026020010151602001878481518110612500576125006142be565b602002602001015160c001828152508215151515815250505084818151811061252b5761252b6142be565b6020026020010151602001511561255b5760018460000181815161254f9190614aa7565b61ffff16905250612560565b612722565b6125c6858281518110612575576125756142be565b602002602001015160000151606001518860600151838151811061259b5761259b6142be565b60200260200101518960a0015184815181106125b9576125b96142be565b6020026020010151611b82565b8683815181106125d8576125d86142be565b60200260200101516040018784815181106125f5576125f56142be565b602090810291909101015160800191909152901515905260c088015161261c9060016142ed565b61262a9060ff166040614ac2565b6103a48860a001518381518110612643576126436142be565b60200260200101515161265691906142ab565b61266091906142ab565b858281518110612672576126726142be565b602002602001015160a0018181525050848181518110612694576126946142be565b602002602001015160a00151846020018181516126b191906142ab565b90525084518590829081106126c8576126c86142be565b602002602001015160800151866126df9190614ad9565b9550612722876040015182815181106126fa576126fa6142be565b602002602001015184878481518110612715576127156142be565b60200260200101516130a1565b8061272c8161454a565b9150506122ea565b50825161ffff1660000361274b5750505050505050565b6155f0612759366010614ac2565b5a6127649088614ad9565b61276e91906142ab565b61277891906142ab565b8351909550611b589061278f9061ffff1687614b1b565b61279991906142ab565b945060008060005b88604001515181101561297d578681815181106127c0576127c06142be565b6020026020010151602001511561296b576128598a8a6040015183815181106127eb576127eb6142be565b6020026020010151898481518110612805576128056142be565b6020026020010151608001518c600001518d602001518d8c602001518e8981518110612833576128336142be565b602002602001015160a001518c61284a9190614ac2565b6128549190614b1b565b6131a6565b6060880180519295509093508391612872908390614286565b6bffffffffffffffffffffffff16905250604086018051849190612897908390614286565b6bffffffffffffffffffffffff1690525086518790829081106128bc576128bc6142be565b6020026020010151604001511515896040015182815181106128e0576128e06142be565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866129159190614286565b8a8581518110612927576129276142be565b6020026020010151608001518c8e60800151878151811061294a5761294a6142be565b60200260200101516040516129629493929190614b2f565b60405180910390a35b806129758161454a565b9150506127a1565b505050604083810151336000908152600b6020529190912080546002906129b99084906201000090046bffffffffffffffffffffffff16614286565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260600151601260000160008282829054906101000a90046bffffffffffffffffffffffff16612a179190614286565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610396565b3373ffffffffffffffffffffffffffffffffffffffff821603612b4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610396565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612dc0576000816060015185612c5c9190614b6c565b90506000612c6a8583614b91565b90508083604001818151612c7e9190614286565b6bffffffffffffffffffffffff16905250612c998582614bbc565b83606001818151612caa9190614286565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000808a8a8a8a8a8a8a8a8a604051602001612df099989796959493929190614bec565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b60006120c9825490565b6000612e8c8383613329565b9392505050565b6000612e8c8373ffffffffffffffffffffffffffffffffffffffff8416613353565b6000612e8c8373ffffffffffffffffffffffffffffffffffffffff841661344d565b6000818160045b600f811015612f64577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612f1c57612f1c6142be565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612f5257506000949350505050565b80612f5c8161454a565b915050612ede565b5081600f1a6001811115612f7a57612f7a614a78565b949350505050565b600080808085606001516001811115612f9d57612f9d614a78565b03612fc357612faf888888888861349c565b612fbe57600092509050613097565b61303b565b600185606001516001811115612fdb57612fdb614a78565b03613009576000612fee89898988613627565b92509050806130035750600092509050613097565b5061303b565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516040015163ffffffff16871061309057877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd56368760405161307d9190613a92565b60405180910390a2600092509050613097565b6001925090505b9550959350505050565b6000816060015160018111156130b9576130b9614a78565b0361311d57600083815260046020526040902060010180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff851602179055505050565b60018160600151600181111561313557613135614a78565b036131a15760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b6000806131b9898886868a8a6001613835565b60008a8152600460205260408120600101549294509092506c010000000000000000000000009091046bffffffffffffffffffffffff16906131fb8385614286565b9050836bffffffffffffffffffffffff16826bffffffffffffffffffffffff16101561322f57509150600090508180613262565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff16101561326257508061325f8482614b6c565b92505b60008a81526004602052604090206001018054829190600c906132a49084906c0100000000000000000000000090046bffffffffffffffffffffffff16614b6c565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008c8152600460205260408120600101805485945090926132ed91859116614286565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505097509795505050505050565b6000826000018281548110613340576133406142be565b9060005260206000200154905092915050565b6000818152600183016020526040812054801561343c576000613377600183614ad9565b855490915060009061338b90600190614ad9565b90508181146133f05760008660000182815481106133ab576133ab6142be565b90600052602060002001549050808760000184815481106133ce576133ce6142be565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061340157613401614c81565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506120c9565b60009150506120c9565b5092915050565b6000818152600183016020526040812054613494575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556120c9565b5060006120c9565b600080848060200190518101906134b39190614cb0565b845160c00151815191925063ffffffff9081169116101561351057867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516134fe9190613a92565b60405180910390a2600091505061361e565b82610120015180156135d157506020810151158015906135d15750602081015161014084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa1580156135aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ce9190614582565b14155b806135e35750805163ffffffff168611155b1561361857867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516134fe9190613a92565b60019150505b95945050505050565b6000806000848060200190518101906136409190614d08565b90506000878260000151836020015184604001516040516020016136a294939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b604051602081830303815290604052805190602001209050846101200151801561377e575060808201511580159061377e5750608082015161014086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061377b9190614582565b14155b80613793575086826060015163ffffffff1610155b156137dd57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516137c89190613a92565b60405180910390a260009350915061382c9050565b60008181526008602052604090205460ff161561382457877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516137c89190613a92565b600193509150505b94509492505050565b60008060008960a0015161ffff168661384e9190614ac2565b905083801561385c5750803a105b1561386457503a5b600085886138728b8d6142ab565b61387c9085614ac2565b61388691906142ab565b61389890670de0b6b3a7640000614ac2565b6138a29190614b1b565b905060008b6040015163ffffffff1664e8d4a510006138c19190614ac2565b60208d0151889063ffffffff168b6138d98f88614ac2565b6138e391906142ab565b6138f190633b9aca00614ac2565b6138fb9190614ac2565b6139059190614b1b565b61390f91906142ab565b90506b033b2e3c9fd0803ce800000061392882846142ab565b1115613960576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b5080546000825590600052602060002090810190610b229190613a19565b828054828255906000526020600020908101928215613a09579160200282015b82811115613a0957825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906139af565b50613a15929150613a19565b5090565b5b80821115613a155760008155600101613a1a565b6000815180845260005b81811015613a5457602081850181015186830182015201613a38565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612e8c6020830184613a2e565b73ffffffffffffffffffffffffffffffffffffffff81168114610b2257600080fd5b8035613ad281613aa5565b919050565b60008083601f840112613ae957600080fd5b50813567ffffffffffffffff811115613b0157600080fd5b602083019150836020828501011115613b1957600080fd5b9250929050565b60008060008060608587031215613b3657600080fd5b8435613b4181613aa5565b935060208501359250604085013567ffffffffffffffff811115613b6457600080fd5b613b7087828801613ad7565b95989497509550505050565b600080600060408486031215613b9157600080fd5b83359250602084013567ffffffffffffffff811115613baf57600080fd5b613bbb86828701613ad7565b9497909650939450505050565b60008083601f840112613bda57600080fd5b50813567ffffffffffffffff811115613bf257600080fd5b6020830191508360208260051b8501011115613b1957600080fd5b60008060008060008060008060e0898b031215613c2957600080fd5b606089018a811115613c3a57600080fd5b8998503567ffffffffffffffff80821115613c5457600080fd5b613c608c838d01613ad7565b909950975060808b0135915080821115613c7957600080fd5b613c858c838d01613bc8565b909750955060a08b0135915080821115613c9e57600080fd5b50613cab8b828c01613bc8565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610220810167ffffffffffffffff81118282101715613d1757613d17613cc4565b60405290565b60405160c0810167ffffffffffffffff81118282101715613d1757613d17613cc4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d8757613d87613cc4565b604052919050565b600067ffffffffffffffff821115613da957613da9613cc4565b5060051b60200190565b600082601f830112613dc457600080fd5b81356020613dd9613dd483613d8f565b613d40565b82815260059290921b84018101918181019086841115613df857600080fd5b8286015b84811015613e1c578035613e0f81613aa5565b8352918301918301613dfc565b509695505050505050565b803560ff81168114613ad257600080fd5b600082601f830112613e4957600080fd5b813567ffffffffffffffff811115613e6357613e63613cc4565b613e9460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613d40565b818152846020838601011115613ea957600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613ad257600080fd5b60008060008060008060c08789031215613ef757600080fd5b863567ffffffffffffffff80821115613f0f57600080fd5b613f1b8a838b01613db3565b97506020890135915080821115613f3157600080fd5b613f3d8a838b01613db3565b9650613f4b60408a01613e27565b95506060890135915080821115613f6157600080fd5b613f6d8a838b01613e38565b9450613f7b60808a01613ec6565b935060a0890135915080821115613f9157600080fd5b50613f9e89828a01613e38565b9150509295509295509295565b600060208284031215613fbd57600080fd5b8135612e8c81613aa5565b63ffffffff81168114610b2257600080fd5b8035613ad281613fc8565b62ffffff81168114610b2257600080fd5b8035613ad281613fe5565b61ffff81168114610b2257600080fd5b8035613ad281614001565b6bffffffffffffffffffffffff81168114610b2257600080fd5b8035613ad28161401c565b8015158114610b2257600080fd5b8035613ad281614041565b6000610220828403121561406d57600080fd5b614075613cf3565b905061408082613fda565b815261408e60208301613fda565b602082015261409f60408301613fda565b60408201526140b060608301613ff6565b60608201526140c160808301614011565b60808201526140d260a08301614036565b60a08201526140e360c08301613fda565b60c08201526140f460e08301613fda565b60e0820152610100614107818401613fda565b90820152610120614119838201613fda565b9082015261014082810135908201526101608083013590820152610180614141818401613ac7565b908201526101a08281013567ffffffffffffffff81111561416157600080fd5b61416d85828601613db3565b8284015250506101c0614181818401613ac7565b908201526101e0614193838201613ac7565b908201526102006141a583820161404f565b9082015292915050565b60008060008060008060c087890312156141c857600080fd5b863567ffffffffffffffff808211156141e057600080fd5b6141ec8a838b01613db3565b9750602089013591508082111561420257600080fd5b61420e8a838b01613db3565b965061421c60408a01613e27565b9550606089013591508082111561423257600080fd5b613f6d8a838b0161405a565b60006020828403121561425057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff81811683821601908082111561344657613446614257565b808201808211156120c9576120c9614257565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff81811683821601908111156120c9576120c9614257565b8051613ad281613fc8565b8051613ad281613fe5565b8051613ad281614001565b8051613ad28161401c565b8051613ad281613aa5565b600082601f83011261434e57600080fd5b8151602061435e613dd483613d8f565b82815260059290921b8401810191818101908684111561437d57600080fd5b8286015b84811015613e1c57805161439481613aa5565b8352918301918301614381565b8051613ad281614041565b6000602082840312156143be57600080fd5b815167ffffffffffffffff808211156143d657600080fd5b9083019061022082860312156143eb57600080fd5b6143f3613cf3565b6143fc83614306565b815261440a60208401614306565b602082015261441b60408401614306565b604082015261442c60608401614311565b606082015261443d6080840161431c565b608082015261444e60a08401614327565b60a082015261445f60c08401614306565b60c082015261447060e08401614306565b60e0820152610100614483818501614306565b90820152610120614495848201614306565b90820152610140838101519082015261016080840151908201526101806144bd818501614332565b908201526101a083810151838111156144d557600080fd5b6144e18882870161433d565b8284015250506101c091506144f7828401614332565b828201526101e0915061450b828401614332565b82820152610200915061451f8284016143a1565b91810191909152949350505050565b60ff818116838216029081169081811461344657613446614257565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457b5761457b614257565b5060010190565b60006020828403121561459457600080fd5b5051919050565b63ffffffff81811683821601908082111561344657613446614257565b600081518084526020808501945080840160005b838110156145fe57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016145cc565b509495945050505050565b6020815261462060208201835163ffffffff169052565b60006020830151614639604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006146b28185018363ffffffff169052565b84015190506101206146cb8482018363ffffffff169052565b84015190506101406146e48482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147278185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506102206101c081818601526147476102408601846145b8565b908601519092506101e06147728682018373ffffffffffffffffffffffffffffffffffffffff169052565b860151905061020061479b8682018373ffffffffffffffffffffffffffffffffffffffff169052565b90950151151593019290925250919050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526147dd8184018a6145b8565b905082810360808401526147f181896145b8565b905060ff871660a084015282810360c084015261480e8187613a2e565b905067ffffffffffffffff851660e08401528281036101008401526148338185613a2e565b9c9b505050505050505050505050565b828152604060208201526000612f7a6040830184613a2e565b6000806040838503121561486f57600080fd5b825161487a81614041565b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f8301126148c157600080fd5b813560206148d1613dd483613d8f565b82815260059290921b840181019181810190868411156148f057600080fd5b8286015b84811015613e1c57803583529183019183016148f4565b600082601f83011261491c57600080fd5b8135602061492c613dd483613d8f565b82815260059290921b8401810191818101908684111561494b57600080fd5b8286015b84811015613e1c57803567ffffffffffffffff81111561496f5760008081fd5b61497d8986838b0101613e38565b84525091830191830161494f565b60006020828403121561499d57600080fd5b813567ffffffffffffffff808211156149b557600080fd5b9083019060c082860312156149c957600080fd5b6149d1613d1d565b82358152602083013560208201526040830135828111156149f157600080fd5b6149fd878286016148b0565b604083015250606083013582811115614a1557600080fd5b614a21878286016148b0565b606083015250608083013582811115614a3957600080fd5b614a458782860161490b565b60808301525060a083013582811115614a5d57600080fd5b614a698782860161490b565b60a08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff81811683821601908082111561344657613446614257565b80820281158282048414176120c9576120c9614257565b818103818111156120c9576120c9614257565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614b2a57614b2a614aec565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000614b626080830184613a2e565b9695505050505050565b6bffffffffffffffffffffffff82811682821603908082111561344657613446614257565b60006bffffffffffffffffffffffff80841680614bb057614bb0614aec565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114614be457614be4614257565b505092915050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614c338285018b6145b8565b91508382036080850152614c47828a6145b8565b915060ff881660a085015283820360c0850152614c648288613a2e565b90861660e085015283810361010085015290506148338185613a2e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215614cc257600080fd5b6040516040810181811067ffffffffffffffff82111715614ce557614ce5613cc4565b6040528251614cf381613fc8565b81526020928301519281019290925250919050565b600060a08284031215614d1a57600080fd5b60405160a0810181811067ffffffffffffffff82111715614d3d57614d3d613cc4565b806040525082518152602083015160208201526040830151614d5e81613fc8565b60408201526060830151614d7181613fc8565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", } var AutomationRegistryABI = AutomationRegistryMetaData.ABI diff --git a/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2/i_automation_registry_master_wrapper_2_2.go similarity index 85% rename from core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go rename to core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2/i_automation_registry_master_wrapper_2_2.go index 829f3a57e4b..611dc43af9e 100644 --- a/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_2/i_keeper_registry_master_wrapper_2_2.go +++ b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2/i_automation_registry_master_wrapper_2_2.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package i_keeper_registry_master_wrapper_2_2 +package i_automation_registry_master_wrapper_2_2 import ( "errors" @@ -95,7 +95,7 @@ type AutomationRegistryBase22UpkeepInfo struct { } var IAutomationRegistryMasterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"setChainSpecificModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_2.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var IAutomationRegistryMasterABI = IAutomationRegistryMasterMetaData.ABI @@ -843,6 +843,50 @@ func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetSta return _IAutomationRegistryMaster.Contract.GetState(&_IAutomationRegistryMaster.CallOpts) } +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getTransmitCalldataFixedBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataFixedBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataFixedBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getTransmitCalldataPerSignerBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) { @@ -1346,18 +1390,6 @@ func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) Se return _IAutomationRegistryMaster.Contract.SetAdminPrivilegeConfig(&_IAutomationRegistryMaster.TransactOpts, admin, newPrivilegeConfig) } -func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) { - return _IAutomationRegistryMaster.contract.Transact(opts, "setChainSpecificModule", newModule) -} - -func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { - return _IAutomationRegistryMaster.Contract.SetChainSpecificModule(&_IAutomationRegistryMaster.TransactOpts, newModule) -} - -func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetChainSpecificModule(newModule common.Address) (*types.Transaction, error) { - return _IAutomationRegistryMaster.Contract.SetChainSpecificModule(&_IAutomationRegistryMaster.TransactOpts, newModule) -} - func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { return _IAutomationRegistryMaster.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } @@ -6339,6 +6371,10 @@ type IAutomationRegistryMasterInterface interface { error) + GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) @@ -6403,8 +6439,6 @@ type IAutomationRegistryMasterInterface interface { SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) - SetChainSpecificModule(opts *bind.TransactOpts, newModule common.Address) (*types.Transaction, error) - SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase22OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index a94cf5a462c..5aae6183434 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -7,6 +7,9 @@ automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBe automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 automation_registrar_wrapper2_2: ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin 7c61908c1bb1bfd05a4da22bb73d62c0e2c05240f3f8fb5e06331603ff2246a9 +automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 38036d73155b89d241e6f17aab0af78be21e90dfa9e455cd575fe02d1a6474f9 +automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin e5669214a6b747b17331ebbf8f2d13cf7100d3313d652c6f1304ccf158441fc6 +automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin eca1187a878b622ef3fced041a28a4229d45dd797d95630838ff6351b6afc437 automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 331bfa79685aee6ddf63b64c0747abee556c454cae3fb8175edff425b615d8aa automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 6fe2e41b1d3b74bee4013a48c10d84da25e559f28e22749aa13efabbf2cc2ee8 batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore/BatchBlockhashStore.bin 14356c48ef70f66ef74f22f644450dbf3b2a147c1b68deaa7e7d1eb8ffab15db @@ -23,8 +26,8 @@ flags_wrapper: ../../contracts/solc/v0.6/Flags/Flags.abi ../../contracts/solc/v0 flux_aggregator_wrapper: ../../contracts/solc/v0.6/FluxAggregator/FluxAggregator.abi ../../contracts/solc/v0.6/FluxAggregator/FluxAggregator.bin a3b0a6396c4aa3b5ee39b3c4bd45efc89789d4859379a8a92caca3a0496c5794 gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723 gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8 +i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 0886dd1df1f4dcf5b08012f8adcf30fd96caab28999610e70ce02beb2170c92f i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin 6501bb9bcf5048bab2737b00685c6984a24867e234ddf5b60a65904eee9a4ebc -i_keeper_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 0ce3cb008ba9681b8d08aa4e8b0b1f5b5b96852abf7c388e48166a9aeacc72f0 i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin 296beccb6af655d6fc3a6e676b244831cce2da6688d3afc4f21f8738ae59e03e keeper_consumer_performance_wrapper: ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.abi ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.bin eeda39f5d3e1c8ffa0fb6cd1803731b98a4bc262d41833458e3fe8b40933ae90 keeper_consumer_wrapper: ../../contracts/solc/v0.8.16/KeeperConsumer/KeeperConsumer.abi ../../contracts/solc/v0.8.16/KeeperConsumer/KeeperConsumer.bin 2c6163b145082fbab74b7343577a9cec8fda8b0da9daccf2a82581b1f5a84b83 @@ -34,16 +37,13 @@ keeper_registrar_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistrar2_0/Keep keeper_registry_logic1_3: ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3/KeeperRegistryLogic1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3/KeeperRegistryLogic1_3.bin 903f8b9c8e25425ca6d0b81b89e339d695a83630bfbfa24a6f3b38869676bc5a keeper_registry_logic2_0: ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0/KeeperRegistryLogic2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0/KeeperRegistryLogic2_0.bin d69d2bc8e4844293dbc2d45abcddc50b84c88554ecccfa4fa77c0ca45ec80871 keeper_registry_logic_a_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1/KeeperRegistryLogicA2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1/KeeperRegistryLogicA2_1.bin 77481ab75c9aa86a62a7b2a708599b5ea1a6346ed1c0def6d4826e7ae523f1ee -keeper_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 6bcf855e020256092a9d02be38d143006d3261c7531d2c98fb42f19296f08d6b keeper_registry_logic_b_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.bin 467d10741a04601b136553a2b1c6ab37f2a65d809366faf03180a22ff26be215 -keeper_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin 12f4fd408e4bed3ce5312c7f89a83e6a39ad95009c8f598d50f705fdc9463fdf keeper_registry_wrapper1_1: ../../contracts/solc/v0.7/KeeperRegistry1_1/KeeperRegistry1_1.abi ../../contracts/solc/v0.7/KeeperRegistry1_1/KeeperRegistry1_1.bin 6ce079f2738f015f7374673a2816e8e9787143d00b780ea7652c8aa9ad9e1e20 keeper_registry_wrapper1_1_mock: ../../contracts/solc/v0.7/KeeperRegistry1_1Mock/KeeperRegistry1_1Mock.abi ../../contracts/solc/v0.7/KeeperRegistry1_1Mock/KeeperRegistry1_1Mock.bin 98ddb3680e86359de3b5d17e648253ba29a84703f087a1b52237824003a8c6df keeper_registry_wrapper1_2: ../../contracts/solc/v0.8.6/KeeperRegistry1_2/KeeperRegistry1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_2/KeeperRegistry1_2.bin a40ff877dd7c280f984cbbb2b428e160662b0c295e881d5f778f941c0088ca22 keeper_registry_wrapper1_3: ../../contracts/solc/v0.8.6/KeeperRegistry1_3/KeeperRegistry1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_3/KeeperRegistry1_3.bin d4dc760b767ae274ee25c4a604ea371e1fa603a7b6421b69efb2088ad9e8abb3 keeper_registry_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistry2_0/KeeperRegistry2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistry2_0/KeeperRegistry2_0.bin c32dea7d5ef66b7c58ddc84ddf69aa44df1b3ae8601fbc271c95be4ff5853056 keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1/KeeperRegistry2_1.bin 604e4a0cd980c713929b523b999462a3aa0ed06f96ff563a4c8566cf59c8445b -keeper_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin 0defe584ccaab499a584eecd742442ec06f8aacd80fbacb85a25c42b227ef6d2 keepers_vrf_consumer: ../../contracts/solc/v0.8.6/KeepersVRFConsumer/KeepersVRFConsumer.abi ../../contracts/solc/v0.8.6/KeepersVRFConsumer/KeepersVRFConsumer.bin fa75572e689c9e84705c63e8dbe1b7b8aa1a8fe82d66356c4873d024bb9166e8 log_emitter: ../../contracts/solc/v0.8.19/LogEmitter/LogEmitter.abi ../../contracts/solc/v0.8.19/LogEmitter/LogEmitter.bin 4b129ab93432c95ff9143f0631323e189887668889e0b36ccccf18a571e41ccf log_triggered_streams_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.bin f8da43a927c1a66238a9f4fd5d5dd7e280e361daa0444da1f7f79498ace901e1 diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index de6097f31d4..be07a548a4e 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -57,10 +57,10 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin IKeeperRegistryMaster i_keeper_registry_master_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin AutomationUtils automation_utils_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin AutomationRegistrar automation_registrar_wrapper2_2 -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin AutomationRegistry keeper_registry_wrapper_2_2 -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin AutomationRegistryLogicA keeper_registry_logic_a_wrapper_2_2 -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin AutomationRegistryLogicB keeper_registry_logic_b_wrapper_2_2 -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin IAutomationRegistryMaster i_keeper_registry_master_wrapper_2_2 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin AutomationRegistry automation_registry_wrapper_2_2 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin AutomationRegistryLogicA automation_registry_logic_a_wrapper_2_2 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin AutomationRegistryLogicB automation_registry_logic_b_wrapper_2_2 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin IAutomationRegistryMaster i_automation_registry_master_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin AutomationUtils automation_utils_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin ILogAutomation i_log_automation //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin AutomationForwarderLogic automation_forwarder_logic From cce6c80d9b815f173ec6240bda9e7ece2eed3d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sat, 17 Feb 2024 05:47:43 +0900 Subject: [PATCH 48/98] Keystone: EVM write capability + forwarder contract (#12045) * Add keystone forwarder contract + EVM write capability * Dust off nix flake, update dependencies * KeystoneForwarder: Test basic functionality * Use chain-selectors to name the capability * Mark utils as internal for inlining? * Add missing gethwrappers * Fix go.md --------- Co-authored-by: Bolek Kulbabinski <1416262+bolekk@users.noreply.github.com> --- .github/workflows/solidity-foundry.yml | 2 +- .github/workflows/solidity-hardhat.yml | 2 +- common/txmgr/types/tx.go | 3 + contracts/GNUmakefile | 2 +- contracts/foundry.toml | 6 + contracts/gas-snapshots/keystone.gas-snapshot | 2 + contracts/scripts/native_solc_compile_all | 2 +- .../scripts/native_solc_compile_all_keystone | 31 + .../src/v0.8/keystone/KeystoneForwarder.sol | 80 +++ .../v0.8/keystone/interfaces/IForwarder.sol | 5 + .../src/v0.8/keystone/libraries/Utils.sol | 42 ++ .../keystone/test/KeystoneForwarder.t.sol | 66 ++ core/capabilities/targets/write_target.go | 239 +++++++ .../capabilities/targets/write_target_test.go | 92 +++ core/chains/evm/config/chain_scoped.go | 4 + .../evm/config/chain_scoped_chain_writer.go | 18 + core/chains/evm/config/config.go | 7 + core/chains/evm/config/toml/config.go | 15 + core/chains/evm/config/toml/defaults.go | 1 + core/config/docs/chains-evm.toml | 6 + core/config/docs/docs_test.go | 4 + core/gethwrappers/go_generate.go | 3 + .../keystone/generated/forwarder/forwarder.go | 600 ++++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 2 + core/gethwrappers/keystone/go_generate.go | 7 + core/scripts/go.mod | 1 + core/scripts/go.sum | 2 + core/services/chainlink/application.go | 1 + core/services/chainlink/config_test.go | 8 + core/services/workflows/delegate.go | 7 +- docs/CONFIG.md | 20 + flake.lock | 30 +- go.md | 3 +- go.mod | 1 + go.sum | 2 + integration-tests/go.mod | 1 + integration-tests/go.sum | 2 + shell.nix | 13 +- 38 files changed, 1311 insertions(+), 21 deletions(-) create mode 100644 contracts/gas-snapshots/keystone.gas-snapshot create mode 100755 contracts/scripts/native_solc_compile_all_keystone create mode 100644 contracts/src/v0.8/keystone/KeystoneForwarder.sol create mode 100644 contracts/src/v0.8/keystone/interfaces/IForwarder.sol create mode 100644 contracts/src/v0.8/keystone/libraries/Utils.sol create mode 100644 contracts/src/v0.8/keystone/test/KeystoneForwarder.t.sol create mode 100644 core/capabilities/targets/write_target.go create mode 100644 core/capabilities/targets/write_target_test.go create mode 100644 core/chains/evm/config/chain_scoped_chain_writer.go create mode 100644 core/gethwrappers/keystone/generated/forwarder/forwarder.go create mode 100644 core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt create mode 100644 core/gethwrappers/keystone/go_generate.go diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 7c930207fe7..47f9571eea3 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -32,7 +32,7 @@ jobs: strategy: fail-fast: false matrix: - product: [vrf, automation, llo-feeds, l2ep, functions, shared] + product: [vrf, automation, llo-feeds, l2ep, functions, keystone, shared] needs: [changes] name: Foundry Tests ${{ matrix.product }} # See https://github.com/foundry-rs/foundry/issues/3827 diff --git a/.github/workflows/solidity-hardhat.yml b/.github/workflows/solidity-hardhat.yml index da9d7daccbb..f07c9f8fdca 100644 --- a/.github/workflows/solidity-hardhat.yml +++ b/.github/workflows/solidity-hardhat.yml @@ -25,7 +25,7 @@ jobs: with: filters: | src: - - 'contracts/src/!(v0.8/(llo-feeds|ccip)/**)/**/*' + - 'contracts/src/!(v0.8/(llo-feeds|keystone|ccip)/**)/**/*' - 'contracts/test/**/*' - 'contracts/package.json' - 'contracts/pnpm-lock.yaml' diff --git a/common/txmgr/types/tx.go b/common/txmgr/types/tx.go index 27cda86f6eb..3b294adcd07 100644 --- a/common/txmgr/types/tx.go +++ b/common/txmgr/types/tx.go @@ -150,6 +150,9 @@ type TxMeta[ADDR types.Hashable, TX_HASH types.Hashable] struct { ForceFulfilled *bool `json:"ForceFulfilled,omitempty"` ForceFulfillmentAttempt *uint64 `json:"ForceFulfillmentAttempt,omitempty"` + // Used for Keystone Workflows + WorkflowExecutionID *string `json:"WorkflowExecutionID,omitempty"` + // Used only for forwarded txs, tracks the original destination address. // When this is set, it indicates tx is forwarded through To address. FwdrDestAddress *ADDR `json:"ForwarderDestAddress,omitempty"` diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index f666014c48f..751a47b3be4 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -1,6 +1,6 @@ # ALL_FOUNDRY_PRODUCTS contains a list of all products that have a foundry # profile defined and use the Foundry snapshots. -ALL_FOUNDRY_PRODUCTS = l2ep llo-feeds functions shared +ALL_FOUNDRY_PRODUCTS = l2ep llo-feeds functions keystone shared # To make a snapshot for a specific product, either set the `FOUNDRY_PROFILE` env var # or call the target with `FOUNDRY_PROFILE=product` diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 931f0d12361..13807c71bdf 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -46,6 +46,12 @@ test = 'src/v0.8/llo-feeds/test' solc_version = '0.8.19' # We cannot turn on deny_warnings = true as that will hide any CI failure +[profile.keystone] +solc_version = '0.8.19' +src = 'src/v0.8/keystone' +test = 'src/v0.8/keystone/test' +optimizer_runs = 10_000 + [profile.shared] optimizer_runs = 1000000 src = 'src/v0.8/shared' diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot new file mode 100644 index 00000000000..be23de1fc62 --- /dev/null +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -0,0 +1,2 @@ +KeystoneForwarderTest:test_abi_partial_decoding_works() (gas: 2068) +KeystoneForwarderTest:test_it_works() (gas: 993848) \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all b/contracts/scripts/native_solc_compile_all index cf1226a2d5c..f4cec6ce1ee 100755 --- a/contracts/scripts/native_solc_compile_all +++ b/contracts/scripts/native_solc_compile_all @@ -12,7 +12,7 @@ python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt # 6 and 7 are legacy contracts, for each other product we have a native_solc_compile_all_$product script # These scripts can be run individually, or all together with this script. # To add new CL products, simply write a native_solc_compile_all_$product script and add it to the list below. -for product in 6 7 automation events_mock feeds functions llo-feeds logpoller operatorforwarder shared transmission vrf +for product in 6 7 automation events_mock feeds functions keystone llo-feeds logpoller operatorforwarder shared transmission vrf do $SCRIPTPATH/native_solc_compile_all_$product done diff --git a/contracts/scripts/native_solc_compile_all_keystone b/contracts/scripts/native_solc_compile_all_keystone new file mode 100755 index 00000000000..3f4d33d6ecc --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_keystone @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling Keystone contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.19" +OPTIMIZE_RUNS=1000000 + + +SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +python3 -m pip install --require-hashes -r "$SCRIPTPATH"/requirements.txt +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION +export SOLC_VERSION=$SOLC_VERSION + +ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ../../ && pwd -P )" + +compileContract () { + local contract + contract=$(basename "$1" ".sol") + + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \ + --abi --bin --allow-paths "$ROOT"/contracts/src/v0.8\ + "$ROOT"/contracts/src/v0.8/"$1" +} + +compileContract keystone/KeystoneForwarder.sol diff --git a/contracts/src/v0.8/keystone/KeystoneForwarder.sol b/contracts/src/v0.8/keystone/KeystoneForwarder.sol new file mode 100644 index 00000000000..2fa3304addc --- /dev/null +++ b/contracts/src/v0.8/keystone/KeystoneForwarder.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {IForwarder} from "./interfaces/IForwarder.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; +import {Utils} from "./libraries/Utils.sol"; + +// solhint-disable custom-errors, no-unused-vars +contract KeystoneForwarder is IForwarder, ConfirmedOwner, TypeAndVersionInterface { + error ReentrantCall(); + + struct HotVars { + bool reentrancyGuard; // guard against reentrancy + } + + HotVars internal s_hotVars; // Mixture of config and state, commonly accessed + + mapping(bytes32 => address) internal s_reports; + + constructor() ConfirmedOwner(msg.sender) {} + + // send a report to targetAddress + function report( + address targetAddress, + bytes calldata data, + bytes[] calldata signatures + ) external nonReentrant returns (bool) { + require(data.length > 4 + 64, "invalid data length"); + + // data is an encoded call with the selector prefixed: (bytes4 selector, bytes report, ...) + // we are able to partially decode just the first param, since we don't know the rest + bytes memory rawReport = abi.decode(data[4:], (bytes)); + + // TODO: we probably need some type of f value config? + + bytes32 hash = keccak256(rawReport); + + // validate signatures + for (uint256 i = 0; i < signatures.length; i++) { + // TODO: is libocr-style multiple bytes32 arrays more optimal? + (bytes32 r, bytes32 s, uint8 v) = Utils._splitSignature(signatures[i]); + address signer = ecrecover(hash, v, r, s); + // TODO: we need to store oracle cluster similar to aggregator then, to validate valid signer list + } + + (bytes32 workflowId, bytes32 workflowExecutionId) = Utils._splitReport(rawReport); + + // report was already processed + if (s_reports[workflowExecutionId] != address(0)) { + return false; + } + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory result) = targetAddress.call(data); + + s_reports[workflowExecutionId] = msg.sender; + return true; + } + + // get transmitter of a given report or 0x0 if it wasn't transmitted yet + function getTransmitter(bytes32 workflowExecutionId) external view returns (address) { + return s_reports[workflowExecutionId]; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "KeystoneForwarder 1.0.0"; + } + + /** + * @dev replicates Open Zeppelin's ReentrancyGuard but optimized to fit our storage + */ + modifier nonReentrant() { + if (s_hotVars.reentrancyGuard) revert ReentrantCall(); + s_hotVars.reentrancyGuard = true; + _; + s_hotVars.reentrancyGuard = false; + } +} diff --git a/contracts/src/v0.8/keystone/interfaces/IForwarder.sol b/contracts/src/v0.8/keystone/interfaces/IForwarder.sol new file mode 100644 index 00000000000..ce9512c6570 --- /dev/null +++ b/contracts/src/v0.8/keystone/interfaces/IForwarder.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @title IForwarder - forwards keystone reports to a target +interface IForwarder {} diff --git a/contracts/src/v0.8/keystone/libraries/Utils.sol b/contracts/src/v0.8/keystone/libraries/Utils.sol new file mode 100644 index 00000000000..3a11c0792a1 --- /dev/null +++ b/contracts/src/v0.8/keystone/libraries/Utils.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// solhint-disable custom-errors +library Utils { + // solhint-disable avoid-low-level-calls, chainlink-solidity/explicit-returns + function _splitSignature(bytes memory sig) internal pure returns (bytes32 r, bytes32 s, uint8 v) { + require(sig.length == 65, "invalid signature length"); + + assembly { + /* + First 32 bytes stores the length of the signature + + add(sig, 32) = pointer of sig + 32 + effectively, skips first 32 bytes of signature + + mload(p) loads next 32 bytes starting at the memory address p into memory + */ + + // first 32 bytes, after the length prefix + r := mload(add(sig, 32)) + // second 32 bytes + s := mload(add(sig, 64)) + // final byte (first byte of the next 32 bytes) + v := byte(0, mload(add(sig, 96))) + } + + // implicitly return (r, s, v) + } + + // solhint-disable avoid-low-level-calls, chainlink-solidity/explicit-returns + function _splitReport( + bytes memory rawReport + ) internal pure returns (bytes32 workflowId, bytes32 workflowExecutionId) { + require(rawReport.length > 64, "invalid report length"); + assembly { + // skip first 32 bytes, contains length of the report + workflowId := mload(add(rawReport, 32)) + workflowExecutionId := mload(add(rawReport, 64)) + } + } +} diff --git a/contracts/src/v0.8/keystone/test/KeystoneForwarder.t.sol b/contracts/src/v0.8/keystone/test/KeystoneForwarder.t.sol new file mode 100644 index 00000000000..10d4cb3f9c2 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/KeystoneForwarder.t.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "forge-std/Test.sol"; + +import "../KeystoneForwarder.sol"; +import {Utils} from "../libraries/Utils.sol"; + +contract Receiver { + event MessageReceived(bytes32 indexed workflowId, bytes32 indexed workflowExecutionId, bytes[] mercuryReports); + + constructor() {} + + function foo(bytes calldata rawReport) external { + // decode metadata + (bytes32 workflowId, bytes32 workflowExecutionId) = Utils._splitReport(rawReport); + // parse actual report + bytes[] memory mercuryReports = abi.decode(rawReport[64:], (bytes[])); + emit MessageReceived(workflowId, workflowExecutionId, mercuryReports); + } +} + +contract KeystoneForwarderTest is Test { + function setUp() public virtual {} + + function test_abi_partial_decoding_works() public { + bytes memory report = hex"0102"; + uint256 amount = 1; + bytes memory payload = abi.encode(report, amount); + bytes memory decodedReport = abi.decode(payload, (bytes)); + assertEq(decodedReport, report, "not equal"); + } + + function test_it_works() public { + KeystoneForwarder forwarder = new KeystoneForwarder(); + Receiver receiver = new Receiver(); + + // taken from https://github.com/smartcontractkit/chainlink/blob/2390ec7f3c56de783ef4e15477e99729f188c524/core/services/relay/evm/cap_encoder_test.go#L42-L55 + bytes + memory report = hex"6d795f69640000000000000000000000000000000000000000000000000000006d795f657865637574696f6e5f696400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000301020300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004aabbccdd00000000000000000000000000000000000000000000000000000000"; + bytes memory data = abi.encodeWithSignature("foo(bytes)", report); + bytes[] memory signatures = new bytes[](0); + + vm.expectCall(address(receiver), data); + vm.recordLogs(); + + bool delivered1 = forwarder.report(address(receiver), data, signatures); + assertTrue(delivered1, "report not delivered"); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(entries[0].emitter, address(receiver)); + // validate workflow id and workflow execution id + bytes32 workflowId = hex"6d795f6964000000000000000000000000000000000000000000000000000000"; + bytes32 executionId = hex"6d795f657865637574696f6e5f69640000000000000000000000000000000000"; + assertEq(entries[0].topics[1], workflowId); + assertEq(entries[0].topics[2], executionId); + bytes[] memory mercuryReports = abi.decode(entries[0].data, (bytes[])); + assertEq(mercuryReports.length, 2); + assertEq(mercuryReports[0], hex"010203"); + assertEq(mercuryReports[1], hex"aabbccdd"); + + // doesn't deliver the same report more than once + bool delivered2 = forwarder.report(address(receiver), data, signatures); + assertFalse(delivered2, "report redelivered"); + } +} diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go new file mode 100644 index 00000000000..c6d34271662 --- /dev/null +++ b/core/capabilities/targets/write_target.go @@ -0,0 +1,239 @@ +package targets + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" + + chainselectors "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/values" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" + abiutil "github.com/smartcontractkit/chainlink/v2/core/chains/evm/abi" + "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/services/pipeline" +) + +var forwardABI = evmtypes.MustGetABI(forwarder.KeystoneForwarderMetaData.ABI) + +func InitializeWrite(registry commontypes.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer) error { + for _, chain := range legacyEVMChains.Slice() { + capability := NewEvmWrite(chain) + if err := registry.Add(context.TODO(), capability); err != nil { + return err + } + } + return nil +} + +var ( + _ capabilities.ActionCapability = &EvmWrite{} +) + +type EvmWrite struct { + chain legacyevm.Chain + capabilities.CapabilityInfo +} + +func NewEvmWrite(chain legacyevm.Chain) *EvmWrite { + // generate ID based on chain selector + name := fmt.Sprintf("write_%v", chain.ID()) + chainName, err := chainselectors.NameFromChainId(chain.ID().Uint64()) + if err == nil { + name = fmt.Sprintf("write_%v", chainName) + } + + info := capabilities.MustNewCapabilityInfo( + name, + capabilities.CapabilityTypeTarget, + "Write target.", + "v1.0.0", + ) + + return &EvmWrite{ + chain, + info, + } +} + +type EvmConfig struct { + ChainID uint + Address string + Params []any + ABI string +} + +// TODO: enforce required key presence + +func parseConfig(rawConfig *values.Map) (EvmConfig, error) { + var config EvmConfig + configAny, err := rawConfig.Unwrap() + if err != nil { + return config, err + } + err = mapstructure.Decode(configAny, &config) + return config, err +} + +func evaluateParams(params []any, inputs map[string]any) ([]any, error) { + vars := pipeline.NewVarsFrom(inputs) + var args []any + for _, param := range params { + switch v := param.(type) { + case string: + val, err := pipeline.VarExpr(v, vars)() + if err == nil { + args = append(args, val) + } else if errors.Is(errors.Cause(err), pipeline.ErrParameterEmpty) { + args = append(args, param) + } else { + return args, err + } + default: + args = append(args, param) + } + } + + return args, nil +} + +func encodePayload(args []any, rawSelector string) ([]byte, error) { + // TODO: do spec parsing as part of parseConfig() + + // Based on https://github.com/ethereum/go-ethereum/blob/f1c27c286ea2d0e110a507e5749e92d0a6144f08/signer/fourbyte/abi.go#L77-L102 + + // NOTE: without having full ABI it's actually impossible to support function overloading + selector, err := abiutil.ParseSignature(rawSelector) + if err != nil { + return nil, err + } + + abidata, err := json.Marshal([]abi.SelectorMarshaling{selector}) + if err != nil { + return nil, err + } + + spec, err := abi.JSON(strings.NewReader(string(abidata))) + if err != nil { + return nil, err + } + + return spec.Pack(selector.Name, args...) + + // NOTE: could avoid JSON encoding/decoding the selector + // var args abi.Arguments + // for _, arg := range selector.Inputs { + // ty, err := abi.NewType(arg.Type, arg.InternalType, arg.Components) + // if err != nil { + // return nil, err + // } + // args = append(args, abi.Argument{Name: arg.Name, Type: ty}) + // } + // // we only care about the name + inputs so we can compute the method ID + // method := abi.NewMethod(selector.Name, selector.Name, abi.Function, "nonpayable", false, false, args, nil) + // + // https://github.com/ethereum/go-ethereum/blob/f1c27c286ea2d0e110a507e5749e92d0a6144f08/accounts/abi/abi.go#L77-L82 + // arguments, err := method.Inputs.Pack(args...) + // if err != nil { + // return nil, err + // } + // // Pack up the method ID too if not a constructor and return + // return append(method.ID, arguments...), nil +} + +func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.CapabilityResponse, request capabilities.CapabilityRequest) error { + // TODO: idempotency + + // TODO: extract into ChainWriter? + txm := cap.chain.TxManager() + + config := cap.chain.Config().EVM().ChainWriter() + + reqConfig, err := parseConfig(request.Config) + if err != nil { + return err + } + + inputsAny, err := request.Inputs.Unwrap() + if err != nil { + return err + } + inputs := inputsAny.(map[string]any) + + // evaluate any variables in reqConfig.Params + args, err := evaluateParams(reqConfig.Params, inputs) + if err != nil { + return err + } + + data, err := encodePayload(args, reqConfig.ABI) + if err != nil { + return err + } + + // TODO: validate encoded report is prefixed with workflowID and executionID that match the request meta + + // unlimited gas in the MVP demo + gasLimit := 0 + // No signature validation in the MVP demo + signatures := [][]byte{} + + // construct forwarding payload + calldata, err := forwardABI.Pack("report", common.HexToAddress(reqConfig.Address), data, signatures) + if err != nil { + return err + } + + txMeta := &txmgr.TxMeta{ + // FwdrDestAddress could also be set for better logging but it's used for various purposes around Operator Forwarders + WorkflowExecutionID: &request.Metadata.WorkflowExecutionID, + } + strategy := txmgrcommon.NewSendEveryStrategy() + + checker := txmgr.TransmitCheckerSpec{ + CheckerType: txmgr.TransmitCheckerTypeSimulate, + } + req := txmgr.TxRequest{ + FromAddress: config.FromAddress().Address(), + ToAddress: config.ForwarderAddress().Address(), + EncodedPayload: calldata, + FeeLimit: uint32(gasLimit), + Meta: txMeta, + Strategy: strategy, + Checker: checker, + // SignalCallback: true, TODO: add code that checks if a workflow id is present, if so, route callback to chainwriter rather than pipeline + } + tx, err := txm.CreateTransaction(ctx, req) + if err != nil { + return err + } + fmt.Printf("Transaction submitted %v", tx.ID) + go func() { + // TODO: cast tx.Error to Err (or Value to Value?) + callback <- capabilities.CapabilityResponse{ + Value: nil, + Err: nil, + } + close(callback) + }() + return nil +} + +func (cap *EvmWrite) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { + return nil +} + +func (cap *EvmWrite) UnregisterFromWorkflow(ctx context.Context, request capabilities.UnregisterFromWorkflowRequest) error { + return nil +} diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go new file mode 100644 index 00000000000..68ca890cc0c --- /dev/null +++ b/core/capabilities/targets/write_target_test.go @@ -0,0 +1,92 @@ +package targets_test + +import ( + "math/big" + "testing" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/forwarder" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +var forwardABI = evmtypes.MustGetABI(forwarder.KeystoneForwarderMetaData.ABI) + +func TestEvmWrite(t *testing.T) { + chain := evmmocks.NewChain(t) + + txManager := txmmocks.NewMockEvmTxManager(t) + chain.On("ID").Return(big.NewInt(11155111)) + chain.On("TxManager").Return(txManager) + + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + a := testutils.NewAddress() + addr, err := ethkey.NewEIP55Address(a.Hex()) + require.NoError(t, err) + c.EVM[0].ChainWriter.FromAddress = &addr + + forwarderA := testutils.NewAddress() + forwarderAddr, err := ethkey.NewEIP55Address(forwarderA.Hex()) + require.NoError(t, err) + c.EVM[0].ChainWriter.ForwarderAddress = &forwarderAddr + }) + evmcfg := evmtest.NewChainScopedConfig(t, cfg) + chain.On("Config").Return(evmcfg) + + capability := targets.NewEvmWrite(chain) + ctx := testutils.Context(t) + + config, err := values.NewMap(map[string]any{ + "abi": "receive(report bytes)", + "params": []any{"$(report)"}, + }) + require.NoError(t, err) + + inputs, err := values.NewMap(map[string]any{ + "report": []byte{1, 2, 3}, + }) + require.NoError(t, err) + + req := capabilities.CapabilityRequest{ + Metadata: capabilities.RequestMetadata{ + WorkflowID: "hello", + }, + Config: config, + Inputs: inputs, + } + + txManager.On("CreateTransaction", mock.Anything, mock.Anything).Return(txmgr.Tx{}, nil).Run(func(args mock.Arguments) { + req := args.Get(1).(txmgr.TxRequest) + payload := make(map[string]any) + method := forwardABI.Methods["report"] + err = method.Inputs.UnpackIntoMap(payload, req.EncodedPayload[4:]) + require.NoError(t, err) + require.Equal(t, []byte{ + 0xa6, 0x9b, 0x6e, 0xd0, // selector = keccak(signature)[:4] + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, // type = bytes + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, // len = 3 + 0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // elements [1, 2, 3] zero padded + }, payload["data"]) + + }) + + ch := make(chan capabilities.CapabilityResponse) + + err = capability.Execute(ctx, ch, req) + require.NoError(t, err) + + response := <-ch + require.Nil(t, response.Err) +} diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go index fb6df26b1ad..c579da86c8c 100644 --- a/core/chains/evm/config/chain_scoped.go +++ b/core/chains/evm/config/chain_scoped.go @@ -94,6 +94,10 @@ func (e *evmConfig) OCR2() OCR2 { return &ocr2Config{c: e.c.OCR2} } +func (e *evmConfig) ChainWriter() ChainWriter { + return &chainWriterConfig{c: e.c.ChainWriter} +} + func (e *evmConfig) GasEstimator() GasEstimator { return &gasEstimatorConfig{c: e.c.GasEstimator, blockDelay: e.c.RPCBlockQueryDelay, transactionsMaxInFlight: e.c.Transactions.MaxInFlight, k: e.c.KeySpecific} } diff --git a/core/chains/evm/config/chain_scoped_chain_writer.go b/core/chains/evm/config/chain_scoped_chain_writer.go new file mode 100644 index 00000000000..b84731314e1 --- /dev/null +++ b/core/chains/evm/config/chain_scoped_chain_writer.go @@ -0,0 +1,18 @@ +package config + +import ( + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" +) + +type chainWriterConfig struct { + c toml.ChainWriter +} + +func (b *chainWriterConfig) FromAddress() *ethkey.EIP55Address { + return b.c.FromAddress +} + +func (b *chainWriterConfig) ForwarderAddress() *ethkey.EIP55Address { + return b.c.ForwarderAddress +} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 33e2c85eee5..5b397ddd574 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -10,6 +10,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink/v2/common/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/config" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" ) type EVM interface { @@ -19,6 +20,7 @@ type EVM interface { GasEstimator() GasEstimator OCR() OCR OCR2() OCR2 + ChainWriter() ChainWriter NodePool() NodePool AutoCreateKey() bool @@ -124,6 +126,11 @@ type BlockHistory interface { TransactionPercentile() uint16 } +type ChainWriter interface { + FromAddress() *ethkey.EIP55Address + ForwarderAddress() *ethkey.EIP55Address +} + type NodePool interface { PollFailureThreshold() uint32 PollInterval() time.Duration diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 2348e648696..6ebf3ed0a94 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -368,6 +368,7 @@ type Chain struct { NodePool NodePool `toml:",omitempty"` OCR OCR `toml:",omitempty"` OCR2 OCR2 `toml:",omitempty"` + ChainWriter ChainWriter `toml:",omitempty"` } func (c *Chain) ValidateConfig() (err error) { @@ -447,6 +448,20 @@ func (a *Automation) setFrom(f *Automation) { } } +type ChainWriter struct { + FromAddress *ethkey.EIP55Address `toml:",omitempty"` + ForwarderAddress *ethkey.EIP55Address `toml:",omitempty"` +} + +func (m *ChainWriter) setFrom(f *ChainWriter) { + if v := f.FromAddress; v != nil { + m.FromAddress = v + } + if v := f.ForwarderAddress; v != nil { + m.ForwarderAddress = v + } +} + type BalanceMonitor struct { Enabled *bool } diff --git a/core/chains/evm/config/toml/defaults.go b/core/chains/evm/config/toml/defaults.go index 5e9a10de003..adb91b3a1bc 100644 --- a/core/chains/evm/config/toml/defaults.go +++ b/core/chains/evm/config/toml/defaults.go @@ -177,4 +177,5 @@ func (c *Chain) SetFrom(f *Chain) { c.NodePool.setFrom(&f.NodePool) c.OCR.setFrom(&f.OCR) c.OCR2.setFrom(&f.OCR2) + c.ChainWriter.setFrom(&f.ChainWriter) } diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 975264be6d4..6f2322fd6db 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -363,3 +363,9 @@ Order = 100 # Default [EVM.OCR2.Automation] # GasLimit controls the gas limit for transmit transactions from ocr2automation job. GasLimit = 5400000 # Default + +[EVM.ChainWriter] +# FromAddress is Address of the transmitter key to use for workflow writes. +FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example +# ForwarderAddress is the keystone forwarder contract address on chain. +ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example diff --git a/core/config/docs/docs_test.go b/core/config/docs/docs_test.go index dc1e0f2af12..8b4e38b980d 100644 --- a/core/config/docs/docs_test.go +++ b/core/config/docs/docs_test.go @@ -80,6 +80,10 @@ func TestDoc(t *testing.T) { docDefaults.FlagsContractAddress = nil docDefaults.LinkContractAddress = nil docDefaults.OperatorFactoryAddress = nil + require.Empty(t, docDefaults.ChainWriter.FromAddress) + require.Empty(t, docDefaults.ChainWriter.ForwarderAddress) + docDefaults.ChainWriter.FromAddress = nil + docDefaults.ChainWriter.ForwarderAddress = nil assertTOML(t, fallbackDefaults, docDefaults) }) diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index be07a548a4e..00da87af56b 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -154,6 +154,9 @@ package gethwrappers // Chainlink Functions //go:generate go generate ./functions +// Chainlink Keystone +//go:generate go generate ./keystone + // Mercury //go:generate go generate ./llo-feeds diff --git a/core/gethwrappers/keystone/generated/forwarder/forwarder.go b/core/gethwrappers/keystone/generated/forwarder/forwarder.go new file mode 100644 index 00000000000..c66e2886793 --- /dev/null +++ b/core/gethwrappers/keystone/generated/forwarder/forwarder.go @@ -0,0 +1,600 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package forwarder + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var KeystoneForwarderMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"targetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"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\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610c12806101576000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063c0965dc311610050578063c0965dc314610108578063e6b714581461012b578063f2fde38b1461016157600080fd5b8063181f5a771461007757806379ba5097146100bf5780638da5cb5b146100c9575b600080fd5b604080518082018252601781527f4b657973746f6e65466f7277617264657220312e302e30000000000000000000602082015290516100b69190610827565b60405180910390f35b6100c7610174565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b6565b61011b6101163660046108bc565b610276565b60405190151581526020016100b6565b6100e3610139366004610998565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6100c761016f3660046109b1565b61058e565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60025460009060ff16156102b6576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556044841161034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c69642064617461206c656e6774680000000000000000000000000060448201526064016101f1565b600061035a85600481896109d3565b8101906103679190610a2c565b8051602082012090915060005b848110156104655760008060006103e289898681811061039657610396610afb565b90506020028101906103a89190610b2a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a292505050565b925092509250600060018683868660405160008152602001604052604051610426949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610448573d6000803e3d6000fd5b5086955061045d9450859350610b9692505050565b915050610374565b5060008061047284610630565b600081815260036020526040902054919350915073ffffffffffffffffffffffffffffffffffffffff16156104ae57600094505050505061055d565b6000808b73ffffffffffffffffffffffffffffffffffffffff168b8b6040516104d8929190610bf5565b6000604051808303816000865af19150503d8060008114610515576040519150601f19603f3d011682016040523d82523d6000602084013e61051a565b606091505b5050506000928352505060036020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055506001925050505b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905595945050505050565b6105966106af565b61059f81610732565b50565b60008060008351604114610612576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f696e76616c6964207369676e6174757265206c656e677468000000000000000060448201526064016101f1565b50505060208101516040820151606090920151909260009190911a90565b600080604083511161069e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f696e76616c6964207265706f7274206c656e677468000000000000000000000060448201526064016101f1565b505060208101516040909101519091565b60005473ffffffffffffffffffffffffffffffffffffffff163314610730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101f1565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036107b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208083528351808285015260005b8181101561085457858101830151858201604001528201610838565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108b757600080fd5b919050565b6000806000806000606086880312156108d457600080fd5b6108dd86610893565b9450602086013567ffffffffffffffff808211156108fa57600080fd5b818801915088601f83011261090e57600080fd5b81358181111561091d57600080fd5b89602082850101111561092f57600080fd5b60208301965080955050604088013591508082111561094d57600080fd5b818801915088601f83011261096157600080fd5b81358181111561097057600080fd5b8960208260051b850101111561098557600080fd5b9699959850939650602001949392505050565b6000602082840312156109aa57600080fd5b5035919050565b6000602082840312156109c357600080fd5b6109cc82610893565b9392505050565b600080858511156109e357600080fd5b838611156109f057600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610a3e57600080fd5b813567ffffffffffffffff80821115610a5657600080fd5b818401915084601f830112610a6a57600080fd5b813581811115610a7c57610a7c6109fd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610ac257610ac26109fd565b81604052828152876020848701011115610adb57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610b5f57600080fd5b83018035915067ffffffffffffffff821115610b7a57600080fd5b602001915036819003821315610b8f57600080fd5b9250929050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610bee577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b818382376000910190815291905056fea164736f6c6343000813000a", +} + +var KeystoneForwarderABI = KeystoneForwarderMetaData.ABI + +var KeystoneForwarderBin = KeystoneForwarderMetaData.Bin + +func DeployKeystoneForwarder(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *KeystoneForwarder, error) { + parsed, err := KeystoneForwarderMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(KeystoneForwarderBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &KeystoneForwarder{address: address, abi: *parsed, KeystoneForwarderCaller: KeystoneForwarderCaller{contract: contract}, KeystoneForwarderTransactor: KeystoneForwarderTransactor{contract: contract}, KeystoneForwarderFilterer: KeystoneForwarderFilterer{contract: contract}}, nil +} + +type KeystoneForwarder struct { + address common.Address + abi abi.ABI + KeystoneForwarderCaller + KeystoneForwarderTransactor + KeystoneForwarderFilterer +} + +type KeystoneForwarderCaller struct { + contract *bind.BoundContract +} + +type KeystoneForwarderTransactor struct { + contract *bind.BoundContract +} + +type KeystoneForwarderFilterer struct { + contract *bind.BoundContract +} + +type KeystoneForwarderSession struct { + Contract *KeystoneForwarder + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type KeystoneForwarderCallerSession struct { + Contract *KeystoneForwarderCaller + CallOpts bind.CallOpts +} + +type KeystoneForwarderTransactorSession struct { + Contract *KeystoneForwarderTransactor + TransactOpts bind.TransactOpts +} + +type KeystoneForwarderRaw struct { + Contract *KeystoneForwarder +} + +type KeystoneForwarderCallerRaw struct { + Contract *KeystoneForwarderCaller +} + +type KeystoneForwarderTransactorRaw struct { + Contract *KeystoneForwarderTransactor +} + +func NewKeystoneForwarder(address common.Address, backend bind.ContractBackend) (*KeystoneForwarder, error) { + abi, err := abi.JSON(strings.NewReader(KeystoneForwarderABI)) + if err != nil { + return nil, err + } + contract, err := bindKeystoneForwarder(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &KeystoneForwarder{address: address, abi: abi, KeystoneForwarderCaller: KeystoneForwarderCaller{contract: contract}, KeystoneForwarderTransactor: KeystoneForwarderTransactor{contract: contract}, KeystoneForwarderFilterer: KeystoneForwarderFilterer{contract: contract}}, nil +} + +func NewKeystoneForwarderCaller(address common.Address, caller bind.ContractCaller) (*KeystoneForwarderCaller, error) { + contract, err := bindKeystoneForwarder(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &KeystoneForwarderCaller{contract: contract}, nil +} + +func NewKeystoneForwarderTransactor(address common.Address, transactor bind.ContractTransactor) (*KeystoneForwarderTransactor, error) { + contract, err := bindKeystoneForwarder(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &KeystoneForwarderTransactor{contract: contract}, nil +} + +func NewKeystoneForwarderFilterer(address common.Address, filterer bind.ContractFilterer) (*KeystoneForwarderFilterer, error) { + contract, err := bindKeystoneForwarder(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &KeystoneForwarderFilterer{contract: contract}, nil +} + +func bindKeystoneForwarder(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := KeystoneForwarderMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_KeystoneForwarder *KeystoneForwarderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeystoneForwarder.Contract.KeystoneForwarderCaller.contract.Call(opts, result, method, params...) +} + +func (_KeystoneForwarder *KeystoneForwarderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.KeystoneForwarderTransactor.contract.Transfer(opts) +} + +func (_KeystoneForwarder *KeystoneForwarderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.KeystoneForwarderTransactor.contract.Transact(opts, method, params...) +} + +func (_KeystoneForwarder *KeystoneForwarderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeystoneForwarder.Contract.contract.Call(opts, result, method, params...) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.contract.Transfer(opts) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.contract.Transact(opts, method, params...) +} + +func (_KeystoneForwarder *KeystoneForwarderCaller) GetTransmitter(opts *bind.CallOpts, workflowExecutionId [32]byte) (common.Address, error) { + var out []interface{} + err := _KeystoneForwarder.contract.Call(opts, &out, "getTransmitter", workflowExecutionId) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_KeystoneForwarder *KeystoneForwarderSession) GetTransmitter(workflowExecutionId [32]byte) (common.Address, error) { + return _KeystoneForwarder.Contract.GetTransmitter(&_KeystoneForwarder.CallOpts, workflowExecutionId) +} + +func (_KeystoneForwarder *KeystoneForwarderCallerSession) GetTransmitter(workflowExecutionId [32]byte) (common.Address, error) { + return _KeystoneForwarder.Contract.GetTransmitter(&_KeystoneForwarder.CallOpts, workflowExecutionId) +} + +func (_KeystoneForwarder *KeystoneForwarderCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _KeystoneForwarder.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_KeystoneForwarder *KeystoneForwarderSession) Owner() (common.Address, error) { + return _KeystoneForwarder.Contract.Owner(&_KeystoneForwarder.CallOpts) +} + +func (_KeystoneForwarder *KeystoneForwarderCallerSession) Owner() (common.Address, error) { + return _KeystoneForwarder.Contract.Owner(&_KeystoneForwarder.CallOpts) +} + +func (_KeystoneForwarder *KeystoneForwarderCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _KeystoneForwarder.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_KeystoneForwarder *KeystoneForwarderSession) TypeAndVersion() (string, error) { + return _KeystoneForwarder.Contract.TypeAndVersion(&_KeystoneForwarder.CallOpts) +} + +func (_KeystoneForwarder *KeystoneForwarderCallerSession) TypeAndVersion() (string, error) { + return _KeystoneForwarder.Contract.TypeAndVersion(&_KeystoneForwarder.CallOpts) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeystoneForwarder.contract.Transact(opts, "acceptOwnership") +} + +func (_KeystoneForwarder *KeystoneForwarderSession) AcceptOwnership() (*types.Transaction, error) { + return _KeystoneForwarder.Contract.AcceptOwnership(&_KeystoneForwarder.TransactOpts) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _KeystoneForwarder.Contract.AcceptOwnership(&_KeystoneForwarder.TransactOpts) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactor) Report(opts *bind.TransactOpts, targetAddress common.Address, data []byte, signatures [][]byte) (*types.Transaction, error) { + return _KeystoneForwarder.contract.Transact(opts, "report", targetAddress, data, signatures) +} + +func (_KeystoneForwarder *KeystoneForwarderSession) Report(targetAddress common.Address, data []byte, signatures [][]byte) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.Report(&_KeystoneForwarder.TransactOpts, targetAddress, data, signatures) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactorSession) Report(targetAddress common.Address, data []byte, signatures [][]byte) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.Report(&_KeystoneForwarder.TransactOpts, targetAddress, data, signatures) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _KeystoneForwarder.contract.Transact(opts, "transferOwnership", to) +} + +func (_KeystoneForwarder *KeystoneForwarderSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.TransferOwnership(&_KeystoneForwarder.TransactOpts, to) +} + +func (_KeystoneForwarder *KeystoneForwarderTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _KeystoneForwarder.Contract.TransferOwnership(&_KeystoneForwarder.TransactOpts, to) +} + +type KeystoneForwarderOwnershipTransferRequestedIterator struct { + Event *KeystoneForwarderOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeystoneForwarderOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeystoneForwarderOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(KeystoneForwarderOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *KeystoneForwarderOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *KeystoneForwarderOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeystoneForwarderOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeystoneForwarder *KeystoneForwarderFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneForwarderOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _KeystoneForwarder.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeystoneForwarderOwnershipTransferRequestedIterator{contract: _KeystoneForwarder.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_KeystoneForwarder *KeystoneForwarderFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeystoneForwarderOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _KeystoneForwarder.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeystoneForwarderOwnershipTransferRequested) + if err := _KeystoneForwarder.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_KeystoneForwarder *KeystoneForwarderFilterer) ParseOwnershipTransferRequested(log types.Log) (*KeystoneForwarderOwnershipTransferRequested, error) { + event := new(KeystoneForwarderOwnershipTransferRequested) + if err := _KeystoneForwarder.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeystoneForwarderOwnershipTransferredIterator struct { + Event *KeystoneForwarderOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeystoneForwarderOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeystoneForwarderOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(KeystoneForwarderOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *KeystoneForwarderOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *KeystoneForwarderOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeystoneForwarderOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeystoneForwarder *KeystoneForwarderFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneForwarderOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _KeystoneForwarder.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeystoneForwarderOwnershipTransferredIterator{contract: _KeystoneForwarder.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_KeystoneForwarder *KeystoneForwarderFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeystoneForwarderOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _KeystoneForwarder.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeystoneForwarderOwnershipTransferred) + if err := _KeystoneForwarder.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_KeystoneForwarder *KeystoneForwarderFilterer) ParseOwnershipTransferred(log types.Log) (*KeystoneForwarderOwnershipTransferred, error) { + event := new(KeystoneForwarderOwnershipTransferred) + if err := _KeystoneForwarder.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_KeystoneForwarder *KeystoneForwarder) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _KeystoneForwarder.abi.Events["OwnershipTransferRequested"].ID: + return _KeystoneForwarder.ParseOwnershipTransferRequested(log) + case _KeystoneForwarder.abi.Events["OwnershipTransferred"].ID: + return _KeystoneForwarder.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (KeystoneForwarderOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (KeystoneForwarderOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_KeystoneForwarder *KeystoneForwarder) Address() common.Address { + return _KeystoneForwarder.address +} + +type KeystoneForwarderInterface interface { + GetTransmitter(opts *bind.CallOpts, workflowExecutionId [32]byte) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Report(opts *bind.TransactOpts, targetAddress common.Address, data []byte, signatures [][]byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneForwarderOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeystoneForwarderOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*KeystoneForwarderOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeystoneForwarderOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeystoneForwarderOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*KeystoneForwarderOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt new file mode 100644 index 00000000000..8dad729b196 --- /dev/null +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -0,0 +1,2 @@ +GETH_VERSION: 1.13.8 +forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin 4886b538e1fdc8aaf860901de36269e0c35acfd3e6eb190654d693ff9dbd4b6d diff --git a/core/gethwrappers/keystone/go_generate.go b/core/gethwrappers/keystone/go_generate.go new file mode 100644 index 00000000000..75800132f8e --- /dev/null +++ b/core/gethwrappers/keystone/go_generate.go @@ -0,0 +1,7 @@ +// Package gethwrappers provides tools for wrapping solidity contracts with +// golang packages, using abigen. +package gethwrappers + +// Keystone + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin KeystoneForwarder forwarder diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 2c877299deb..4dc3995ece4 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -247,6 +247,7 @@ require ( github.com/shirou/gopsutil/v3 v3.23.11 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect + github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 7a4faf31ce3..3b0efd9053e 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1167,6 +1167,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= +github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index d16bfc747c6..e9a128f861e 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -357,6 +357,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { job.Workflow: workflows.NewDelegate( globalLogger, registry, + legacyEVMChains, ), } webhookJobRunner = delegates[job.Webhook].(*webhook.Delegate).WebhookJobRunner() diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index b16551912b2..5b2f3be3788 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1124,6 +1124,14 @@ func TestConfig_full(t *testing.T) { require.NoError(t, config.DecodeTOML(strings.NewReader(fullTOML), &got)) // Except for some EVM node fields. for c := range got.EVM { + addr, err := ethkey.NewEIP55Address("0x2a3e23c6f242F5345320814aC8a1b4E58707D292") + require.NoError(t, err) + if got.EVM[c].ChainWriter.FromAddress == nil { + got.EVM[c].ChainWriter.FromAddress = &addr + } + if got.EVM[c].ChainWriter.ForwarderAddress == nil { + got.EVM[c].ChainWriter.ForwarderAddress = &addr + } for n := range got.EVM[c].Nodes { if got.EVM[c].Nodes[n].WSURL == nil { got.EVM[c].Nodes[n].WSURL = new(commonconfig.URL) diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index 1e48e229da5..32307b9fb9e 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -2,6 +2,8 @@ package workflows import ( "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pg" @@ -35,6 +37,9 @@ func (d *Delegate) ServicesForSpec(spec job.Job) ([]job.ServiceCtx, error) { return []job.ServiceCtx{engine}, nil } -func NewDelegate(logger logger.Logger, registry types.CapabilitiesRegistry) *Delegate { +func NewDelegate(logger logger.Logger, registry types.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer) *Delegate { + // NOTE: we temporarily do registration inside NewDelegate, this will be moved out of job specs in the future + _ = targets.InitializeWrite(registry, legacyEVMChains) + return &Delegate{logger: logger, registry: registry} } diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 3bf68bbe6d0..2c4f3109421 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -6407,6 +6407,26 @@ GasLimit = 5400000 # Default ``` GasLimit controls the gas limit for transmit transactions from ocr2automation job. +## EVM.ChainWriter +```toml +[EVM.ChainWriter] +FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example +ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example +``` + + +### FromAddress +```toml +FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example +``` +FromAddress is Address of the transmitter key to use for workflow writes. + +### ForwarderAddress +```toml +ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example +``` +ForwarderAddress is the keystone forwarder contract address on chain. + ## Cosmos ```toml [[Cosmos]] diff --git a/flake.lock b/flake.lock index 9051b0252f6..bce30e58f58 100644 --- a/flake.lock +++ b/flake.lock @@ -1,12 +1,15 @@ { "nodes": { "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", "owner": "numtide", "repo": "flake-utils", - "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", "type": "github" }, "original": { @@ -17,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1666109165, - "narHash": "sha256-BMLyNVkr0oONuq3lKlFCRVuYqF75CO68Z8EoCh81Zdk=", + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", "owner": "nixos", "repo": "nixpkgs", - "rev": "32096899af23d49010bd8cf6a91695888d9d9e73", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", "type": "github" }, "original": { @@ -36,6 +39,21 @@ "flake-utils": "flake-utils", "nixpkgs": "nixpkgs" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/go.md b/go.md index 97330440a54..497f87d77b5 100644 --- a/go.md +++ b/go.md @@ -22,6 +22,8 @@ flowchart LR chainlink/v2 --> caigo click caigo href "https://github.com/smartcontractkit/caigo" + chainlink/v2 --> chain-selectors + click chain-selectors href "https://github.com/smartcontractkit/chain-selectors" chainlink/v2 --> chainlink-automation click chainlink-automation href "https://github.com/smartcontractkit/chainlink-automation" chainlink/v2 --> chainlink-common @@ -52,7 +54,6 @@ flowchart LR chainlink-cosmos --> chainlink-common chainlink-cosmos --> libocr chainlink-data-streams --> chain-selectors - click chain-selectors href "https://github.com/smartcontractkit/chain-selectors" chainlink-data-streams --> chainlink-common chainlink-data-streams --> libocr chainlink-feeds --> chainlink-common diff --git a/go.mod b/go.mod index 396201fdede..94c9c33f27d 100644 --- a/go.mod +++ b/go.mod @@ -66,6 +66,7 @@ require ( github.com/shirou/gopsutil/v3 v3.23.11 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 + github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 diff --git a/go.sum b/go.sum index e02add4ee89..4073b235b7e 100644 --- a/go.sum +++ b/go.sum @@ -1162,6 +1162,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= +github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ccb0810ab50..a1792a04617 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -369,6 +369,7 @@ require ( github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect + github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index ed933fab701..e0f1e90c4a5 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1501,6 +1501,8 @@ github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= +github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= diff --git a/shell.nix b/shell.nix index 7881af59ba2..7d219553368 100644 --- a/shell.nix +++ b/shell.nix @@ -1,9 +1,9 @@ { pkgs ? import { } }: with pkgs; let - go = go_1_19; + go = go_1_21; postgresql = postgresql_14; - nodejs = nodejs-16_x; + nodejs = nodejs-18_x; nodePackages = pkgs.nodePackages.override { inherit nodejs; }; in mkShell { @@ -11,15 +11,14 @@ mkShell { go postgresql + python3 python3Packages.pip + curl nodejs nodePackages.pnpm # TODO: compiler / gcc for secp compilation - nodePackages.ganache - # py3: web3 slither-analyzer crytic-compile - # echidna go-ethereum # geth # parity # openethereum go-mockery @@ -49,8 +48,4 @@ mkShell { PGDATA = "db"; CL_DATABASE_URL = "postgresql://chainlink:chainlink@localhost:5432/chainlink_test?sslmode=disable"; - shellHook = '' - export GOPATH=$HOME/go - export PATH=$GOPATH/bin:$PATH - ''; } From da02459ddad80f0637172d3e434ba9e3a3d95244 Mon Sep 17 00:00:00 2001 From: jinhoonbang Date: Fri, 16 Feb 2024 13:00:48 -0800 Subject: [PATCH 49/98] add support for backwards mode in avalanche subnets (#12039) --- core/scripts/common/avalanche_subnet.go | 126 ++++++++++++++++++++++++ core/scripts/common/helpers.go | 29 +++++- 2 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 core/scripts/common/avalanche_subnet.go diff --git a/core/scripts/common/avalanche_subnet.go b/core/scripts/common/avalanche_subnet.go new file mode 100644 index 00000000000..238f193d2b8 --- /dev/null +++ b/core/scripts/common/avalanche_subnet.go @@ -0,0 +1,126 @@ +package common + +import ( + "encoding/json" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// AvaSubnetHeader is a copy of [github.com/ava-labs/subnet-evm/core/types.Header] to avoid importing the whole module. +type AvaSubnetHeader struct { + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom AvaBloom `json:"logsBloom" gencodec:"required"` + Difficulty *big.Int `json:"difficulty" gencodec:"required"` + Number *big.Int `json:"number" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Time uint64 `json:"timestamp" gencodec:"required"` + Extra []byte `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce AvaBlockNonce `json:"nonce"` + BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"` + BlockGasCost *big.Int `json:"blockGasCost" rlp:"optional"` +} + +func (h *AvaSubnetHeader) UnmarshalJSON(input []byte) error { + type Header struct { + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase *common.Address `json:"miner" gencodec:"required"` + Root *common.Hash `json:"stateRoot" gencodec:"required"` + TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom *AvaBloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest *common.Hash `json:"mixHash"` + Nonce *AvaBlockNonce `json:"nonce"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + BlockGasCost *hexutil.Big `json:"blockGasCost" rlp:"optional"` + } + var dec Header + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ParentHash == nil { + return errors.New("missing required field 'parentHash' for Header") + } + h.ParentHash = *dec.ParentHash + if dec.UncleHash == nil { + return errors.New("missing required field 'sha3Uncles' for Header") + } + h.UncleHash = *dec.UncleHash + if dec.Coinbase == nil { + return errors.New("missing required field 'miner' for Header") + } + h.Coinbase = *dec.Coinbase + if dec.Root == nil { + return errors.New("missing required field 'stateRoot' for Header") + } + h.Root = *dec.Root + if dec.TxHash == nil { + return errors.New("missing required field 'transactionsRoot' for Header") + } + h.TxHash = *dec.TxHash + if dec.ReceiptHash == nil { + return errors.New("missing required field 'receiptsRoot' for Header") + } + h.ReceiptHash = *dec.ReceiptHash + if dec.Bloom == nil { + return errors.New("missing required field 'logsBloom' for Header") + } + h.Bloom = *dec.Bloom + if dec.Difficulty == nil { + return errors.New("missing required field 'difficulty' for Header") + } + h.Difficulty = (*big.Int)(dec.Difficulty) + if dec.Number == nil { + return errors.New("missing required field 'number' for Header") + } + h.Number = (*big.Int)(dec.Number) + if dec.GasLimit == nil { + return errors.New("missing required field 'gasLimit' for Header") + } + h.GasLimit = uint64(*dec.GasLimit) + if dec.GasUsed == nil { + return errors.New("missing required field 'gasUsed' for Header") + } + h.GasUsed = uint64(*dec.GasUsed) + if dec.Time == nil { + return errors.New("missing required field 'timestamp' for Header") + } + h.Time = uint64(*dec.Time) + if dec.Extra == nil { + return errors.New("missing required field 'extraData' for Header") + } + h.Extra = *dec.Extra + if dec.MixDigest != nil { + h.MixDigest = *dec.MixDigest + } + if dec.Nonce != nil { + h.Nonce = *dec.Nonce + } + if dec.BaseFee != nil { + h.BaseFee = (*big.Int)(dec.BaseFee) + } + if dec.BlockGasCost != nil { + h.BlockGasCost = (*big.Int)(dec.BlockGasCost) + } + return nil +} + +func (h *AvaSubnetHeader) Hash() common.Hash { + return rlpHash(h) +} diff --git a/core/scripts/common/helpers.go b/core/scripts/common/helpers.go index 0ed9929956a..0967991e62b 100644 --- a/core/scripts/common/helpers.go +++ b/core/scripts/common/helpers.go @@ -498,7 +498,20 @@ func GetRlpHeaders(env Environment, blockNumbers []*big.Int, getParentBlocks boo //fmt.Println("Calculated BH:", bh.String(), // "fetched BH:", h.Hash(), // "block number:", new(big.Int).Set(blockNum).Add(blockNum, offset).String()) + } else if IsAvaxSubnet(env.ChainID) { + var h AvaSubnetHeader + // Get child block since it's the one that has the parent hash in its header. + nextBlockNum := new(big.Int).Set(blockNum).Add(blockNum, offset) + err2 := env.Jc.CallContext(context.Background(), &h, "eth_getBlockByNumber", hexutil.EncodeBig(nextBlockNum), false) + if err2 != nil { + return nil, hashes, fmt.Errorf("failed to get header: %+v", err2) + } + rlpHeader, err2 = rlp.EncodeToBytes(h) + if err2 != nil { + return nil, hashes, fmt.Errorf("failed to encode rlp: %+v", err2) + } + hashes = append(hashes, h.Hash().String()) } else if IsPolygonEdgeNetwork(env.ChainID) { // Get child block since it's the one that has the parent hash in its header. @@ -570,12 +583,20 @@ func CalculateLatestBlockHeader(env Environment, blockNumberInput int) (err erro return err } -// IsAvaxNetwork returns true if the given chain ID corresponds to an avalanche network or subnet. +// IsAvaxNetwork returns true if the given chain ID corresponds to an avalanche network. func IsAvaxNetwork(chainID int64) bool { return chainID == 43114 || // C-chain mainnet - chainID == 43113 || // Fuji testnet - chainID == 335 || // DFK testnet - chainID == 53935 // DFK mainnet + chainID == 43113 // Fuji testnet +} + +// IsAvaxSubnet returns true if the given chain ID corresponds to an avalanche subnet. +func IsAvaxSubnet(chainID int64) bool { + return chainID == 335 || // DFK testnet + chainID == 53935 || // DFK mainnet + chainID == 955081 || // Nexon Dev + chainID == 595581 || // Nexon Test + chainID == 807424 || // Nexon QA + chainID == 847799 // Nexon Stage } func UpkeepLink(chainID int64, upkeepID *big.Int) string { From ff6f53bda0d62977430afbffd464ad60b3031c15 Mon Sep 17 00:00:00 2001 From: Awbrey Hughlett Date: Mon, 19 Feb 2024 10:42:28 -0500 Subject: [PATCH 50/98] Fail to Boot if P2P Not Enabled for OCR (#12005) * Fail to Boot if P2P Not Enabled for OCR OCR and OCR2 both require P2P.V2 to be enabled with valid listen addresses. In the case that one or both are enabled, return an error if P2P is not enabled. * update to changelog --- core/config/toml/types.go | 4 + core/services/chainlink/application.go | 2 +- core/services/chainlink/config_test.go | 3 +- .../chainlink/testdata/config-invalid.toml | 7 + docs/CHANGELOG.md | 4 + .../node/validate/invalid-ocr-p2p.txtar | 276 ++++++++++++++++++ 6 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 testdata/scripts/node/validate/invalid-ocr-p2p.txtar diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 7b4656da1f6..08ebf68f59b 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -98,6 +98,10 @@ func (c *Core) ValidateConfig() (err error) { err = multierr.Append(err, configutils.ErrInvalid{Name: "RootDir", Value: true, Msg: fmt.Sprintf("Failed to expand RootDir. Please use an explicit path: %s", verr)}) } + if (*c.OCR.Enabled || *c.OCR2.Enabled) && !*c.P2P.V2.Enabled { + err = multierr.Append(err, configutils.ErrInvalid{Name: "P2P.V2.Enabled", Value: false, Msg: "P2P required for OCR or OCR2. Please enable P2P or disable OCR/OCR2."}) + } + return err } diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index e9a128f861e..de2fe789396 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -388,7 +388,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { peerWrapper = ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, globalLogger) srvcs = append(srvcs, peerWrapper) } else { - globalLogger.Debug("P2P stack disabled") + return nil, fmt.Errorf("P2P stack required for OCR or OCR2") } if cfg.OCR().Enabled() { diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 5b2f3be3788..552a91d6e2f 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1157,7 +1157,8 @@ func TestConfig_Validate(t *testing.T) { toml string exp string }{ - {name: "invalid", toml: invalidTOML, exp: `invalid configuration: 6 errors: + {name: "invalid", toml: invalidTOML, exp: `invalid configuration: 7 errors: + - P2P.V2.Enabled: invalid value (false): P2P required for OCR or OCR2. Please enable P2P or disable OCR/OCR2. - Database.Lock.LeaseRefreshInterval: invalid value (6s): must be less than or equal to half of LeaseDuration (10s) - WebServer: 8 errors: - LDAP.BaseDN: invalid value (): LDAP BaseDN can not be empty diff --git a/core/services/chainlink/testdata/config-invalid.toml b/core/services/chainlink/testdata/config-invalid.toml index 4d8c9bc29a9..d11cd48d6ef 100644 --- a/core/services/chainlink/testdata/config-invalid.toml +++ b/core/services/chainlink/testdata/config-invalid.toml @@ -138,3 +138,10 @@ Name = 'primary' URL = 'http://second.stark.node' [[Starknet]] + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +Enabled = false \ No newline at end of file diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index e7a303d7ab1..8fff0e36cad 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Gas bumping logic to the `SuggestedPriceEstimator`. The bumping mechanism for this estimator refetches the price from the RPC and adds a buffer on top using the greater of `BumpPercent` and `BumpMin`. +### Fixed + +- `P2P.V2` is required in configuration when either `OCR` or `OCR2` are enabled. The node will fail to boot if `P2P.V2` is not enabled. + ## 2.9.0 - UNRELEASED ### Added diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar new file mode 100644 index 00000000000..7f109b654d9 --- /dev/null +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -0,0 +1,276 @@ +! exec chainlink node -c config.toml -s secrets.toml validate +cmp stderr err.txt +cmp stdout out.txt + +-- config.toml -- +Log.Level = 'debug' + +[OCR2] +Enabled = true + +[P2P.V2] +Enabled = false + +-- secrets.toml -- +[Database] +URL = 'postgresql://user:pass1234567890abcd@localhost:5432/dbname?sslmode=disable' + +[Password] +Keystore = 'keystore_pass' + +-- out.txt -- +# Secrets: +[Database] +URL = 'xxxxx' +AllowSimplePasswords = false + +[Password] +Keystore = 'xxxxx' + +# Input Configuration: +[Log] +Level = 'debug' + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +Enabled = false + +# Effective Configuration, with defaults applied: +InsecureFastScrypt = false +RootDir = '~/.chainlink' +ShutdownGracePeriod = '5s' + +[Feature] +FeedsManager = true +LogPoller = false +UICSAKeys = false + +[Database] +DefaultIdleInTxSessionTimeout = '1h0m0s' +DefaultLockTimeout = '15s' +DefaultQueryTimeout = '10s' +LogQueries = false +MaxIdleConns = 10 +MaxOpenConns = 20 +MigrateOnStartup = true + +[Database.Backup] +Dir = '' +Frequency = '1h0m0s' +Mode = 'none' +OnVersionUpgrade = true + +[Database.Listener] +MaxReconnectDuration = '10m0s' +MinReconnectInterval = '1m0s' +FallbackPollInterval = '30s' + +[Database.Lock] +Enabled = true +LeaseDuration = '10s' +LeaseRefreshInterval = '1s' + +[TelemetryIngress] +UniConn = true +Logging = false +BufferSize = 100 +MaxBatchSize = 50 +SendInterval = '500ms' +SendTimeout = '10s' +UseBatchSend = true + +[AuditLogger] +Enabled = false +ForwardToUrl = '' +JsonWrapperKey = '' +Headers = [] + +[Log] +Level = 'debug' +JSONConsole = false +UnixTS = false + +[Log.File] +Dir = '' +MaxSize = '5.12gb' +MaxAgeDays = 0 +MaxBackups = 1 + +[WebServer] +AuthenticationMethod = 'local' +AllowOrigins = 'http://localhost:3000,http://localhost:6688' +BridgeResponseURL = '' +BridgeCacheTTL = '0s' +HTTPWriteTimeout = '10s' +HTTPPort = 6688 +SecureCookies = true +SessionTimeout = '15m0s' +SessionReaperExpiration = '240h0m0s' +HTTPMaxSize = '32.77kb' +StartTimeout = '15s' +ListenIP = '0.0.0.0' + +[WebServer.LDAP] +ServerTLS = true +SessionTimeout = '15m0s' +QueryTimeout = '2m0s' +BaseUserAttr = 'uid' +BaseDN = '' +UsersDN = 'ou=users' +GroupsDN = 'ou=groups' +ActiveAttribute = '' +ActiveAttributeAllowedValue = '' +AdminUserGroupCN = 'NodeAdmins' +EditUserGroupCN = 'NodeEditors' +RunUserGroupCN = 'NodeRunners' +ReadUserGroupCN = 'NodeReadOnly' +UserApiTokenEnabled = false +UserAPITokenDuration = '240h0m0s' +UpstreamSyncInterval = '0s' +UpstreamSyncRateLimit = '2m0s' + +[WebServer.MFA] +RPID = '' +RPOrigin = '' + +[WebServer.RateLimit] +Authenticated = 1000 +AuthenticatedPeriod = '1m0s' +Unauthenticated = 5 +UnauthenticatedPeriod = '20s' + +[WebServer.TLS] +CertPath = '' +ForceRedirect = false +Host = '' +HTTPSPort = 6689 +KeyPath = '' +ListenIP = '0.0.0.0' + +[JobPipeline] +ExternalInitiatorsEnabled = false +MaxRunDuration = '10m0s' +MaxSuccessfulRuns = 10000 +ReaperInterval = '1h0m0s' +ReaperThreshold = '24h0m0s' +ResultWriteQueueDepth = 100 + +[JobPipeline.HTTPRequest] +DefaultTimeout = '15s' +MaxSize = '32.77kb' + +[FluxMonitor] +DefaultTransactionQueueDepth = 1 +SimulateTransactions = false + +[OCR2] +Enabled = true +ContractConfirmations = 3 +BlockchainTimeout = '20s' +ContractPollInterval = '1m0s' +ContractSubscribeInterval = '2m0s' +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' +CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = true +DefaultTransactionQueueDepth = 1 +SimulateTransactions = false +TraceLogging = false + +[OCR] +Enabled = false +ObservationTimeout = '5s' +BlockchainTimeout = '20s' +ContractPollInterval = '1m0s' +ContractSubscribeInterval = '2m0s' +DefaultTransactionQueueDepth = 1 +KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' +SimulateTransactions = false +TransmitterAddress = '' +CaptureEATelemetry = false +TraceLogging = false + +[P2P] +IncomingMessageBufferSize = 10 +OutgoingMessageBufferSize = 10 +PeerID = '' +TraceLogging = false + +[P2P.V2] +Enabled = false +AnnounceAddresses = [] +DefaultBootstrappers = [] +DeltaDial = '15s' +DeltaReconcile = '1m0s' +ListenAddresses = [] + +[Keeper] +DefaultTransactionQueueDepth = 1 +GasPriceBufferPercent = 20 +GasTipCapBufferPercent = 20 +BaseFeeBufferPercent = 20 +MaxGracePeriod = 100 +TurnLookBack = 1000 + +[Keeper.Registry] +CheckGasOverhead = 200000 +PerformGasOverhead = 300000 +MaxPerformDataSize = 5000 +SyncInterval = '30m0s' +SyncUpkeepQueueSize = 10 + +[AutoPprof] +Enabled = false +ProfileRoot = '' +PollInterval = '10s' +GatherDuration = '10s' +GatherTraceDuration = '5s' +MaxProfileSize = '100.00mb' +CPUProfileRate = 1 +MemProfileRate = 1 +BlockProfileRate = 1 +MutexProfileFraction = 1 +MemThreshold = '4.00gb' +GoroutineThreshold = 5000 + +[Pyroscope] +ServerAddress = '' +Environment = 'mainnet' + +[Sentry] +Debug = false +DSN = '' +Environment = '' +Release = '' + +[Insecure] +DevWebServer = false +OCRDevelopmentMode = false +InfiniteDepthQueries = false +DisableRateLimiting = false + +[Tracing] +Enabled = false +CollectorTarget = '' +NodeID = '' +SamplingRatio = 0.0 +Mode = 'tls' +TLSCertPath = '' + +[Mercury] +[Mercury.Cache] +LatestReportTTL = '1s' +MaxStaleAge = '1h0m0s' +LatestReportDeadline = '5s' + +[Mercury.TLS] +CertFile = '' + +Invalid configuration: invalid configuration: P2P.V2.Enabled: invalid value (false): P2P required for OCR or OCR2. Please enable P2P or disable OCR/OCR2. + +-- err.txt -- +invalid configuration \ No newline at end of file From 66a4a6b7ff0905a2234e3c909eecb46c24dc3eca Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:56:02 +0200 Subject: [PATCH 51/98] Pin to latest version of common (#12079) * Pin to latest version of common * Pin to latest version of common --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 4dc3995ece4..3064d0d3ffa 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 3b0efd9053e..015ec4d6674 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1171,8 +1171,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/go.mod b/go.mod index 94c9c33f27d..623ad2b6c4d 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 4073b235b7e..8c83807227e 100644 --- a/go.sum +++ b/go.sum @@ -1166,8 +1166,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a1792a04617..741c76f2bff 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 github.com/smartcontractkit/chainlink-testing-framework v1.23.2 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e0f1e90c4a5..f99c0e5b8ef 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1505,8 +1505,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6 h1:hpNkTpLtwWXKqguf7wYqetxpmxY/bSO+1PLpY8VBu2w= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240216174848-c7f1809138d6/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= From 3fd52ff85b7d4ba822b692bd85d92fbb57738fa1 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Mon, 19 Feb 2024 08:51:21 -0800 Subject: [PATCH 52/98] [KS-54] OCR3 contract + config tooling (#12078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [KS-54] OCR3 contract + config tooling * Update CODEOWNERS Co-authored-by: Blaž Hrastnik --------- Co-authored-by: Blaž Hrastnik --- CODEOWNERS | 2 + .../src/v0.8/keystone/OCR3Capability.sol | 37 ++++ core/scripts/keystone/config_example.json | 27 +++ core/scripts/keystone/gen_ocr3_config.go | 207 ++++++++++++++++++ .../scripts/keystone/public_keys_example.json | 38 ++++ 5 files changed, 311 insertions(+) create mode 100644 contracts/src/v0.8/keystone/OCR3Capability.sol create mode 100644 core/scripts/keystone/config_example.json create mode 100644 core/scripts/keystone/gen_ocr3_config.go create mode 100644 core/scripts/keystone/public_keys_example.json diff --git a/CODEOWNERS b/CODEOWNERS index 74a7208cc0a..b6052f1628a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -66,6 +66,8 @@ core/scripts/gateway @smartcontractkit/functions /contracts/**/*llo-feeds* @smartcontrackit/mercury-team /contracts/**/*vrf* @smartcontractkit/vrf-team /contracts/**/*l2ep* @smartcontractkit/integrations +# TODO: replace with a team tag when ready +/contracts/**/*keystone* @archseer @bolekk @patrick-dowell /contracts/src/v0.8/automation @smartcontractkit/keepers /contracts/src/v0.8/functions @smartcontractkit/functions diff --git a/contracts/src/v0.8/keystone/OCR3Capability.sol b/contracts/src/v0.8/keystone/OCR3Capability.sol new file mode 100644 index 00000000000..872ff7e910e --- /dev/null +++ b/contracts/src/v0.8/keystone/OCR3Capability.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.6; + +import {OCR2Base} from "../shared/ocr2/OCR2Base.sol"; + +// OCR2Base provides config management compatible with OCR3 +contract OCR3Capability is OCR2Base { + error ReportingUnsupported(); + + constructor() OCR2Base(true) {} + + function typeAndVersion() external pure override returns (string memory) { + return "Keystone 0.0.0"; + } + + function _beforeSetConfig(uint8 _f, bytes memory _onchainConfig) internal override {} + + function _afterSetConfig(uint8 _f, bytes memory _onchainConfig) internal override {} + + function _validateReport( + bytes32 /* configDigest */, + uint40 /* epochAndRound */, + bytes memory /* report */ + ) internal pure override returns (bool) { + return true; + } + + function _report( + uint256 /* initialGas */, + address /* transmitter */, + uint8 /* signerCount */, + address[MAX_NUM_ORACLES] memory /* signers */, + bytes calldata /* report */ + ) internal virtual override { + revert ReportingUnsupported(); + } +} diff --git a/core/scripts/keystone/config_example.json b/core/scripts/keystone/config_example.json new file mode 100644 index 00000000000..6835a4143f4 --- /dev/null +++ b/core/scripts/keystone/config_example.json @@ -0,0 +1,27 @@ +{ + "OracleConfig": { + "MaxQueryLengthBytes": 1000000, + "MaxObservationLengthBytes": 1000000, + "MaxReportLengthBytes": 1000000, + "MaxRequestBatchSize": 1000, + "UniqueReports": true, + + "DeltaProgressMillis": 5000, + "DeltaResendMillis": 5000, + "DeltaInitialMillis": 5000, + "DeltaRoundMillis": 2000, + "DeltaGraceMillis": 500, + "DeltaCertifiedCommitRequestMillis": 1000, + "DeltaStageMillis": 30000, + "MaxRoundsPerEpoch": 10, + "TransmissionSchedule": [1, 1, 1, 1], + + "MaxDurationQueryMillis": 1000, + "MaxDurationObservationMillis": 1000, + "MaxDurationReportMillis": 1000, + "MaxDurationAcceptMillis": 1000, + "MaxDurationTransmitMillis": 1000, + + "MaxFaultyOracles": 1 + } +} diff --git a/core/scripts/keystone/gen_ocr3_config.go b/core/scripts/keystone/gen_ocr3_config.go new file mode 100644 index 00000000000..2f873dadda7 --- /dev/null +++ b/core/scripts/keystone/gen_ocr3_config.go @@ -0,0 +1,207 @@ +package main + +import ( + "crypto/ed25519" + "encoding/hex" + "encoding/json" + "flag" + "fmt" + "io" + "os" + "time" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + helpers "github.com/smartcontractkit/chainlink/core/scripts/common" +) + +type TopLevelConfigSource struct { + OracleConfig OracleConfigSource +} + +type OracleConfigSource struct { + MaxQueryLengthBytes uint32 + MaxObservationLengthBytes uint32 + MaxReportLengthBytes uint32 + MaxRequestBatchSize uint32 + UniqueReports bool + + DeltaProgressMillis uint32 + DeltaResendMillis uint32 + DeltaInitialMillis uint32 + DeltaRoundMillis uint32 + DeltaGraceMillis uint32 + DeltaCertifiedCommitRequestMillis uint32 + DeltaStageMillis uint32 + MaxRoundsPerEpoch uint64 + TransmissionSchedule []int + + MaxDurationQueryMillis uint32 + MaxDurationObservationMillis uint32 + MaxDurationAcceptMillis uint32 + MaxDurationTransmitMillis uint32 + + MaxFaultyOracles int +} + +type NodeKeys struct { + EthAddress string + P2PPeerID string // p2p_ + OCR2BundleID string // used only in job spec + OCR2OnchainPublicKey string // ocr2on_evm_ + OCR2OffchainPublicKey string // ocr2off_evm_ + OCR2ConfigPublicKey string // ocr2cfg_evm_ + CSAPublicKey string +} + +type orc2drOracleConfig struct { + Signers []string `json:"signers"` + Transmitters []string `json:"transmitters"` + F uint8 `json:"f"` + OnchainConfig string `json:"onchainConfig"` + OffchainConfigVersion uint64 `json:"offchainConfigVersion"` + OffchainConfig string `json:"offchainConfig"` +} + +type generateOCR2Config struct { +} + +func NewGenerateOCR2ConfigCommand() *generateOCR2Config { + return &generateOCR2Config{} +} + +func (g *generateOCR2Config) Name() string { + return "generate-ocr2config" +} + +func mustParseJSONConfigFile(fileName string) (output TopLevelConfigSource) { + return mustParseJSON[TopLevelConfigSource](fileName) +} + +func mustParseKeysFile(fileName string) (output []NodeKeys) { + return mustParseJSON[[]NodeKeys](fileName) +} + +func mustParseJSON[T any](fileName string) (output T) { + jsonFile, err := os.Open(fileName) + if err != nil { + panic(err) + } + defer jsonFile.Close() + bytes, err := io.ReadAll(jsonFile) + if err != nil { + panic(err) + } + err = json.Unmarshal(bytes, &output) + if err != nil { + panic(err) + } + return +} + +func main() { + fs := flag.NewFlagSet("config_gen", flag.ExitOnError) + configFile := fs.String("config", "config_example.json", "a file containing JSON config") + keysFile := fs.String("keys", "public_keys_example.json", "a file containing node public keys") + if err := fs.Parse(os.Args[1:]); err != nil || *keysFile == "" || *configFile == "" { + fs.Usage() + os.Exit(1) + } + + topLevelCfg := mustParseJSONConfigFile(*configFile) + cfg := topLevelCfg.OracleConfig + nca := mustParseKeysFile(*keysFile) + + onchainPubKeys := []common.Address{} + for _, n := range nca { + onchainPubKeys = append(onchainPubKeys, common.HexToAddress(n.OCR2OnchainPublicKey)) + } + + offchainPubKeysBytes := []types.OffchainPublicKey{} + for _, n := range nca { + pkBytes, err := hex.DecodeString(n.OCR2OffchainPublicKey) + if err != nil { + panic(err) + } + + pkBytesFixed := [ed25519.PublicKeySize]byte{} + nCopied := copy(pkBytesFixed[:], pkBytes) + if nCopied != ed25519.PublicKeySize { + panic("wrong num elements copied from ocr2 offchain public key") + } + + offchainPubKeysBytes = append(offchainPubKeysBytes, types.OffchainPublicKey(pkBytesFixed)) + } + + configPubKeysBytes := []types.ConfigEncryptionPublicKey{} + for _, n := range nca { + pkBytes, err := hex.DecodeString(n.OCR2ConfigPublicKey) + helpers.PanicErr(err) + + pkBytesFixed := [ed25519.PublicKeySize]byte{} + n := copy(pkBytesFixed[:], pkBytes) + if n != ed25519.PublicKeySize { + panic("wrong num elements copied") + } + + configPubKeysBytes = append(configPubKeysBytes, types.ConfigEncryptionPublicKey(pkBytesFixed)) + } + + identities := []confighelper.OracleIdentityExtra{} + for index := range nca { + identities = append(identities, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: onchainPubKeys[index][:], + OffchainPublicKey: offchainPubKeysBytes[index], + PeerID: nca[index].P2PPeerID, + TransmitAccount: types.Account(nca[index].EthAddress), + }, + ConfigEncryptionPublicKey: configPubKeysBytes[index], + }) + } + + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + time.Duration(cfg.DeltaProgressMillis)*time.Millisecond, + time.Duration(cfg.DeltaResendMillis)*time.Millisecond, + time.Duration(cfg.DeltaInitialMillis)*time.Millisecond, + time.Duration(cfg.DeltaRoundMillis)*time.Millisecond, + time.Duration(cfg.DeltaGraceMillis)*time.Millisecond, + time.Duration(cfg.DeltaCertifiedCommitRequestMillis)*time.Millisecond, + time.Duration(cfg.DeltaStageMillis)*time.Millisecond, + cfg.MaxRoundsPerEpoch, + cfg.TransmissionSchedule, + identities, + nil, // empty plugin config + time.Duration(cfg.MaxDurationQueryMillis)*time.Millisecond, + time.Duration(cfg.MaxDurationObservationMillis)*time.Millisecond, + time.Duration(cfg.MaxDurationAcceptMillis)*time.Millisecond, + time.Duration(cfg.MaxDurationTransmitMillis)*time.Millisecond, + cfg.MaxFaultyOracles, + nil, // empty onChain config + ) + helpers.PanicErr(err) + + var signersStr []string + var transmittersStr []string + for i := range transmitters { + signersStr = append(signersStr, "0x"+hex.EncodeToString(signers[i])) + transmittersStr = append(transmittersStr, string(transmitters[i])) + } + + config := orc2drOracleConfig{ + Signers: signersStr, + Transmitters: transmittersStr, + F: f, + OnchainConfig: "0x" + hex.EncodeToString(onchainConfig), + OffchainConfigVersion: offchainConfigVersion, + OffchainConfig: "0x" + hex.EncodeToString(offchainConfig), + } + + js, err := json.MarshalIndent(config, "", " ") + helpers.PanicErr(err) + fmt.Println("Config:", string(js)) +} diff --git a/core/scripts/keystone/public_keys_example.json b/core/scripts/keystone/public_keys_example.json new file mode 100644 index 00000000000..1baae3d5c9b --- /dev/null +++ b/core/scripts/keystone/public_keys_example.json @@ -0,0 +1,38 @@ +[ + { + "EthAddress": "0x9639dCc7D0ca4468B5f684ef89F12F0B365c9F6d", + "P2PPeerID": "12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N", + "OCR2BundleID": "29e8dd8c916eac1fc6df8ac6f449481f5db1cf3714e7cb629e16d7b499af5603", + "OCR2OnchainPublicKey": "049b55674e2485b9a6788c0796b74f2c33667670", + "OCR2OffchainPublicKey": "f4f13ca3053e0f44f869648857f0c0ebc20045f9b51d6a5712c867f5920def01", + "OCR2ConfigPublicKey": "17a60b694f7cfb0a02da3da5e79f87b071e518d1f4a27aeb181776969b766e1e", + "CSAPublicKey": "csa_2245bbbee39f75f22e12c345a0ac76bad1f3214b7020a47324a1634dee285761" + }, + { + "EthAddress": "0x8f0fAE64f5f75067833ed5deDC2804B62b21383d", + "P2PPeerID": "12D3KooWG1AyvwmCpZ93J8pBQUE1SuzrjDXnT4BeouncHR3jWLCG", + "OCR2BundleID": "9b19ff8196aec2cdf70f6ac2c3617ea9b03dfb426e0938aee0af2b37459f86eb", + "OCR2OnchainPublicKey": "8405c2b28fcab284f08ed0028f1f511cd57a16b7", + "OCR2OffchainPublicKey": "29e41861f005a0b1bc3156ecd40992a5b552b3182f73f4adec43b4e3052ac2c7", + "OCR2ConfigPublicKey": "0a0c21b14924ee28afad15c96b3a5be372870cdf9b13f002b63fb4ba8942c461", + "CSAPublicKey": "csa_d329bfff7b7835aec205a6ac09bb217e46c754c3ab6730d09b709c7bc395dc3f" + }, + { + "EthAddress": "0xf09A863D920840c13277e76F43CFBdfB22b8FB7C", + "P2PPeerID": "12D3KooWGeUKZBRMbx27FUTgBwZa9Ap9Ym92mywwpuqkEtz8XWyv", + "OCR2BundleID": "200e5d187b4fc8e2d263c13cd28d37c914f275aba1aee91199d5c7766ada9d63", + "OCR2OnchainPublicKey": "4a5199a4e65acfd07b690493ec02bdba3c44c1ec", + "OCR2OffchainPublicKey": "f535037b9ca113d61eb0548e62c28d5abc201bfe36a803ea5f1e94f66da64c9e", + "OCR2ConfigPublicKey": "d62623257ebf3e805ee77162a1b1df0d1b3f57c7dc1dc28b88acb6c9b4f5455f", + "CSAPublicKey": "csa_35ff548c85ada4dbd09b5f02ea3421217d15ebec00a63cab7e529f8bb90542a1" + }, + { + "EthAddress": "0x7eD90b519bC3054a575C464dBf39946b53Ff90EF", + "P2PPeerID": "12D3KooW9zYWQv3STmDeNDidyzxsJSTxoCTLicafgfeEz9nhwhC4", + "OCR2BundleID": "25b40149256109e6036f27b11969c61ba9e765fc60a13324410588c4801f0466", + "OCR2OnchainPublicKey": "07183b1fe36c8f3885a3ce4131b9151a2c7e86b4", + "OCR2OffchainPublicKey": "c64252067d48efe341745cff9aad2f20990158dfe31548322a0bf2921e9428b8", + "OCR2ConfigPublicKey": "893f61aa755f356a248d66b58974742b22518db962ab036b440a33c3eb86ea5b", + "CSAPublicKey": "csa_541f97026a2be5e460276ba4eddebce6e74ccb1d1cfb1550fe54ef615c0534c9" + } +] From 1b5ab9a6fca860a687c5f60ad86414700e626efe Mon Sep 17 00:00:00 2001 From: David Cauchi <13139524+davidcauchi@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:59:29 +0100 Subject: [PATCH 53/98] [ship-812] enable gnosis soak (#12081) * Rename xdai config to gnosis * Add Gnosis Chiado toml config * Update config docs * Enable Gnosis * Enable EIP1559 * Update CTF to latest * make config-docs * Remove legacy config * Removed cl address * Rebase develop * make config-docs --- .../config/toml/defaults/Gnosis_Chiado.toml | 11 +++ ...{xDai_Mainnet.toml => Gnosis_Mainnet.toml} | 0 docs/CONFIG.md | 83 ++++++++++++++++++- .../contracts/contract_deployer.go | 6 ++ .../contracts/contract_loader.go | 7 ++ integration-tests/go.mod | 2 +- integration-tests/go.sum | 8 +- 7 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml rename core/chains/evm/config/toml/defaults/{xDai_Mainnet.toml => Gnosis_Mainnet.toml} (100%) diff --git a/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml b/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml new file mode 100644 index 00000000000..4770e104fbb --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml @@ -0,0 +1,11 @@ +ChainID = '10200' +# Gnoisis Finality is approx 8 minutes @ 12 blocks per minute, so 96 blocks +FinalityDepth = 100 +ChainType = 'xdai' +LogPollInterval = '5s' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMax = '500 gwei' +# 15s delay since feeds update every minute in volatile situations +BumpThreshold = 3 diff --git a/core/chains/evm/config/toml/defaults/xDai_Mainnet.toml b/core/chains/evm/config/toml/defaults/Gnosis_Mainnet.toml similarity index 100% rename from core/chains/evm/config/toml/defaults/xDai_Mainnet.toml rename to core/chains/evm/config/toml/defaults/Gnosis_Mainnet.toml diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 2c4f3109421..cb1653c1020 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -2564,7 +2564,7 @@ GasLimit = 5400000

-
xDai Mainnet (100)

+

Gnosis Mainnet (100)

```toml AutoCreateKey = true @@ -4181,6 +4181,87 @@ GasLimit = 6500000

+
Gnosis Chiado (10200)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'xdai' +FinalityDepth = 100 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '5s' +LogKeepBlocksDepth = 100000 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '3m0s' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '500 gwei' +PriceMin = '1 gwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = true +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' + +[OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 +``` + +

+
Arbitrum Mainnet (42161)

```toml diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index 2acc0a2109e..47c654b5d46 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -193,6 +193,8 @@ func NewContractDeployer(bcClient blockchain.EVMClient, logger zerolog.Logger) ( return &KromaContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil case *blockchain.WeMixClient: return &WeMixContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil + case *blockchain.GnosisClient: + return &GnosisContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil } return nil, errors.New("unknown blockchain client implementation for contract deployer, register blockchain client in NewContractDeployer") } @@ -268,6 +270,10 @@ type WeMixContractDeployer struct { *EthereumContractDeployer } +type GnosisContractDeployer struct { + *EthereumContractDeployer +} + // NewEthereumContractDeployer returns an instantiated instance of the ETH contract deployer func NewEthereumContractDeployer(ethClient blockchain.EVMClient, logger zerolog.Logger) *EthereumContractDeployer { return &EthereumContractDeployer{ diff --git a/integration-tests/contracts/contract_loader.go b/integration-tests/contracts/contract_loader.go index 0fec424426a..92526c7ddda 100644 --- a/integration-tests/contracts/contract_loader.go +++ b/integration-tests/contracts/contract_loader.go @@ -81,6 +81,8 @@ func NewContractLoader(bcClient blockchain.EVMClient, logger zerolog.Logger) (Co return &FantomContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil case *blockchain.BSCClient: return &BSCContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil + case *blockchain.GnosisClient: + return &GnosisContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil } return nil, errors.New("unknown blockchain client implementation for contract Loader, register blockchain client in NewContractLoader") } @@ -154,6 +156,11 @@ type BSCContractLoader struct { *EthereumContractLoader } +// GnosisContractLoader wraps for Gnosis +type GnosisContractLoader struct { + *EthereumContractLoader +} + // NewEthereumContractLoader returns an instantiated instance of the ETH contract Loader func NewEthereumContractLoader(ethClient blockchain.EVMClient, logger zerolog.Logger) *EthereumContractLoader { return &EthereumContractLoader{ diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 741c76f2bff..63c0c15162d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -25,7 +25,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 - github.com/smartcontractkit/chainlink-testing-framework v1.23.2 + github.com/smartcontractkit/chainlink-testing-framework v1.23.5 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a diff --git a/integration-tests/go.sum b/integration-tests/go.sum index f99c0e5b8ef..084077d21d1 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1473,8 +1473,8 @@ github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY= github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1517,8 +1517,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= -github.com/smartcontractkit/chainlink-testing-framework v1.23.2 h1:haXPd9Pg++Zs5/QIZnhFd9RElmz/d0+4nNeletUg9ZM= -github.com/smartcontractkit/chainlink-testing-framework v1.23.2/go.mod h1:StIOdxvwd8AMO6xuBtmD6FQfJXktEn/mJJEr7728BTc= +github.com/smartcontractkit/chainlink-testing-framework v1.23.5 h1:bymN/mr4Tbx3DQ7EMB/z81+pCLhJkiYgxJDgAeTo9/w= +github.com/smartcontractkit/chainlink-testing-framework v1.23.5/go.mod h1:lGaqSnCB36n49fZNdTGXMrxhPu9w5+2n3c9V1Fqz1hM= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= From 60392982e3cff20864b2810c58c74625ad3a4232 Mon Sep 17 00:00:00 2001 From: Lee Yik Jiun Date: Tue, 20 Feb 2024 04:44:10 +0800 Subject: [PATCH 54/98] Add native payment to RandomWordsFulfilled event (#12085) * Add native payment to RandomWordsFulfilled event * Minor change --------- Co-authored-by: Sri Kidambi <1702865+kidambisrinivas@users.noreply.github.com> --- .../src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol | 26 ++++++++----------- .../test/v0.8/foundry/vrf/VRFV2Plus.t.sol | 8 +++--- .../vrf_coordinator_v2_5.go | 21 ++++++++------- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../vrf/v2/coordinator_v2x_interface.go | 4 +++ 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol b/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol index 4bd7c1bd20c..619930e6439 100644 --- a/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol +++ b/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol @@ -75,6 +75,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { uint256 outputSeed, uint256 indexed subId, uint96 payment, + bool nativePayment, bool success, bool onlyPremium ); @@ -457,28 +458,23 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { } } - uint256 requestId = output.requestId; - delete s_requestCommitments[requestId]; - bool success = _deliverRandomness(requestId, rc, randomWords); + delete s_requestCommitments[output.requestId]; + bool success = _deliverRandomness(output.requestId, rc, randomWords); // Increment the req count for the subscription. - uint256 subId = rc.subId; - ++s_subscriptions[subId].reqCount; + ++s_subscriptions[rc.subId].reqCount; - // stack too deep error - { - bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; + bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; - // We want to charge users exactly for how much gas they use in their callback. - // The gasAfterPaymentCalculation is meant to cover these additional operations where we - // decrement the subscription balance and increment the oracles withdrawable balance. - payment = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium); + // We want to charge users exactly for how much gas they use in their callback. + // The gasAfterPaymentCalculation is meant to cover these additional operations where we + // decrement the subscription balance and increment the oracles withdrawable balance. + payment = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium); - _chargePayment(payment, nativePayment, subId); - } + _chargePayment(payment, nativePayment, rc.subId); // Include payment in the event for tracking costs. - emit RandomWordsFulfilled(requestId, randomness, subId, payment, success, onlyPremium); + emit RandomWordsFulfilled(output.requestId, randomness, rc.subId, payment, nativePayment, success, onlyPremium); return payment; } diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol index dfd2c83d07b..44daade0b1e 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol @@ -332,7 +332,7 @@ contract VRFV2Plus is BaseTest { VmSafe.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries[0].topics[1], bytes32(uint256(requestId))); assertEq(entries[0].topics[2], bytes32(uint256(subId))); - (uint256 loggedOutputSeed, , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool)); + (uint256 loggedOutputSeed, , , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool, bool)); assertEq(loggedOutputSeed, outputSeed); assertEq(loggedSuccess, true); @@ -374,7 +374,7 @@ contract VRFV2Plus is BaseTest { VmSafe.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries[0].topics[1], bytes32(uint256(requestId))); assertEq(entries[0].topics[2], bytes32(uint256(subId))); - (uint256 loggedOutputSeed, , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool)); + (uint256 loggedOutputSeed, , , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool, bool)); assertEq(loggedOutputSeed, outputSeed); assertEq(loggedSuccess, true); @@ -624,7 +624,7 @@ contract VRFV2Plus is BaseTest { VmSafe.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries[0].topics[1], bytes32(uint256(requestId))); assertEq(entries[0].topics[2], bytes32(uint256(subId))); - (uint256 loggedOutputSeed, , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool)); + (uint256 loggedOutputSeed, , , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool, bool)); assertEq(loggedOutputSeed, outputSeed); assertEq(loggedSuccess, true); @@ -671,7 +671,7 @@ contract VRFV2Plus is BaseTest { VmSafe.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries[0].topics[1], bytes32(uint256(requestId))); assertEq(entries[0].topics[2], bytes32(uint256(subId))); - (uint256 loggedOutputSeed, , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool)); + (uint256 loggedOutputSeed, , , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool, bool)); assertEq(loggedOutputSeed, outputSeed); assertEq(loggedSuccess, true); diff --git a/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go b/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go index 6a53141253b..2d1c2f4cec7 100644 --- a/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go +++ b/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go @@ -61,8 +61,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } var VRFCoordinatorV25MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"want\",\"type\":\"uint256\"}],\"name\":\"InsufficientGasForConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2_5.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162005da138038062005da1833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615bc6620001db6000396000818161055001526131e70152615bc66000f3fe60806040526004361061021c5760003560e01c80638402595e11610124578063b2a7cac5116100a6578063b2a7cac514610732578063bec4c08c14610752578063caf70c4a14610772578063cb63179714610792578063d98e620e146107b2578063da2f2610146107d2578063dac83d2914610831578063dc311dd314610851578063e72f6e3014610882578063ee9d2d38146108a2578063f2fde38b146108cf57600080fd5b80638402595e146105c757806386fe91c7146105e75780638da5cb5b1461060757806395b55cfc146106255780639b1c385e146106385780639d40a6fd14610658578063a21a23e414610690578063a4c0ed36146106a5578063a63e0bfb146106c5578063aa433aff146106e5578063aefb212f1461070557600080fd5b8063405b84fa116101ad578063405b84fa1461044e57806340d6bb821461046e57806341af6c871461049957806351cff8d9146104c95780635d06b4ab146104e957806364d51a2a14610509578063659827441461051e578063689c45171461053e57806372e9d5651461057257806379ba5097146105925780637a5a2aef146105a757600080fd5b806304104edb14610221578063043bd6ae14610243578063088070f51461026c57806308821d581461033a5780630ae095401461035a57806315c48b841461037a57806318e3dd27146103a25780631b6b6d23146103e15780632f622e6b1461040e578063301f42e91461042e575b600080fd5b34801561022d57600080fd5b5061024161023c366004614f92565b6108ef565b005b34801561024f57600080fd5b5061025960105481565b6040519081526020015b60405180910390f35b34801561027857600080fd5b50600c546102dd9061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610263565b34801561034657600080fd5b50610241610355366004615070565b610a5c565b34801561036657600080fd5b5061024161037536600461535a565b610c06565b34801561038657600080fd5b5061038f60c881565b60405161ffff9091168152602001610263565b3480156103ae57600080fd5b50600a546103c990600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610263565b3480156103ed57600080fd5b50600254610401906001600160a01b031681565b604051610263919061558b565b34801561041a57600080fd5b50610241610429366004614f92565b610c4e565b34801561043a57600080fd5b506103c9610449366004615176565b610d9a565b34801561045a57600080fd5b5061024161046936600461535a565b610fc0565b34801561047a57600080fd5b506104846101f481565b60405163ffffffff9091168152602001610263565b3480156104a557600080fd5b506104b96104b43660046150f9565b611372565b6040519015158152602001610263565b3480156104d557600080fd5b506102416104e4366004614f92565b611482565b3480156104f557600080fd5b50610241610504366004614f92565b611610565b34801561051557600080fd5b5061038f606481565b34801561052a57600080fd5b50610241610539366004614faf565b6116c7565b34801561054a57600080fd5b506104017f000000000000000000000000000000000000000000000000000000000000000081565b34801561057e57600080fd5b50600354610401906001600160a01b031681565b34801561059e57600080fd5b50610241611727565b3480156105b357600080fd5b506102416105c236600461508c565b6117d1565b3480156105d357600080fd5b506102416105e2366004614f92565b611901565b3480156105f357600080fd5b50600a546103c9906001600160601b031681565b34801561061357600080fd5b506000546001600160a01b0316610401565b6102416106333660046150f9565b611a13565b34801561064457600080fd5b50610259610653366004615264565b611b37565b34801561066457600080fd5b50600754610678906001600160401b031681565b6040516001600160401b039091168152602001610263565b34801561069c57600080fd5b50610259611e78565b3480156106b157600080fd5b506102416106c0366004614fe8565b61204b565b3480156106d157600080fd5b506102416106e03660046152b9565b6121c7565b3480156106f157600080fd5b506102416107003660046150f9565b612444565b34801561071157600080fd5b5061072561072036600461537f565b61248c565b6040516102639190615602565b34801561073e57600080fd5b5061024161074d3660046150f9565b61258e565b34801561075e57600080fd5b5061024161076d36600461535a565b612683565b34801561077e57600080fd5b5061025961078d3660046150c0565b61278f565b34801561079e57600080fd5b506102416107ad36600461535a565b6127bf565b3480156107be57600080fd5b506102596107cd3660046150f9565b612a2e565b3480156107de57600080fd5b506108126107ed3660046150f9565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b03909116602083015201610263565b34801561083d57600080fd5b5061024161084c36600461535a565b612a4f565b34801561085d57600080fd5b5061087161086c3660046150f9565b612ae6565b6040516102639594939291906157d7565b34801561088e57600080fd5b5061024161089d366004614f92565b612bd4565b3480156108ae57600080fd5b506102596108bd3660046150f9565b600f6020526000908152604090205481565b3480156108db57600080fd5b506102416108ea366004614f92565b612da7565b6108f7612db8565b60115460005b81811015610a3457826001600160a01b03166011828154811061092257610922615b22565b6000918252602090912001546001600160a01b03161415610a2457601161094a6001846159d2565b8154811061095a5761095a615b22565b600091825260209091200154601180546001600160a01b03909216918390811061098657610986615b22565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060118054806109c5576109c5615b0c565b600082815260209020810160001990810180546001600160a01b03191690550190556040517ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3790610a1790859061558b565b60405180910390a1505050565b610a2d81615a8a565b90506108fd565b5081604051635428d44960e01b8152600401610a50919061558b565b60405180910390fd5b50565b610a64612db8565b604080518082018252600091610a9391908490600290839083908082843760009201919091525061278f915050565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b03169183019190915291925090610af157604051631dfd6e1360e21b815260048101839052602401610a50565b6000828152600d6020526040812080546001600160481b0319169055600e54905b81811015610bc25783600e8281548110610b2e57610b2e615b22565b90600052602060002001541415610bb257600e610b4c6001846159d2565b81548110610b5c57610b5c615b22565b9060005260206000200154600e8281548110610b7a57610b7a615b22565b600091825260209091200155600e805480610b9757610b97615b0c565b60019003818190600052602060002001600090559055610bc2565b610bbb81615a8a565b9050610b12565b507f9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5838360200151604051610bf8929190615615565b60405180910390a150505050565b81610c1081612e0d565b610c18612e6e565b610c2183611372565b15610c3f57604051631685ecdd60e31b815260040160405180910390fd5b610c498383612e99565b505050565b610c56612e6e565b610c5e612db8565b600b54600160601b90046001600160601b0316610c8e57604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c610cb18380615a0e565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610cf99190615a0e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610d73576040519150601f19603f3d011682016040523d82523d6000602084013e610d78565b606091505b5050905080610c495760405163950b247960e01b815260040160405180910390fd5b6000610da4612e6e565b60005a90506000610db5868661304d565b90506000610dcb85836000015160200151613309565b60408301516060888101519293509163ffffffff16806001600160401b03811115610df857610df8615b38565b604051908082528060200260200182016040528015610e21578160200160208202803683370190505b50925060005b81811015610e895760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c848281518110610e6e57610e6e615b22565b6020908102919091010152610e8281615a8a565b9050610e27565b50506020808501516000818152600f9092526040822082905590610eae828b86613357565b60208b81015160008181526006909252604090912080549293509091601890610ee690600160c01b90046001600160401b0316615aa5565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555060008b60a0015160018d60a0015151610f2391906159d2565b81518110610f3357610f33615b22565b60209101015160f81c6001149050610f4d8988838e6133f2565b9950610f5a8a8284613422565b50604080518581526001600160601b038b166020820152831515818301528b151560608201529051829185917f6c6b5394380e16e41988d8383648010de6f5c2e4814803be5de1c6b1c852db559181900360800190a350505050505050505b9392505050565b610fc8612e6e565b610fd181613575565b610ff05780604051635428d44960e01b8152600401610a50919061558b565b600080600080610fff86612ae6565b945094505093509350336001600160a01b0316826001600160a01b0316146110625760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610a50565b61106b86611372565b156110b15760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610a50565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a0830152915190916000916111069184910161563f565b6040516020818303038152906040529050611120886135e1565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b0388169061115990859060040161562c565b6000604051808303818588803b15801561117257600080fd5b505af1158015611186573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506111af905057506001600160601b03861615155b156112795760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906111e6908a908a906004016155d2565b602060405180830381600087803b15801561120057600080fd5b505af1158015611214573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123891906150dc565b6112795760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a50565b600c805460ff60301b1916600160301b17905560005b8351811015611320578381815181106112aa576112aa615b22565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016112dd919061558b565b600060405180830381600087803b1580156112f757600080fd5b505af115801561130b573d6000803e3d6000fd5b505050508061131990615a8a565b905061128f565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906113609089908b9061559f565b60405180910390a15050505050505050565b6000818152600560205260408120600201805480611394575060009392505050565b600e5460005b828110156114765760008482815481106113b6576113b6615b22565b60009182526020822001546001600160a01b031691505b8381101561146357600061142b600e83815481106113ed576113ed615b22565b60009182526020808320909101546001600160a01b03871683526004825260408084208e855290925291205485908c906001600160401b0316613789565b506000818152600f6020526040902054909150156114525750600198975050505050505050565b5061145c81615a8a565b90506113cd565b50508061146f90615a8a565b905061139a565b50600095945050505050565b61148a612e6e565b611492612db8565b6002546001600160a01b03166114bb5760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166114e457604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006115008380615a0e565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166115489190615a0e565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061159d90859085906004016155d2565b602060405180830381600087803b1580156115b757600080fd5b505af11580156115cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ef91906150dc565b61160c57604051631e9acf1760e31b815260040160405180910390fd5b5050565b611618612db8565b61162181613575565b15611641578060405163ac8a27ef60e01b8152600401610a50919061558b565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625906116bc90839061558b565b60405180910390a150565b6116cf612db8565b6002546001600160a01b0316156116f957604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b0316331461177a5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610a50565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6117d9612db8565b60408051808201825260009161180891908590600290839083908082843760009201919091525061278f915050565b6000818152600d602052604090205490915060ff161561183e57604051634a0b8fa760e01b815260048101829052602401610a50565b60408051808201825260018082526001600160401b0385811660208085019182526000878152600d9091528581209451855492516001600160481b031990931690151568ffffffffffffffff00191617610100929093169190910291909117909255600e805491820181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01829055517f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd390610a179083908590615615565b611909612db8565b600a544790600160601b90046001600160601b031681811115611949576040516354ced18160e11b81526004810182905260248101839052604401610a50565b81811015610c4957600061195d82846159d2565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d80600081146119ac576040519150601f19603f3d011682016040523d82523d6000602084013e6119b1565b606091505b50509050806119d35760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611a0492919061559f565b60405180910390a15050505050565b611a1b612e6e565b6000818152600560205260409020546001600160a01b0316611a5057604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611a7f838561597d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611ac7919061597d565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611b1a919061591e565b604080519283526020830191909152015b60405180910390a25050565b6000611b41612e6e565b602080830135600081815260059092526040909120546001600160a01b0316611b7d57604051630fb532db60e11b815260040160405180910390fd5b33600090815260046020908152604080832084845291829052909120546001600160401b031680611bc55782336040516379bfd40160e01b8152600401610a509291906156b4565b600c5461ffff16611bdc606087016040880161529e565b61ffff161080611bff575060c8611bf9606087016040880161529e565b61ffff16115b15611c4557611c14606086016040870161529e565b600c5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610a50565b600c5462010000900463ffffffff16611c6460808701606088016153a1565b63ffffffff161115611cb457611c8060808601606087016153a1565b600c54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610a50565b6101f4611cc760a08701608088016153a1565b63ffffffff161115611d0d57611ce360a08601608087016153a1565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610a50565b611d1681615aa5565b90506000611d278635338685613789565b90955090506000611d4b611d46611d4160a08a018a61582c565b613802565b61387f565b905085611d566138f0565b86611d6760808b0160608c016153a1565b611d7760a08c0160808d016153a1565b3386604051602001611d8f9796959493929190615737565b60405160208183030381529060405280519060200120600f600088815260200190815260200160002081905550336001600160a01b03168588600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e89868c6040016020810190611e02919061529e565b8d6060016020810190611e1591906153a1565b8e6080016020810190611e2891906153a1565b89604051611e3b969594939291906156f8565b60405180910390a450506000928352602091909152604090912080546001600160401b0319166001600160401b039092169190911790555b919050565b6000611e82612e6e565b6007546001600160401b031633611e9a6001436159d2565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611eff816001615936565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b039283161783559351600183018054909516911617909255925180519294939192611ffd9260028501920190614cac565b5061200d91506008905084613980565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161203e919061558b565b60405180910390a2505090565b612053612e6e565b6002546001600160a01b0316331461207e576040516344b0e3c360e01b815260040160405180910390fd5b6020811461209f57604051638129bbcd60e01b815260040160405180910390fd5b60006120ad828401846150f9565b6000818152600560205260409020549091506001600160a01b03166120e557604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061210c838561597d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b0316612154919061597d565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846121a7919061591e565b6040805192835260208301919091520160405180910390a2505050505050565b6121cf612db8565b60c861ffff8a1611156122095760405163539c34bb60e11b815261ffff8a1660048201819052602482015260c86044820152606401610a50565b6000851361222d576040516321ea67b360e11b815260048101869052602401610a50565b60008463ffffffff1611801561224f57508363ffffffff168363ffffffff1610155b1561227d576040516313c06e5960e11b815263ffffffff808516600483015285166024820152604401610a50565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b9099029890981667ffffffffffffffff60781b19600160581b90960263ffffffff60581b19600160381b9098029790971668ffffffffffffffffff60301b196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b690612431908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b61244c612db8565b6000818152600560205260409020546001600160a01b03168061248257604051630fb532db60e11b815260040160405180910390fd5b61160c8282612e99565b6060600061249a600861398c565b90508084106124bc57604051631390f2a160e01b815260040160405180910390fd5b60006124c8848661591e565b9050818111806124d6575083155b6124e057806124e2565b815b905060006124f086836159d2565b9050806001600160401b0381111561250a5761250a615b38565b604051908082528060200260200182016040528015612533578160200160208202803683370190505b50935060005b818110156125835761255661254e888361591e565b600890613996565b85828151811061256857612568615b22565b602090810291909101015261257c81615a8a565b9050612539565b505050505b92915050565b612596612e6e565b6000818152600560205260409020546001600160a01b0316806125cc57604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b03163314612623576000828152600560205260409081902060010154905163d084e97560e01b8152610a50916001600160a01b03169060040161558b565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611b2b9185916155b8565b8161268d81612e0d565b612695612e6e565b60008381526005602052604090206002018054606414156126c9576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b038316600090815260046020908152604080832087845291829052909120546001600160401b031615612704575050505050565b600085815260208281526040808320805460016001600160401b0319909116811790915585549081018655858452919092200180546001600160a01b0319166001600160a01b0387161790555185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061278090879061558b565b60405180910390a25050505050565b6000816040516020016127a291906155f4565b604051602081830303815290604052805190602001209050919050565b816127c981612e0d565b6127d1612e6e565b6127da83611372565b156127f857604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b03166128465782826040516379bfd40160e01b8152600401610a509291906156b4565b6000838152600560209081526040808320600201805482518185028101850190935280835291929091908301828280156128a957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161288b575b505050505090506000600182516128c091906159d2565b905060005b82518110156129ca57846001600160a01b03168382815181106128ea576128ea615b22565b60200260200101516001600160a01b031614156129ba57600083838151811061291557612915615b22565b602002602001015190508060056000898152602001908152602001600020600201838154811061294757612947615b22565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925588815260059091526040902060020180548061299257612992615b0c565b600082815260209020810160001990810180546001600160a01b0319169055019055506129ca565b6129c381615a8a565b90506128c5565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160401b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79061278090879061558b565b600e8181548110612a3e57600080fd5b600091825260209091200154905081565b81612a5981612e0d565b612a61612e6e565b600083815260056020526040902060018101546001600160a01b03848116911614612ae0576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612ad790339087906155b8565b60405180910390a25b50505050565b600081815260056020526040812054819081906001600160a01b0316606081612b2257604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612bba57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612b9c575b505050505090509450945094509450945091939590929450565b612bdc612db8565b6002546001600160a01b0316612c055760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612c3690309060040161558b565b60206040518083038186803b158015612c4e57600080fd5b505afa158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c869190615112565b600a549091506001600160601b031681811115612cc0576040516354ced18160e11b81526004810182905260248101839052604401610a50565b81811015610c49576000612cd482846159d2565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612d07908790859060040161559f565b602060405180830381600087803b158015612d2157600080fd5b505af1158015612d35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5991906150dc565b612d7657604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366008482604051610bf892919061559f565b612daf612db8565b610a59816139a2565b6000546001600160a01b03163314612e0b5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610a50565b565b6000818152600560205260409020546001600160a01b031680612e4357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461160c5780604051636c51fda960e11b8152600401610a50919061558b565b600c54600160301b900460ff1615612e0b5760405163769dd35360e11b815260040160405180910390fd5b600080612ea5846135e1565b60025491935091506001600160a01b031615801590612ecc57506001600160601b03821615155b15612f7b5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90612f0c9086906001600160601b0387169060040161559f565b602060405180830381600087803b158015612f2657600080fd5b505af1158015612f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5e91906150dc565b612f7b57604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114612fd1576040519150601f19603f3d011682016040523d82523d6000602084013e612fd6565b606091505b5050905080612ff85760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c490606001612780565b6040805160a08101825260006060820181815260808301829052825260208201819052918101919091526000613086846000015161278f565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b031691830191909152919250906130e457604051631dfd6e1360e21b815260048101839052602401610a50565b6000828660800151604051602001613106929190918252602082015260400190565b60408051601f1981840301815291815281516020928301206000818152600f9093529120549091508061314c57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d0151935161317b978a979096959101615783565b6040516020818303038152906040528051906020012081146131b05760405163354a450b60e21b815260040160405180910390fd5b60006131bf8760000151613a46565b905080613297578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561323157600080fd5b505afa158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615112565b90508061329757865160405163175dadad60e01b81526001600160401b039091166004820152602401610a50565b60008860800151826040516020016132b9929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006132e08a83613b28565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a111561334f57821561333257506001600160401b038116612588565b3a8260405163435e532d60e11b8152600401610a50929190615615565b503a92915050565b6000806000631fe543e360e01b86856040516024016133779291906156df565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559086015160808701519192506133db9163ffffffff9091169083613b93565b600c805460ff60301b191690559695505050505050565b6000821561340c57613405858584613bdf565b905061341a565b613417858584613cf0565b90505b949350505050565b600081815260066020526040902082156134e15780546001600160601b03600160601b909104811690851681101561346d57604051631e9acf1760e31b815260040160405180910390fd5b6134778582615a0e565b8254600160601b600160c01b031916600160601b6001600160601b039283168102919091178455600b805488939192600c926134b792869290041661597d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050612ae0565b80546001600160601b0390811690851681101561351157604051631e9acf1760e31b815260040160405180910390fd5b61351b8582615a0e565b82546001600160601b0319166001600160601b03918216178355600b8054879260009161354a9185911661597d565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050505050565b601154600090815b818110156135d757836001600160a01b0316601182815481106135a2576135a2615b22565b6000918252602090912001546001600160a01b031614156135c7575060019392505050565b6135d081615a8a565b905061357d565b5060009392505050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b81811015613683576004600084838154811061363657613636615b22565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160401b031916905561367c81615a8a565b9050613618565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906136bb6002830182614d11565b50506000858152600660205260408120556136d7600886613ed9565b506001600160601b0384161561372a57600a80548591906000906137059084906001600160601b0316615a0e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156137825782600a600c8282829054906101000a90046001600160601b031661375d9190615a0e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b6040805160208082018790526001600160a01b03959095168183015260608101939093526001600160401b03919091166080808401919091528151808403909101815260a08301825280519084012060c083019490945260e0808301859052815180840390910181526101009092019052805191012091565b6040805160208101909152600081528161382b5750604080516020810190915260008152612588565b63125fa26760e31b61383d8385615a2e565b6001600160e01b0319161461386557604051632923fee760e11b815260040160405180910390fd5b61387282600481866158f4565b810190610fb9919061512b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016138b891511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b6000466138fc81613ee5565b156139795760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561393b57600080fd5b505afa15801561394f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139739190615112565b91505090565b4391505090565b6000610fb98383613f08565b6000612588825490565b6000610fb98383613f57565b6001600160a01b0381163314156139f55760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610a50565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613a5281613ee5565b15613b1957610100836001600160401b0316613a6c6138f0565b613a7691906159d2565b1180613a925750613a856138f0565b836001600160401b031610155b15613aa05750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a82906024015b60206040518083038186803b158015613ae157600080fd5b505afa158015613af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb99190615112565b50506001600160401b03164090565b6000613b5c8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f81565b60038360200151604051602001613b749291906156cb565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613ba557600080fd5b611388810390508460408204820311613bbd57600080fd5b50823b613bc957600080fd5b60008083516020850160008789f1949350505050565b600080613c226000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061419d92505050565b905060005a600c54613c42908890600160581b900463ffffffff1661591e565b613c4c91906159d2565b613c5690866159b3565b600c54909150600090613c7b90600160781b900463ffffffff1664e8d4a510006159b3565b90508415613cc757600c548190606490600160b81b900460ff16613c9f858761591e565b613ca991906159b3565b613cb3919061599f565b613cbd919061591e565b9350505050610fb9565b600c548190606490613ce390600160b81b900460ff1682615958565b60ff16613c9f858761591e565b600080613cfb61426b565b905060008113613d21576040516321ea67b360e11b815260048101829052602401610a50565b6000613d636000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061419d92505050565b9050600082825a600c54613d85908b90600160581b900463ffffffff1661591e565b613d8f91906159d2565b613d9990896159b3565b613da3919061591e565b613db590670de0b6b3a76400006159b3565b613dbf919061599f565b600c54909150600090613de89063ffffffff600160981b8204811691600160781b9004166159e9565b613dfd9063ffffffff1664e8d4a510006159b3565b9050600084613e1483670de0b6b3a76400006159b3565b613e1e919061599f565b905060008715613e5f57600c548290606490613e4490600160c01b900460ff16876159b3565b613e4e919061599f565b613e58919061591e565b9050613e9f565b600c548290606490613e7b90600160c01b900460ff1682615958565b613e889060ff16876159b3565b613e92919061599f565b613e9c919061591e565b90505b6b033b2e3c9fd0803ce8000000811115613ecc5760405163e80fa38160e01b815260040160405180910390fd5b9998505050505050505050565b6000610fb9838361433a565b600061a4b1821480613ef9575062066eed82145b8061258857505062066eee1490565b6000818152600183016020526040812054613f4f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612588565b506000612588565b6000826000018281548110613f6e57613f6e615b22565b9060005260206000200154905092915050565b613f8a8961442d565b613fd35760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610a50565b613fdc8861442d565b6140205760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610a50565b6140298361442d565b6140755760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610a50565b61407e8261442d565b6140ca5760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610a50565b6140d6878a88876144f0565b61411e5760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610a50565b600061412a8a87614613565b9050600061413d898b878b868989614677565b9050600061414e838d8d8a86614796565b9050808a1461418f5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610a50565b505050505050505050505050565b6000466141a981613ee5565b156141e857606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613ae157600080fd5b6141f1816147d6565b1561426257600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615b72604891396040516020016142379291906154e1565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613ac9919061562c565b50600092915050565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169284926001600160a01b039091169163feaf968c9160048082019260a092909190829003018186803b1580156142c657600080fd5b505afa1580156142da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142fe91906153bc565b50919550909250505063ffffffff82161580159061432a575061432181426159d2565b8263ffffffff16105b156143355760105492505b505090565b6000818152600183016020526040812054801561442357600061435e6001836159d2565b8554909150600090614372906001906159d2565b90508181146143d757600086600001828154811061439257614392615b22565b90600052602060002001549050808760000184815481106143b5576143b5615b22565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806143e8576143e8615b0c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612588565b6000915050612588565b80516000906401000003d0191161447b5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610a50565b60208201516401000003d019116144c95760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610a50565b60208201516401000003d0199080096144e98360005b6020020151614810565b1492915050565b60006001600160a01b0382166145365760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610a50565b60208401516000906001161561454d57601c614550565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa1580156145eb573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b61461b614d2f565b614648600184846040516020016146349392919061556a565b604051602081830303815290604052614834565b90505b6146548161442d565b6125885780516040805160208101929092526146709101614634565b905061464b565b61467f614d2f565b825186516401000003d01990819006910614156146de5760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610a50565b6146e9878988614882565b61472e5760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610a50565b614739848685614882565b61477f5760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610a50565b61478a8684846149aa565b98975050505050505050565b6000600286868685876040516020016147b496959493929190615510565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a8214806147e857506101a482145b806147f5575062aa37dc82145b80614801575061210582145b8061258857505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b61483c614d2f565b61484582614a6d565b815261485a6148558260006144df565b614aa8565b602082018190526002900660011415611e73576020810180516401000003d019039052919050565b6000826148bf5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610a50565b835160208501516000906148d590600290615acc565b156148e157601c6148e4565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614956573d6000803e3d6000fd5b50505060206040510351905060008660405160200161497591906154cf565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b6149b2614d2f565b8351602080860151855191860151600093849384936149d393909190614ac8565b919450925090506401000003d019858209600114614a2f5760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610a50565b60405180604001604052806401000003d01980614a4e57614a4e615af6565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611e7357604080516020808201939093528151808203840181529082019091528051910120614a75565b6000612588826002614ac16401000003d019600161591e565b901c614ba8565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614b0883838585614c3f565b9098509050614b1988828e88614c63565b9098509050614b2a88828c87614c63565b90985090506000614b3d8d878b85614c63565b9098509050614b4e88828686614c3f565b9098509050614b5f88828e89614c63565b9098509050818114614b94576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614b98565b8196505b5050505050509450945094915050565b600080614bb3614d4d565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614be5614d6b565b60208160c0846005600019fa925082614c355760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610a50565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614d01579160200282015b82811115614d0157825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614ccc565b50614d0d929150614d89565b5090565b5080546000825590600052602060002090810190610a599190614d89565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614d0d5760008155600101614d8a565b8035611e7381615b4e565b806040810183101561258857600080fd5b600082601f830112614dcb57600080fd5b604051604081018181106001600160401b0382111715614ded57614ded615b38565b8060405250808385604086011115614e0457600080fd5b60005b6002811015614e26578135835260209283019290910190600101614e07565b509195945050505050565b8035611e7381615b63565b600060c08284031215614e4e57600080fd5b614e56615879565b9050614e6182614f50565b815260208083013581830152614e7960408401614f3c565b6040830152614e8a60608401614f3c565b60608301526080830135614e9d81615b4e565b608083015260a08301356001600160401b0380821115614ebc57600080fd5b818501915085601f830112614ed057600080fd5b813581811115614ee257614ee2615b38565b614ef4601f8201601f191685016158c4565b91508082528684828501011115614f0a57600080fd5b80848401858401376000848284010152508060a085015250505092915050565b803561ffff81168114611e7357600080fd5b803563ffffffff81168114611e7357600080fd5b80356001600160401b0381168114611e7357600080fd5b803560ff81168114611e7357600080fd5b805169ffffffffffffffffffff81168114611e7357600080fd5b600060208284031215614fa457600080fd5b8135610fb981615b4e565b60008060408385031215614fc257600080fd5b8235614fcd81615b4e565b91506020830135614fdd81615b4e565b809150509250929050565b60008060008060608587031215614ffe57600080fd5b843561500981615b4e565b93506020850135925060408501356001600160401b038082111561502c57600080fd5b818701915087601f83011261504057600080fd5b81358181111561504f57600080fd5b88602082850101111561506157600080fd5b95989497505060200194505050565b60006040828403121561508257600080fd5b610fb98383614da9565b6000806060838503121561509f57600080fd5b6150a98484614da9565b91506150b760408401614f50565b90509250929050565b6000604082840312156150d257600080fd5b610fb98383614dba565b6000602082840312156150ee57600080fd5b8151610fb981615b63565b60006020828403121561510b57600080fd5b5035919050565b60006020828403121561512457600080fd5b5051919050565b60006020828403121561513d57600080fd5b604051602081018181106001600160401b038211171561515f5761515f615b38565b604052823561516d81615b63565b81529392505050565b60008060008385036101e081121561518d57600080fd5b6101a08082121561519d57600080fd5b6151a56158a1565b91506151b18787614dba565b82526151c08760408801614dba565b60208301526080860135604083015260a0860135606083015260c086013560808301526151ef60e08701614d9e565b60a083015261010061520388828901614dba565b60c0840152615216886101408901614dba565b60e0840152610180870135908301529093508401356001600160401b0381111561523f57600080fd5b61524b86828701614e3c565b92505061525b6101c08501614e31565b90509250925092565b60006020828403121561527657600080fd5b81356001600160401b0381111561528c57600080fd5b820160c08185031215610fb957600080fd5b6000602082840312156152b057600080fd5b610fb982614f2a565b60008060008060008060008060006101208a8c0312156152d857600080fd5b6152e18a614f2a565b98506152ef60208b01614f3c565b97506152fd60408b01614f3c565b965061530b60608b01614f3c565b955060808a0135945061532060a08b01614f3c565b935061532e60c08b01614f3c565b925061533c60e08b01614f67565b915061534b6101008b01614f67565b90509295985092959850929598565b6000806040838503121561536d57600080fd5b823591506020830135614fdd81615b4e565b6000806040838503121561539257600080fd5b50508035926020909101359150565b6000602082840312156153b357600080fd5b610fb982614f3c565b600080600080600060a086880312156153d457600080fd5b6153dd86614f78565b945060208601519350604086015192506060860151915061540060808701614f78565b90509295509295909350565b600081518084526020808501945080840160005b838110156154455781516001600160a01b031687529582019590820190600101615420565b509495945050505050565b8060005b6002811015612ae0578151845260209384019390910190600101615454565b600081518084526020808501945080840160005b8381101561544557815187529582019590820190600101615487565b600081518084526154bb816020860160208601615a5e565b601f01601f19169290920160200192915050565b6154d98183615450565b604001919050565b600083516154f3818460208801615a5e565b835190830190615507818360208801615a5e565b01949350505050565b8681526155206020820187615450565b61552d6060820186615450565b61553a60a0820185615450565b61554760e0820184615450565b60609190911b6001600160601b0319166101208201526101340195945050505050565b83815261557a6020820184615450565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b604081016125888284615450565b602081526000610fb96020830184615473565b9182526001600160401b0316602082015260400190565b602081526000610fb960208301846154a3565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261568460e084018261540c565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b9182526001600160a01b0316602082015260400190565b82815260608101610fb96020830184615450565b82815260406020820152600061341a6040830184615473565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261478a60c08301846154a3565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ecc908301846154a3565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ecc908301846154a3565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a0608082018190526000906158219083018461540c565b979650505050505050565b6000808335601e1984360301811261584357600080fd5b8301803591506001600160401b0382111561585d57600080fd5b60200191503681900382131561587257600080fd5b9250929050565b60405160c081016001600160401b038111828210171561589b5761589b615b38565b60405290565b60405161012081016001600160401b038111828210171561589b5761589b615b38565b604051601f8201601f191681016001600160401b03811182821017156158ec576158ec615b38565b604052919050565b6000808585111561590457600080fd5b8386111561591157600080fd5b5050820193919092039150565b6000821982111561593157615931615ae0565b500190565b60006001600160401b0380831681851680830382111561550757615507615ae0565b600060ff821660ff84168060ff0382111561597557615975615ae0565b019392505050565b60006001600160601b0382811684821680830382111561550757615507615ae0565b6000826159ae576159ae615af6565b500490565b60008160001904831182151516156159cd576159cd615ae0565b500290565b6000828210156159e4576159e4615ae0565b500390565b600063ffffffff83811690831681811015615a0657615a06615ae0565b039392505050565b60006001600160601b0383811690831681811015615a0657615a06615ae0565b6001600160e01b03198135818116916004851015615a565780818660040360031b1b83161692505b505092915050565b60005b83811015615a79578181015183820152602001615a61565b83811115612ae05750506000910152565b6000600019821415615a9e57615a9e615ae0565b5060010190565b60006001600160401b0380831681811415615ac257615ac2615ae0565b6001019392505050565b600082615adb57615adb615af6565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a5957600080fd5b8015158114610a5957600080fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"want\",\"type\":\"uint256\"}],\"name\":\"InsufficientGasForConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2_5.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162005db538038062005db5833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615bda620001db6000396000818161055001526131fb0152615bda6000f3fe60806040526004361061021c5760003560e01c80638402595e11610124578063b2a7cac5116100a6578063b2a7cac514610732578063bec4c08c14610752578063caf70c4a14610772578063cb63179714610792578063d98e620e146107b2578063da2f2610146107d2578063dac83d2914610831578063dc311dd314610851578063e72f6e3014610882578063ee9d2d38146108a2578063f2fde38b146108cf57600080fd5b80638402595e146105c757806386fe91c7146105e75780638da5cb5b1461060757806395b55cfc146106255780639b1c385e146106385780639d40a6fd14610658578063a21a23e414610690578063a4c0ed36146106a5578063a63e0bfb146106c5578063aa433aff146106e5578063aefb212f1461070557600080fd5b8063405b84fa116101ad578063405b84fa1461044e57806340d6bb821461046e57806341af6c871461049957806351cff8d9146104c95780635d06b4ab146104e957806364d51a2a14610509578063659827441461051e578063689c45171461053e57806372e9d5651461057257806379ba5097146105925780637a5a2aef146105a757600080fd5b806304104edb14610221578063043bd6ae14610243578063088070f51461026c57806308821d581461033a5780630ae095401461035a57806315c48b841461037a57806318e3dd27146103a25780631b6b6d23146103e15780632f622e6b1461040e578063301f42e91461042e575b600080fd5b34801561022d57600080fd5b5061024161023c366004614fa6565b6108ef565b005b34801561024f57600080fd5b5061025960105481565b6040519081526020015b60405180910390f35b34801561027857600080fd5b50600c546102dd9061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610263565b34801561034657600080fd5b50610241610355366004615084565b610a5c565b34801561036657600080fd5b5061024161037536600461536e565b610c06565b34801561038657600080fd5b5061038f60c881565b60405161ffff9091168152602001610263565b3480156103ae57600080fd5b50600a546103c990600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610263565b3480156103ed57600080fd5b50600254610401906001600160a01b031681565b604051610263919061559f565b34801561041a57600080fd5b50610241610429366004614fa6565b610c4e565b34801561043a57600080fd5b506103c961044936600461518a565b610d9a565b34801561045a57600080fd5b5061024161046936600461536e565b610fd4565b34801561047a57600080fd5b506104846101f481565b60405163ffffffff9091168152602001610263565b3480156104a557600080fd5b506104b96104b436600461510d565b611386565b6040519015158152602001610263565b3480156104d557600080fd5b506102416104e4366004614fa6565b611496565b3480156104f557600080fd5b50610241610504366004614fa6565b611624565b34801561051557600080fd5b5061038f606481565b34801561052a57600080fd5b50610241610539366004614fc3565b6116db565b34801561054a57600080fd5b506104017f000000000000000000000000000000000000000000000000000000000000000081565b34801561057e57600080fd5b50600354610401906001600160a01b031681565b34801561059e57600080fd5b5061024161173b565b3480156105b357600080fd5b506102416105c23660046150a0565b6117e5565b3480156105d357600080fd5b506102416105e2366004614fa6565b611915565b3480156105f357600080fd5b50600a546103c9906001600160601b031681565b34801561061357600080fd5b506000546001600160a01b0316610401565b61024161063336600461510d565b611a27565b34801561064457600080fd5b50610259610653366004615278565b611b4b565b34801561066457600080fd5b50600754610678906001600160401b031681565b6040516001600160401b039091168152602001610263565b34801561069c57600080fd5b50610259611e8c565b3480156106b157600080fd5b506102416106c0366004614ffc565b61205f565b3480156106d157600080fd5b506102416106e03660046152cd565b6121db565b3480156106f157600080fd5b5061024161070036600461510d565b612458565b34801561071157600080fd5b50610725610720366004615393565b6124a0565b6040516102639190615616565b34801561073e57600080fd5b5061024161074d36600461510d565b6125a2565b34801561075e57600080fd5b5061024161076d36600461536e565b612697565b34801561077e57600080fd5b5061025961078d3660046150d4565b6127a3565b34801561079e57600080fd5b506102416107ad36600461536e565b6127d3565b3480156107be57600080fd5b506102596107cd36600461510d565b612a42565b3480156107de57600080fd5b506108126107ed36600461510d565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b03909116602083015201610263565b34801561083d57600080fd5b5061024161084c36600461536e565b612a63565b34801561085d57600080fd5b5061087161086c36600461510d565b612afa565b6040516102639594939291906157eb565b34801561088e57600080fd5b5061024161089d366004614fa6565b612be8565b3480156108ae57600080fd5b506102596108bd36600461510d565b600f6020526000908152604090205481565b3480156108db57600080fd5b506102416108ea366004614fa6565b612dbb565b6108f7612dcc565b60115460005b81811015610a3457826001600160a01b03166011828154811061092257610922615b36565b6000918252602090912001546001600160a01b03161415610a2457601161094a6001846159e6565b8154811061095a5761095a615b36565b600091825260209091200154601180546001600160a01b03909216918390811061098657610986615b36565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060118054806109c5576109c5615b20565b600082815260209020810160001990810180546001600160a01b03191690550190556040517ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3790610a1790859061559f565b60405180910390a1505050565b610a2d81615a9e565b90506108fd565b5081604051635428d44960e01b8152600401610a50919061559f565b60405180910390fd5b50565b610a64612dcc565b604080518082018252600091610a939190849060029083908390808284376000920191909152506127a3915050565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b03169183019190915291925090610af157604051631dfd6e1360e21b815260048101839052602401610a50565b6000828152600d6020526040812080546001600160481b0319169055600e54905b81811015610bc25783600e8281548110610b2e57610b2e615b36565b90600052602060002001541415610bb257600e610b4c6001846159e6565b81548110610b5c57610b5c615b36565b9060005260206000200154600e8281548110610b7a57610b7a615b36565b600091825260209091200155600e805480610b9757610b97615b20565b60019003818190600052602060002001600090559055610bc2565b610bbb81615a9e565b9050610b12565b507f9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5838360200151604051610bf8929190615629565b60405180910390a150505050565b81610c1081612e21565b610c18612e82565b610c2183611386565b15610c3f57604051631685ecdd60e31b815260040160405180910390fd5b610c498383612ead565b505050565b610c56612e82565b610c5e612dcc565b600b54600160601b90046001600160601b0316610c8e57604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c610cb18380615a22565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610cf99190615a22565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610d73576040519150601f19603f3d011682016040523d82523d6000602084013e610d78565b606091505b5050905080610c495760405163950b247960e01b815260040160405180910390fd5b6000610da4612e82565b60005a90506000610db58686613061565b90506000610dcb8583600001516020015161331d565b60408301516060888101519293509163ffffffff16806001600160401b03811115610df857610df8615b4c565b604051908082528060200260200182016040528015610e21578160200160208202803683370190505b50925060005b81811015610e895760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c848281518110610e6e57610e6e615b36565b6020908102919091010152610e8281615a9e565b9050610e27565b5050602080850180516000908152600f9092526040822082905551610eaf908a8561336b565b60208a8101516000908152600690915260409020805491925090601890610ee590600160c01b90046001600160401b0316615ab9565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555060008960a0015160018b60a0015151610f2291906159e6565b81518110610f3257610f32615b36565b60209101015160f81c6001149050610f4c8786838c613406565b9750610f5d88828c60200151613436565b6020808b015187820151604080518781526001600160601b038d16948101949094528415159084015284151560608401528b1515608084015290917faeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b79060a00160405180910390a3505050505050505b9392505050565b610fdc612e82565b610fe581613589565b6110045780604051635428d44960e01b8152600401610a50919061559f565b60008060008061101386612afa565b945094505093509350336001600160a01b0316826001600160a01b0316146110765760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610a50565b61107f86611386565b156110c55760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610a50565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a08301529151909160009161111a91849101615653565b6040516020818303038152906040529050611134886135f5565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b0388169061116d908590600401615640565b6000604051808303818588803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506111c3905057506001600160601b03861615155b1561128d5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906111fa908a908a906004016155e6565b602060405180830381600087803b15801561121457600080fd5b505af1158015611228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124c91906150f0565b61128d5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a50565b600c805460ff60301b1916600160301b17905560005b8351811015611334578381815181106112be576112be615b36565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016112f1919061559f565b600060405180830381600087803b15801561130b57600080fd5b505af115801561131f573d6000803e3d6000fd5b505050508061132d90615a9e565b90506112a3565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906113749089908b906155b3565b60405180910390a15050505050505050565b60008181526005602052604081206002018054806113a8575060009392505050565b600e5460005b8281101561148a5760008482815481106113ca576113ca615b36565b60009182526020822001546001600160a01b031691505b8381101561147757600061143f600e838154811061140157611401615b36565b60009182526020808320909101546001600160a01b03871683526004825260408084208e855290925291205485908c906001600160401b031661379d565b506000818152600f6020526040902054909150156114665750600198975050505050505050565b5061147081615a9e565b90506113e1565b50508061148390615a9e565b90506113ae565b50600095945050505050565b61149e612e82565b6114a6612dcc565b6002546001600160a01b03166114cf5760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166114f857604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006115148380615a22565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b031661155c9190615a22565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906115b190859085906004016155e6565b602060405180830381600087803b1580156115cb57600080fd5b505af11580156115df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160391906150f0565b61162057604051631e9acf1760e31b815260040160405180910390fd5b5050565b61162c612dcc565b61163581613589565b15611655578060405163ac8a27ef60e01b8152600401610a50919061559f565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625906116d090839061559f565b60405180910390a150565b6116e3612dcc565b6002546001600160a01b03161561170d57604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b0316331461178e5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610a50565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6117ed612dcc565b60408051808201825260009161181c9190859060029083908390808284376000920191909152506127a3915050565b6000818152600d602052604090205490915060ff161561185257604051634a0b8fa760e01b815260048101829052602401610a50565b60408051808201825260018082526001600160401b0385811660208085019182526000878152600d9091528581209451855492516001600160481b031990931690151568ffffffffffffffff00191617610100929093169190910291909117909255600e805491820181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01829055517f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd390610a179083908590615629565b61191d612dcc565b600a544790600160601b90046001600160601b03168181111561195d576040516354ced18160e11b81526004810182905260248101839052604401610a50565b81811015610c4957600061197182846159e6565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d80600081146119c0576040519150601f19603f3d011682016040523d82523d6000602084013e6119c5565b606091505b50509050806119e75760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611a189291906155b3565b60405180910390a15050505050565b611a2f612e82565b6000818152600560205260409020546001600160a01b0316611a6457604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611a938385615991565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611adb9190615991565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611b2e9190615932565b604080519283526020830191909152015b60405180910390a25050565b6000611b55612e82565b602080830135600081815260059092526040909120546001600160a01b0316611b9157604051630fb532db60e11b815260040160405180910390fd5b33600090815260046020908152604080832084845291829052909120546001600160401b031680611bd95782336040516379bfd40160e01b8152600401610a509291906156c8565b600c5461ffff16611bf060608701604088016152b2565b61ffff161080611c13575060c8611c0d60608701604088016152b2565b61ffff16115b15611c5957611c2860608601604087016152b2565b600c5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610a50565b600c5462010000900463ffffffff16611c7860808701606088016153b5565b63ffffffff161115611cc857611c9460808601606087016153b5565b600c54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610a50565b6101f4611cdb60a08701608088016153b5565b63ffffffff161115611d2157611cf760a08601608087016153b5565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610a50565b611d2a81615ab9565b90506000611d3b863533868561379d565b90955090506000611d5f611d5a611d5560a08a018a615840565b613816565b613893565b905085611d6a613904565b86611d7b60808b0160608c016153b5565b611d8b60a08c0160808d016153b5565b3386604051602001611da3979695949392919061574b565b60405160208183030381529060405280519060200120600f600088815260200190815260200160002081905550336001600160a01b03168588600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e89868c6040016020810190611e1691906152b2565b8d6060016020810190611e2991906153b5565b8e6080016020810190611e3c91906153b5565b89604051611e4f9695949392919061570c565b60405180910390a450506000928352602091909152604090912080546001600160401b0319166001600160401b039092169190911790555b919050565b6000611e96612e82565b6007546001600160401b031633611eae6001436159e6565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611f1381600161594a565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b0392831617835593516001830180549095169116179092559251805192949391926120119260028501920190614cc0565b5061202191506008905084613994565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d33604051612052919061559f565b60405180910390a2505090565b612067612e82565b6002546001600160a01b03163314612092576040516344b0e3c360e01b815260040160405180910390fd5b602081146120b357604051638129bbcd60e01b815260040160405180910390fd5b60006120c18284018461510d565b6000818152600560205260409020549091506001600160a01b03166120f957604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906121208385615991565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166121689190615991565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846121bb9190615932565b6040805192835260208301919091520160405180910390a2505050505050565b6121e3612dcc565b60c861ffff8a16111561221d5760405163539c34bb60e11b815261ffff8a1660048201819052602482015260c86044820152606401610a50565b60008513612241576040516321ea67b360e11b815260048101869052602401610a50565b60008463ffffffff1611801561226357508363ffffffff168363ffffffff1610155b15612291576040516313c06e5960e11b815263ffffffff808516600483015285166024820152604401610a50565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b9099029890981667ffffffffffffffff60781b19600160581b90960263ffffffff60581b19600160381b9098029790971668ffffffffffffffffff60301b196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b690612445908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b612460612dcc565b6000818152600560205260409020546001600160a01b03168061249657604051630fb532db60e11b815260040160405180910390fd5b6116208282612ead565b606060006124ae60086139a0565b90508084106124d057604051631390f2a160e01b815260040160405180910390fd5b60006124dc8486615932565b9050818111806124ea575083155b6124f457806124f6565b815b9050600061250486836159e6565b9050806001600160401b0381111561251e5761251e615b4c565b604051908082528060200260200182016040528015612547578160200160208202803683370190505b50935060005b818110156125975761256a6125628883615932565b6008906139aa565b85828151811061257c5761257c615b36565b602090810291909101015261259081615a9e565b905061254d565b505050505b92915050565b6125aa612e82565b6000818152600560205260409020546001600160a01b0316806125e057604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b03163314612637576000828152600560205260409081902060010154905163d084e97560e01b8152610a50916001600160a01b03169060040161559f565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611b3f9185916155cc565b816126a181612e21565b6126a9612e82565b60008381526005602052604090206002018054606414156126dd576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b038316600090815260046020908152604080832087845291829052909120546001600160401b031615612718575050505050565b600085815260208281526040808320805460016001600160401b0319909116811790915585549081018655858452919092200180546001600160a01b0319166001600160a01b0387161790555185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061279490879061559f565b60405180910390a25050505050565b6000816040516020016127b69190615608565b604051602081830303815290604052805190602001209050919050565b816127dd81612e21565b6127e5612e82565b6127ee83611386565b1561280c57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03821660009081526004602090815260408083208684529091529020546001600160401b031661285a5782826040516379bfd40160e01b8152600401610a509291906156c8565b6000838152600560209081526040808320600201805482518185028101850190935280835291929091908301828280156128bd57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161289f575b505050505090506000600182516128d491906159e6565b905060005b82518110156129de57846001600160a01b03168382815181106128fe576128fe615b36565b60200260200101516001600160a01b031614156129ce57600083838151811061292957612929615b36565b602002602001015190508060056000898152602001908152602001600020600201838154811061295b5761295b615b36565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558881526005909152604090206002018054806129a6576129a6615b20565b600082815260209020810160001990810180546001600160a01b0319169055019055506129de565b6129d781615a9e565b90506128d9565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160401b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79061279490879061559f565b600e8181548110612a5257600080fd5b600091825260209091200154905081565b81612a6d81612e21565b612a75612e82565b600083815260056020526040902060018101546001600160a01b03848116911614612af4576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612aeb90339087906155cc565b60405180910390a25b50505050565b600081815260056020526040812054819081906001600160a01b0316606081612b3657604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612bce57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612bb0575b505050505090509450945094509450945091939590929450565b612bf0612dcc565b6002546001600160a01b0316612c195760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612c4a90309060040161559f565b60206040518083038186803b158015612c6257600080fd5b505afa158015612c76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9a9190615126565b600a549091506001600160601b031681811115612cd4576040516354ced18160e11b81526004810182905260248101839052604401610a50565b81811015610c49576000612ce882846159e6565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612d1b90879085906004016155b3565b602060405180830381600087803b158015612d3557600080fd5b505af1158015612d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6d91906150f0565b612d8a57604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366008482604051610bf89291906155b3565b612dc3612dcc565b610a59816139b6565b6000546001600160a01b03163314612e1f5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610a50565b565b6000818152600560205260409020546001600160a01b031680612e5757604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146116205780604051636c51fda960e11b8152600401610a50919061559f565b600c54600160301b900460ff1615612e1f5760405163769dd35360e11b815260040160405180910390fd5b600080612eb9846135f5565b60025491935091506001600160a01b031615801590612ee057506001600160601b03821615155b15612f8f5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90612f209086906001600160601b038716906004016155b3565b602060405180830381600087803b158015612f3a57600080fd5b505af1158015612f4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7291906150f0565b612f8f57604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114612fe5576040519150601f19603f3d011682016040523d82523d6000602084013e612fea565b606091505b505090508061300c5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c490606001612794565b6040805160a0810182526000606082018181526080830182905282526020820181905291810191909152600061309a84600001516127a3565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b031691830191909152919250906130f857604051631dfd6e1360e21b815260048101839052602401610a50565b600082866080015160405160200161311a929190918252602082015260400190565b60408051601f1981840301815291815281516020928301206000818152600f9093529120549091508061316057604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d0151935161318f978a979096959101615797565b6040516020818303038152906040528051906020012081146131c45760405163354a450b60e21b815260040160405180910390fd5b60006131d38760000151613a5a565b9050806132ab578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561324557600080fd5b505afa158015613259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061327d9190615126565b9050806132ab57865160405163175dadad60e01b81526001600160401b039091166004820152602401610a50565b60008860800151826040516020016132cd929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006132f48a83613b3c565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a111561336357821561334657506001600160401b03811661259c565b3a8260405163435e532d60e11b8152600401610a50929190615629565b503a92915050565b6000806000631fe543e360e01b868560405160240161338b9291906156f3565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559086015160808701519192506133ef9163ffffffff9091169083613ba7565b600c805460ff60301b191690559695505050505050565b6000821561342057613419858584613bf3565b905061342e565b61342b858584613d04565b90505b949350505050565b600081815260066020526040902082156134f55780546001600160601b03600160601b909104811690851681101561348157604051631e9acf1760e31b815260040160405180910390fd5b61348b8582615a22565b8254600160601b600160c01b031916600160601b6001600160601b039283168102919091178455600b805488939192600c926134cb928692900416615991565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050612af4565b80546001600160601b0390811690851681101561352557604051631e9acf1760e31b815260040160405180910390fd5b61352f8582615a22565b82546001600160601b0319166001600160601b03918216178355600b8054879260009161355e91859116615991565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050505050565b601154600090815b818110156135eb57836001600160a01b0316601182815481106135b6576135b6615b36565b6000918252602090912001546001600160a01b031614156135db575060019392505050565b6135e481615a9e565b9050613591565b5060009392505050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b81811015613697576004600084838154811061364a5761364a615b36565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160401b031916905561369081615a9e565b905061362c565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906136cf6002830182614d25565b50506000858152600660205260408120556136eb600886613eed565b506001600160601b0384161561373e57600a80548591906000906137199084906001600160601b0316615a22565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156137965782600a600c8282829054906101000a90046001600160601b03166137719190615a22565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b6040805160208082018790526001600160a01b03959095168183015260608101939093526001600160401b03919091166080808401919091528151808403909101815260a08301825280519084012060c083019490945260e0808301859052815180840390910181526101009092019052805191012091565b6040805160208101909152600081528161383f575060408051602081019091526000815261259c565b63125fa26760e31b6138518385615a42565b6001600160e01b0319161461387957604051632923fee760e11b815260040160405180910390fd5b6138868260048186615908565b810190610fcd919061513f565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016138cc91511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661391081613ef9565b1561398d5760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561394f57600080fd5b505afa158015613963573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139879190615126565b91505090565b4391505090565b6000610fcd8383613f1c565b600061259c825490565b6000610fcd8383613f6b565b6001600160a01b038116331415613a095760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610a50565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613a6681613ef9565b15613b2d57610100836001600160401b0316613a80613904565b613a8a91906159e6565b1180613aa65750613a99613904565b836001600160401b031610155b15613ab45750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a82906024015b60206040518083038186803b158015613af557600080fd5b505afa158015613b09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcd9190615126565b50506001600160401b03164090565b6000613b708360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f95565b60038360200151604051602001613b889291906156df565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613bb957600080fd5b611388810390508460408204820311613bd157600080fd5b50823b613bdd57600080fd5b60008083516020850160008789f1949350505050565b600080613c366000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506141b192505050565b905060005a600c54613c56908890600160581b900463ffffffff16615932565b613c6091906159e6565b613c6a90866159c7565b600c54909150600090613c8f90600160781b900463ffffffff1664e8d4a510006159c7565b90508415613cdb57600c548190606490600160b81b900460ff16613cb38587615932565b613cbd91906159c7565b613cc791906159b3565b613cd19190615932565b9350505050610fcd565b600c548190606490613cf790600160b81b900460ff168261596c565b60ff16613cb38587615932565b600080613d0f61427f565b905060008113613d35576040516321ea67b360e11b815260048101829052602401610a50565b6000613d776000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506141b192505050565b9050600082825a600c54613d99908b90600160581b900463ffffffff16615932565b613da391906159e6565b613dad90896159c7565b613db79190615932565b613dc990670de0b6b3a76400006159c7565b613dd391906159b3565b600c54909150600090613dfc9063ffffffff600160981b8204811691600160781b9004166159fd565b613e119063ffffffff1664e8d4a510006159c7565b9050600084613e2883670de0b6b3a76400006159c7565b613e3291906159b3565b905060008715613e7357600c548290606490613e5890600160c01b900460ff16876159c7565b613e6291906159b3565b613e6c9190615932565b9050613eb3565b600c548290606490613e8f90600160c01b900460ff168261596c565b613e9c9060ff16876159c7565b613ea691906159b3565b613eb09190615932565b90505b6b033b2e3c9fd0803ce8000000811115613ee05760405163e80fa38160e01b815260040160405180910390fd5b9998505050505050505050565b6000610fcd838361434e565b600061a4b1821480613f0d575062066eed82145b8061259c57505062066eee1490565b6000818152600183016020526040812054613f635750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561259c565b50600061259c565b6000826000018281548110613f8257613f82615b36565b9060005260206000200154905092915050565b613f9e89614441565b613fe75760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610a50565b613ff088614441565b6140345760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610a50565b61403d83614441565b6140895760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610a50565b61409282614441565b6140de5760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610a50565b6140ea878a8887614504565b6141325760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610a50565b600061413e8a87614627565b90506000614151898b878b86898961468b565b90506000614162838d8d8a866147aa565b9050808a146141a35760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610a50565b505050505050505050505050565b6000466141bd81613ef9565b156141fc57606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613af557600080fd5b614205816147ea565b1561427657600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615b866048913960405160200161424b9291906154f5565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613add9190615640565b50600092915050565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169284926001600160a01b039091169163feaf968c9160048082019260a092909190829003018186803b1580156142da57600080fd5b505afa1580156142ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061431291906153d0565b50919550909250505063ffffffff82161580159061433e575061433581426159e6565b8263ffffffff16105b156143495760105492505b505090565b600081815260018301602052604081205480156144375760006143726001836159e6565b8554909150600090614386906001906159e6565b90508181146143eb5760008660000182815481106143a6576143a6615b36565b90600052602060002001549050808760000184815481106143c9576143c9615b36565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806143fc576143fc615b20565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061259c565b600091505061259c565b80516000906401000003d0191161448f5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610a50565b60208201516401000003d019116144dd5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610a50565b60208201516401000003d0199080096144fd8360005b6020020151614824565b1492915050565b60006001600160a01b03821661454a5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610a50565b60208401516000906001161561456157601c614564565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa1580156145ff573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b61462f614d43565b61465c600184846040516020016146489392919061557e565b604051602081830303815290604052614848565b90505b61466881614441565b61259c5780516040805160208101929092526146849101614648565b905061465f565b614693614d43565b825186516401000003d01990819006910614156146f25760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610a50565b6146fd878988614896565b6147425760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610a50565b61474d848685614896565b6147935760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610a50565b61479e8684846149be565b98975050505050505050565b6000600286868685876040516020016147c896959493929190615524565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a8214806147fc57506101a482145b80614809575062aa37dc82145b80614815575061210582145b8061259c57505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614850614d43565b61485982614a81565b815261486e6148698260006144f3565b614abc565b602082018190526002900660011415611e87576020810180516401000003d019039052919050565b6000826148d35760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610a50565b835160208501516000906148e990600290615ae0565b156148f557601c6148f8565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa15801561496a573d6000803e3d6000fd5b50505060206040510351905060008660405160200161498991906154e3565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b6149c6614d43565b8351602080860151855191860151600093849384936149e793909190614adc565b919450925090506401000003d019858209600114614a435760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610a50565b60405180604001604052806401000003d01980614a6257614a62615b0a565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611e8757604080516020808201939093528151808203840181529082019091528051910120614a89565b600061259c826002614ad56401000003d0196001615932565b901c614bbc565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614b1c83838585614c53565b9098509050614b2d88828e88614c77565b9098509050614b3e88828c87614c77565b90985090506000614b518d878b85614c77565b9098509050614b6288828686614c53565b9098509050614b7388828e89614c77565b9098509050818114614ba8576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614bac565b8196505b5050505050509450945094915050565b600080614bc7614d61565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614bf9614d7f565b60208160c0846005600019fa925082614c495760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610a50565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614d15579160200282015b82811115614d1557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614ce0565b50614d21929150614d9d565b5090565b5080546000825590600052602060002090810190610a599190614d9d565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614d215760008155600101614d9e565b8035611e8781615b62565b806040810183101561259c57600080fd5b600082601f830112614ddf57600080fd5b604051604081018181106001600160401b0382111715614e0157614e01615b4c565b8060405250808385604086011115614e1857600080fd5b60005b6002811015614e3a578135835260209283019290910190600101614e1b565b509195945050505050565b8035611e8781615b77565b600060c08284031215614e6257600080fd5b614e6a61588d565b9050614e7582614f64565b815260208083013581830152614e8d60408401614f50565b6040830152614e9e60608401614f50565b60608301526080830135614eb181615b62565b608083015260a08301356001600160401b0380821115614ed057600080fd5b818501915085601f830112614ee457600080fd5b813581811115614ef657614ef6615b4c565b614f08601f8201601f191685016158d8565b91508082528684828501011115614f1e57600080fd5b80848401858401376000848284010152508060a085015250505092915050565b803561ffff81168114611e8757600080fd5b803563ffffffff81168114611e8757600080fd5b80356001600160401b0381168114611e8757600080fd5b803560ff81168114611e8757600080fd5b805169ffffffffffffffffffff81168114611e8757600080fd5b600060208284031215614fb857600080fd5b8135610fcd81615b62565b60008060408385031215614fd657600080fd5b8235614fe181615b62565b91506020830135614ff181615b62565b809150509250929050565b6000806000806060858703121561501257600080fd5b843561501d81615b62565b93506020850135925060408501356001600160401b038082111561504057600080fd5b818701915087601f83011261505457600080fd5b81358181111561506357600080fd5b88602082850101111561507557600080fd5b95989497505060200194505050565b60006040828403121561509657600080fd5b610fcd8383614dbd565b600080606083850312156150b357600080fd5b6150bd8484614dbd565b91506150cb60408401614f64565b90509250929050565b6000604082840312156150e657600080fd5b610fcd8383614dce565b60006020828403121561510257600080fd5b8151610fcd81615b77565b60006020828403121561511f57600080fd5b5035919050565b60006020828403121561513857600080fd5b5051919050565b60006020828403121561515157600080fd5b604051602081018181106001600160401b038211171561517357615173615b4c565b604052823561518181615b77565b81529392505050565b60008060008385036101e08112156151a157600080fd5b6101a0808212156151b157600080fd5b6151b96158b5565b91506151c58787614dce565b82526151d48760408801614dce565b60208301526080860135604083015260a0860135606083015260c0860135608083015261520360e08701614db2565b60a083015261010061521788828901614dce565b60c084015261522a886101408901614dce565b60e0840152610180870135908301529093508401356001600160401b0381111561525357600080fd5b61525f86828701614e50565b92505061526f6101c08501614e45565b90509250925092565b60006020828403121561528a57600080fd5b81356001600160401b038111156152a057600080fd5b820160c08185031215610fcd57600080fd5b6000602082840312156152c457600080fd5b610fcd82614f3e565b60008060008060008060008060006101208a8c0312156152ec57600080fd5b6152f58a614f3e565b985061530360208b01614f50565b975061531160408b01614f50565b965061531f60608b01614f50565b955060808a0135945061533460a08b01614f50565b935061534260c08b01614f50565b925061535060e08b01614f7b565b915061535f6101008b01614f7b565b90509295985092959850929598565b6000806040838503121561538157600080fd5b823591506020830135614ff181615b62565b600080604083850312156153a657600080fd5b50508035926020909101359150565b6000602082840312156153c757600080fd5b610fcd82614f50565b600080600080600060a086880312156153e857600080fd5b6153f186614f8c565b945060208601519350604086015192506060860151915061541460808701614f8c565b90509295509295909350565b600081518084526020808501945080840160005b838110156154595781516001600160a01b031687529582019590820190600101615434565b509495945050505050565b8060005b6002811015612af4578151845260209384019390910190600101615468565b600081518084526020808501945080840160005b838110156154595781518752958201959082019060010161549b565b600081518084526154cf816020860160208601615a72565b601f01601f19169290920160200192915050565b6154ed8183615464565b604001919050565b60008351615507818460208801615a72565b83519083019061551b818360208801615a72565b01949350505050565b8681526155346020820187615464565b6155416060820186615464565b61554e60a0820185615464565b61555b60e0820184615464565b60609190911b6001600160601b0319166101208201526101340195945050505050565b83815261558e6020820184615464565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6040810161259c8284615464565b602081526000610fcd6020830184615487565b9182526001600160401b0316602082015260400190565b602081526000610fcd60208301846154b7565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261569860e0840182615420565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b9182526001600160a01b0316602082015260400190565b82815260608101610fcd6020830184615464565b82815260406020820152600061342e6040830184615487565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261479e60c08301846154b7565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ee0908301846154b7565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613ee0908301846154b7565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a06080820181905260009061583590830184615420565b979650505050505050565b6000808335601e1984360301811261585757600080fd5b8301803591506001600160401b0382111561587157600080fd5b60200191503681900382131561588657600080fd5b9250929050565b60405160c081016001600160401b03811182821017156158af576158af615b4c565b60405290565b60405161012081016001600160401b03811182821017156158af576158af615b4c565b604051601f8201601f191681016001600160401b038111828210171561590057615900615b4c565b604052919050565b6000808585111561591857600080fd5b8386111561592557600080fd5b5050820193919092039150565b6000821982111561594557615945615af4565b500190565b60006001600160401b0380831681851680830382111561551b5761551b615af4565b600060ff821660ff84168060ff0382111561598957615989615af4565b019392505050565b60006001600160601b0382811684821680830382111561551b5761551b615af4565b6000826159c2576159c2615b0a565b500490565b60008160001904831182151516156159e1576159e1615af4565b500290565b6000828210156159f8576159f8615af4565b500390565b600063ffffffff83811690831681811015615a1a57615a1a615af4565b039392505050565b60006001600160601b0383811690831681811015615a1a57615a1a615af4565b6001600160e01b03198135818116916004851015615a6a5780818660040360031b1b83161692505b505092915050565b60005b83811015615a8d578181015183820152602001615a75565b83811115612af45750506000910152565b6000600019821415615ab257615ab2615af4565b5060010190565b60006001600160401b0380831681811415615ad657615ad6615af4565b6001019392505050565b600082615aef57615aef615b0a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a5957600080fd5b8015158114610a5957600080fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000806000a", } var VRFCoordinatorV25ABI = VRFCoordinatorV25MetaData.ABI @@ -2223,13 +2223,14 @@ func (it *VRFCoordinatorV25RandomWordsFulfilledIterator) Close() error { } type VRFCoordinatorV25RandomWordsFulfilled struct { - RequestId *big.Int - OutputSeed *big.Int - SubId *big.Int - Payment *big.Int - Success bool - OnlyPremium bool - Raw types.Log + RequestId *big.Int + OutputSeed *big.Int + SubId *big.Int + Payment *big.Int + NativePayment bool + Success bool + OnlyPremium bool + Raw types.Log } func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorV25RandomWordsFulfilledIterator, error) { @@ -3601,7 +3602,7 @@ func (VRFCoordinatorV25ProvingKeyRegistered) Topic() common.Hash { } func (VRFCoordinatorV25RandomWordsFulfilled) Topic() common.Hash { - return common.HexToHash("0x6c6b5394380e16e41988d8383648010de6f5c2e4814803be5de1c6b1c852db55") + return common.HexToHash("0xaeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b7") } func (VRFCoordinatorV25RandomWordsRequested) Topic() common.Hash { diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 5aae6183434..d112efac94f 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -83,7 +83,7 @@ vrf_consumer_v2_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2Up vrf_coordinator_mock: ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.bin 5c495cf8df1f46d8736b9150cdf174cce358cb8352f60f0d5bb9581e23920501 vrf_coordinator_test_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.bin eaefd785c38bac67fb11a7fc2737ab2da68c988ca170e7db8ff235c80893e01c vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.bin 295f35ce282060317dfd01f45959f5a2b05ba26913e422fbd4fb6bf90b107006 -vrf_coordinator_v2_5: ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.bin aa5875f42461b4f128483ee0fd8b1f1b72a395ee857e6153197e92bcb21d149f +vrf_coordinator_v2_5: ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5/VRFCoordinatorV2_5.bin 3230631b7920236588ccd4ad8795e52ede6222cac7a70fa477c7240da0955a5e vrf_coordinator_v2_plus_v2_example: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example/VRFCoordinatorV2Plus_V2Example.bin 4a5b86701983b1b65f0a8dfa116b3f6d75f8f706fa274004b57bdf5992e4cec3 vrf_coordinator_v2plus_interface: ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal/IVRFCoordinatorV2PlusInternal.abi ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal/IVRFCoordinatorV2PlusInternal.bin 86b8e23aab28c5b98e3d2384dc4f702b093e382dc985c88101278e6e4bf6f7b8 vrf_external_sub_owner_example: ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample/VRFExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample/VRFExternalSubOwnerExample.bin 14f888eb313930b50233a6f01ea31eba0206b7f41a41f6311670da8bb8a26963 diff --git a/core/services/vrf/v2/coordinator_v2x_interface.go b/core/services/vrf/v2/coordinator_v2x_interface.go index 21622c2cb18..05a9e5d8918 100644 --- a/core/services/vrf/v2/coordinator_v2x_interface.go +++ b/core/services/vrf/v2/coordinator_v2x_interface.go @@ -726,6 +726,10 @@ func (rwf *v2_5RandomWordsFulfilled) Raw() types.Log { return rwf.event.Raw } +func (rwf *v2_5RandomWordsFulfilled) NativePayment() bool { + return rwf.event.NativePayment +} + var ( _ SubscriptionCreatedIterator = (*v2SubscriptionCreatedIterator)(nil) _ SubscriptionCreatedIterator = (*v2_5SubscriptionCreatedIterator)(nil) From 298e4178454f7f4f1d76a119b9b18883e81dc05f Mon Sep 17 00:00:00 2001 From: Aaron Lu <50029043+aalu1418@users.noreply.github.com> Date: Tue, 20 Feb 2024 06:16:08 -0700 Subject: [PATCH 55/98] bump solana + update e2e test action (#12052) * bump solana + update e2e test action * bump solana to merged commit --- .github/workflows/integration-tests.yml | 2 ++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e5610fcd8a4..f8beac21a8c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1022,6 +1022,8 @@ jobs: # Remove the created container docker rm "$CONTAINER_ID" + - name: Install Solana CLI # required for ensuring the local test validator is configured correctly + run: ./scripts/install-solana-ci.sh - name: Generate config overrides run: | # https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md cat << EOF > config.toml diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 3064d0d3ffa..854007e9b8e 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -251,7 +251,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 015ec4d6674..9d08d29f0b8 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1179,8 +1179,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5d github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= diff --git a/go.mod b/go.mod index 623ad2b6c4d..401a19c8aa7 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a diff --git a/go.sum b/go.sum index 8c83807227e..e53d5a17755 100644 --- a/go.sum +++ b/go.sum @@ -1174,8 +1174,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5d github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 63c0c15162d..73da0e26234 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -373,7 +373,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 084077d21d1..74858d24794 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1513,8 +1513,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5d github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0 h1:9IxmR+1NH1WxaX44+t553fOrrZRfxwMVvnDuBIy0tgs= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240213161921-c4d342b761b0/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-testing-framework v1.23.5 h1:bymN/mr4Tbx3DQ7EMB/z81+pCLhJkiYgxJDgAeTo9/w= From 05a05c67ac1c2d380f49a71ab0a0494085fcd019 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 20 Feb 2024 10:12:16 -0500 Subject: [PATCH 56/98] Report format => uint32 (#12096) --- .../v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol | 2 +- .../channel_config_store/channel_config_store.go | 8 ++++---- .../generated-wrapper-dependency-versions-do-not-edit.txt | 2 +- core/services/streams/stream_registry.go | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol index 97fafc2cb5c..45e3ee313d8 100644 --- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol @@ -20,7 +20,7 @@ interface IChannelConfigStore is IERC165 { struct ChannelDefinition { // e.g. evm, solana, CosmWasm, kalechain, etc... - bytes8 reportFormat; + uint32 reportFormat; // Specifies the chain on which this channel can be verified. Currently uses // CCIP chain selectors, but lots of other schemes are possible as well. uint64 chainSelector; diff --git a/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go b/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go index d6874fed1f7..3c67b642273 100644 --- a/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go +++ b/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go @@ -31,14 +31,14 @@ var ( ) type IChannelConfigStoreChannelDefinition struct { - ReportFormat [8]byte + ReportFormat uint32 ChainSelector uint64 StreamIDs []uint32 } var ChannelConfigStoreMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ChannelDefinitionNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyStreamIDs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByEOA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StagingConfigAlreadyPromoted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroReportFormat\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"ChannelDefinitionRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes8\",\"name\":\"reportFormat\",\"type\":\"bytes8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"NewChannelDefinition\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"PromoteStagingConfig\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes8\",\"name\":\"reportFormat\",\"type\":\"bytes8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"addChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"getChannelDefinitions\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes8\",\"name\":\"reportFormat\",\"type\":\"bytes8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"removeChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610f1e806101576000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80637e37e7191161005b5780637e37e719146101535780638da5cb5b14610166578063f2fde38b1461018e578063f5810719146101a157600080fd5b806301ffc9a71461008d578063181f5a77146100f757806322d9780c1461013657806379ba50971461014b575b600080fd5b6100e261009b366004610816565b7fffffffff00000000000000000000000000000000000000000000000000000000167fa96f980c000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4368616e6e656c436f6e66696753746f726520302e302e300000000000000000602082015290516100ee919061085f565b6101496101443660046108dd565b6101c1565b005b61014961032d565b610149610161366004610934565b61042f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ee565b61014961019c366004610951565b61050f565b6101b46101af366004610934565b610523565b6040516100ee9190610987565b6101c9610665565b6101d66040820182610a1f565b9050600003610211576040517f4b620e2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102216040820160208301610aa4565b67ffffffffffffffff16600003610264576040517ff89d762900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102716020820182610aef565b7fffffffffffffffff000000000000000000000000000000000000000000000000166000036102cc576040517febd3ef0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8216600090815260026020526040902081906102ed8282610ce5565b9050507fbf2cd44714205d633d3f888ac72ea66d53cd12d4c4e8723a80d9c0bc36484a548282604051610321929190610e2e565b60405180910390a15050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610437610665565b63ffffffff81166000908152600260205260408120600101549003610488576040517fd1a751e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8116600090815260026020526040812080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000168155906104d160018301826107dd565b505060405163ffffffff821681527f334e877e9691ecae0660510061973bebaa8b4fb37332ed6090052e630c9798619060200160405180910390a150565b610517610665565b610520816106e8565b50565b60408051606080820183526000808352602083015291810191909152333214610578576040517f74e2cd5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff82166000908152600260209081526040918290208251606081018452815460c081901b7fffffffffffffffff00000000000000000000000000000000000000000000000016825268010000000000000000900467ffffffffffffffff16818401526001820180548551818602810186018752818152929593949386019383018282801561065557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116106185790505b5050505050815250509050919050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103aa565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610767576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103aa565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b50805460008255600701600890049060005260206000209081019061052091905b8082111561081257600081556001016107fe565b5090565b60006020828403121561082857600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461085857600080fd5b9392505050565b600060208083528351808285015260005b8181101561088c57858101830151858201604001528201610870565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b63ffffffff8116811461052057600080fd5b600080604083850312156108f057600080fd5b82356108fb816108cb565b9150602083013567ffffffffffffffff81111561091757600080fd5b83016060818603121561092957600080fd5b809150509250929050565b60006020828403121561094657600080fd5b8135610858816108cb565b60006020828403121561096357600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461085857600080fd5b60006020808352608083017fffffffffffffffff0000000000000000000000000000000000000000000000008551168285015267ffffffffffffffff82860151166040850152604085015160608086015281815180845260a0870191508483019350600092505b80831015610a1457835163ffffffff1682529284019260019290920191908401906109ee565b509695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610a5457600080fd5b83018035915067ffffffffffffffff821115610a6f57600080fd5b6020019150600581901b3603821315610a8757600080fd5b9250929050565b67ffffffffffffffff8116811461052057600080fd5b600060208284031215610ab657600080fd5b813561085881610a8e565b7fffffffffffffffff0000000000000000000000000000000000000000000000008116811461052057600080fd5b600060208284031215610b0157600080fd5b813561085881610ac1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b68010000000000000000821115610b5457610b54610b0c565b805482825580831015610bd9576000828152602081206007850160031c81016007840160031c82019150601c8660021b168015610bc0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8083018054828460200360031b1c16815550505b505b81811015610bd557828155600101610bc2565b5050505b505050565b60008135610beb816108cb565b92915050565b67ffffffffffffffff831115610c0957610c09610b0c565b610c138382610b3b565b60008181526020902082908460031c60005b81811015610c7e576000805b6008811015610c7157610c60610c4687610bde565b63ffffffff908116600584901b90811b91901b1984161790565b602096909601959150600101610c31565b5083820155600101610c25565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88616808703818814610cdb576000805b82811015610cd557610cc4610c4688610bde565b602097909701969150600101610cb0565b50848401555b5050505050505050565b8135610cf081610ac1565b8060c01c90508154817fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000082161783556020840135610d2d81610a8e565b6fffffffffffffffff00000000000000008160401b16837fffffffffffffffffffffffffffffffff0000000000000000000000000000000084161717845550505060408201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112610da357600080fd5b8201803567ffffffffffffffff811115610dbc57600080fd5b6020820191508060051b3603821315610dd457600080fd5b610de2818360018601610bf1565b50505050565b8183526000602080850194508260005b85811015610e23578135610e0b816108cb565b63ffffffff1687529582019590820190600101610df8565b509495945050505050565b63ffffffff831681526040602082015260008235610e4b81610ac1565b7fffffffffffffffff0000000000000000000000000000000000000000000000001660408301526020830135610e8081610a8e565b67ffffffffffffffff8082166060850152604085013591507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1853603018212610ec857600080fd5b6020918501918201913581811115610edf57600080fd5b8060051b3603831315610ef157600080fd5b60606080860152610f0660a086018285610de8565b97965050505050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ChannelDefinitionNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyStreamIDs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByEOA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StagingConfigAlreadyPromoted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroReportFormat\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"ChannelDefinitionRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"reportFormat\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"NewChannelDefinition\",\"type\":\"event\"},{\"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\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"PromoteStagingConfig\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"reportFormat\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"addChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"getChannelDefinitions\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"reportFormat\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"removeChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610e4f806101576000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b146101535780639682a4501461017b578063f2fde38b1461018e578063f5810719146101a157600080fd5b806301ffc9a71461008d578063181f5a77146100f757806379ba5097146101365780637e37e71914610140575b600080fd5b6100e261009b3660046107d1565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1d344450000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4368616e6e656c436f6e66696753746f726520302e302e300000000000000000602082015290516100ee919061081a565b61013e6101c1565b005b61013e61014e366004610898565b6102c3565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ee565b61013e6101893660046108b5565b6103a3565b61013e61019c36600461090c565b6104f3565b6101b46101af366004610898565b610507565b6040516100ee9190610942565b60015473ffffffffffffffffffffffffffffffffffffffff163314610247576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6102cb610620565b63ffffffff8116600090815260026020526040812060010154900361031c576040517fd1a751e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8116600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168155906103656001830182610798565b505060405163ffffffff821681527f334e877e9691ecae0660510061973bebaa8b4fb37332ed6090052e630c9798619060200160405180910390a150565b6103ab610620565b6103b860408201826109bc565b90506000036103f3576040517f4b620e2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104036040820160208301610a41565b67ffffffffffffffff16600003610446576040517ff89d762900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104536020820182610898565b63ffffffff16600003610492576040517febd3ef0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8216600090815260026020526040902081906104b38282610c37565b9050507f35d63e43dd8abd374a4c4e0b5b02c8294dd20e1f493e7344a1751123d11ecc1482826040516104e7929190610d7f565b60405180910390a15050565b6104fb610620565b610504816106a3565b50565b6040805160608082018352600080835260208301529181019190915233321461055c576040517f74e2cd5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff82811660009081526002602090815260409182902082516060810184528154948516815264010000000090940467ffffffffffffffff16848301526001810180548451818502810185018652818152929486019383018282801561061057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116105d35790505b5050505050815250509050919050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161023e565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610722576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161023e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b50805460008255600701600890049060005260206000209081019061050491905b808211156107cd57600081556001016107b9565b5090565b6000602082840312156107e357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461081357600080fd5b9392505050565b600060208083528351808285015260005b818110156108475785810183015185820160400152820161082b565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b63ffffffff8116811461050457600080fd5b6000602082840312156108aa57600080fd5b813561081381610886565b600080604083850312156108c857600080fd5b82356108d381610886565b9150602083013567ffffffffffffffff8111156108ef57600080fd5b83016060818603121561090157600080fd5b809150509250929050565b60006020828403121561091e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461081357600080fd5b600060208083526080830163ffffffff808651168386015267ffffffffffffffff83870151166040860152604086015160608087015282815180855260a0880191508583019450600092505b808310156109b05784518416825293850193600192909201919085019061098e565b50979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126109f157600080fd5b83018035915067ffffffffffffffff821115610a0c57600080fd5b6020019150600581901b3603821315610a2457600080fd5b9250929050565b67ffffffffffffffff8116811461050457600080fd5b600060208284031215610a5357600080fd5b813561081381610a2b565b60008135610a6b81610886565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b68010000000000000000821115610ab957610ab9610a71565b805482825580831015610b3e576000828152602081206007850160031c81016007840160031c82019150601c8660021b168015610b25577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8083018054828460200360031b1c16815550505b505b81811015610b3a57828155600101610b27565b5050505b505050565b67ffffffffffffffff831115610b5b57610b5b610a71565b610b658382610aa0565b60008181526020902082908460031c60005b81811015610bd0576000805b6008811015610bc357610bb2610b9887610a5e565b63ffffffff908116600584901b90811b91901b1984161790565b602096909601959150600101610b83565b5083820155600101610b77565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88616808703818814610c2d576000805b82811015610c2757610c16610b9888610a5e565b602097909701969150600101610c02565b50848401555b5050505050505050565b8135610c4281610886565b63ffffffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000082161783556020840135610c8281610a2b565b6bffffffffffffffff000000008160201b16837fffffffffffffffffffffffffffffffffffffffff00000000000000000000000084161717845550505060408201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112610cf457600080fd5b8201803567ffffffffffffffff811115610d0d57600080fd5b6020820191508060051b3603821315610d2557600080fd5b610d33818360018601610b43565b50505050565b8183526000602080850194508260005b85811015610d74578135610d5c81610886565b63ffffffff1687529582019590820190600101610d49565b509495945050505050565b600063ffffffff8085168352604060208401528335610d9d81610886565b1660408301526020830135610db181610a2b565b67ffffffffffffffff8082166060850152604085013591507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1853603018212610df957600080fd5b6020918501918201913581811115610e1057600080fd5b8060051b3603831315610e2257600080fd5b60606080860152610e3760a086018285610d39565b97965050505050505056fea164736f6c6343000813000a", } var ChannelConfigStoreABI = ChannelConfigStoreMetaData.ABI @@ -960,7 +960,7 @@ func (ChannelConfigStoreChannelDefinitionRemoved) Topic() common.Hash { } func (ChannelConfigStoreNewChannelDefinition) Topic() common.Hash { - return common.HexToHash("0xbf2cd44714205d633d3f888ac72ea66d53cd12d4c4e8723a80d9c0bc36484a54") + return common.HexToHash("0x35d63e43dd8abd374a4c4e0b5b02c8294dd20e1f493e7344a1751123d11ecc14") } func (ChannelConfigStoreOwnershipTransferRequested) Topic() common.Hash { diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 31333e92ebf..729d3a295cd 100644 --- a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 -channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin 4ae3e6ca866fdf48850d67c0c7a4bdaf4905c81a4e3ce5efb9ef9613a55d8454 +channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin c90e29d9f1a885098982b6175e0447416431b28c605273c807694ac7141e9167 channel_config_verifier_proxy: ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.abi ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.bin 655658e5f61dfadfe3268de04f948b7e690ad03ca45676e645d6cd6018154661 channel_verifier: ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin e6020553bd8e3e6b250fcaffe7efd22aea955c8c1a0eb05d282fdeb0ab6550b7 errored_verifier: ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.bin a3e5a77262e13ee30fe8d35551b32a3452d71929e43fd780bbfefeaf4aa62e43 diff --git a/core/services/streams/stream_registry.go b/core/services/streams/stream_registry.go index bc63e98e288..9d3fcda7109 100644 --- a/core/services/streams/stream_registry.go +++ b/core/services/streams/stream_registry.go @@ -4,14 +4,14 @@ import ( "fmt" "sync" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" ) // alias for easier refactoring -type StreamID = commontypes.StreamID +type StreamID = llotypes.StreamID type Registry interface { Getter From 84783a85f7319e1bd8ff0a372686ea6de11fc366 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Tue, 20 Feb 2024 07:22:14 -0800 Subject: [PATCH 57/98] Support workflow specs added via UI (#12091) Uploads were failing due to missing validations Specs are still empty for the time being. --- core/services/job/models.go | 3 ++ core/services/workflows/delegate.go | 25 +++++++++ core/services/workflows/delegate_test.go | 54 +++++++++++++++++++ .../0223_workflow_spec_validation.sql | 42 +++++++++++++++ core/web/jobs_controller.go | 3 ++ core/web/resolver/mutation.go | 3 ++ 6 files changed, 130 insertions(+) create mode 100644 core/services/workflows/delegate_test.go create mode 100644 core/store/migrate/migrations/0223_workflow_spec_validation.sql diff --git a/core/services/job/models.go b/core/services/job/models.go index b769106d647..233912d09c2 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -87,6 +87,7 @@ var ( Stream: true, VRF: true, Webhook: true, + Workflow: false, } supportsAsync = map[Type]bool{ BlockHeaderFeeder: false, @@ -104,6 +105,7 @@ var ( Stream: true, VRF: true, Webhook: true, + Workflow: false, } schemaVersions = map[Type]uint32{ BlockHeaderFeeder: 1, @@ -121,6 +123,7 @@ var ( Stream: 1, VRF: 1, Webhook: 1, + Workflow: 1, } ) diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index 32307b9fb9e..13a8bda4043 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -1,6 +1,11 @@ package workflows import ( + "fmt" + + "github.com/google/uuid" + "github.com/pelletier/go-toml" + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" @@ -43,3 +48,23 @@ func NewDelegate(logger logger.Logger, registry types.CapabilitiesRegistry, lega return &Delegate{logger: logger, registry: registry} } + +func ValidatedWorkflowSpec(tomlString string) (job.Job, error) { + var jb = job.Job{ExternalJobID: uuid.New()} + + tree, err := toml.Load(tomlString) + if err != nil { + return jb, fmt.Errorf("toml error on load: %w", err) + } + + err = tree.Unmarshal(&jb) + if err != nil { + return jb, fmt.Errorf("toml unmarshal error on spec: %w", err) + } + + if jb.Type != job.Workflow { + return jb, fmt.Errorf("unsupported type %s", jb.Type) + } + + return jb, nil +} diff --git a/core/services/workflows/delegate_test.go b/core/services/workflows/delegate_test.go new file mode 100644 index 00000000000..fd2df9141bc --- /dev/null +++ b/core/services/workflows/delegate_test.go @@ -0,0 +1,54 @@ +package workflows_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/services/workflows" +) + +func TestDelegate_JobSpecValidator(t *testing.T) { + t.Parallel() + + var tt = []struct { + name string + toml string + valid bool + }{ + { + "valid spec", + ` +type = "workflow" +schemaVersion = 1 +`, + true, + }, + { + "parse error", + ` +invalid syntax{{{{ +`, + false, + }, + { + "invalid job type", + ` +type = "work flows" +schemaVersion = 1 +`, + false, + }, + } + for _, tc := range tt { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := workflows.ValidatedWorkflowSpec(tc.toml) + if tc.valid { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/core/store/migrate/migrations/0223_workflow_spec_validation.sql b/core/store/migrate/migrations/0223_workflow_spec_validation.sql new file mode 100644 index 00000000000..6932cc2b759 --- /dev/null +++ b/core/store/migrate/migrations/0223_workflow_spec_validation.sql @@ -0,0 +1,42 @@ +-- +goose Up +ALTER TABLE + jobs +DROP + CONSTRAINT chk_specs, +ADD + CONSTRAINT chk_specs CHECK ( + num_nonnulls( + ocr_oracle_spec_id, ocr2_oracle_spec_id, + direct_request_spec_id, flux_monitor_spec_id, + keeper_spec_id, cron_spec_id, webhook_spec_id, + vrf_spec_id, blockhash_store_spec_id, + block_header_feeder_spec_id, bootstrap_spec_id, + gateway_spec_id, + legacy_gas_station_server_spec_id, + legacy_gas_station_sidecar_spec_id, + eal_spec_id, + CASE "type" WHEN 'stream' THEN 1 ELSE NULL END, -- 'stream' type lacks a spec but should not cause validation to fail + CASE "type" WHEN 'workflow' THEN 1 ELSE NULL END -- 'workflow' type currently lacks a spec but should not cause validation to fail + ) = 1 + ); + +-- +goose Down +ALTER TABLE + jobs +DROP + CONSTRAINT chk_specs, +ADD + CONSTRAINT chk_specs CHECK ( + num_nonnulls( + ocr_oracle_spec_id, ocr2_oracle_spec_id, + direct_request_spec_id, flux_monitor_spec_id, + keeper_spec_id, cron_spec_id, webhook_spec_id, + vrf_spec_id, blockhash_store_spec_id, + block_header_feeder_spec_id, bootstrap_spec_id, + gateway_spec_id, + legacy_gas_station_server_spec_id, + legacy_gas_station_sidecar_spec_id, + eal_spec_id, + CASE "type" WHEN 'stream' THEN 1 ELSE NULL END -- 'stream' type lacks a spec but should not cause validation to fail + ) = 1 + ); diff --git a/core/web/jobs_controller.go b/core/web/jobs_controller.go index 4e11f68097d..6296c6a016f 100644 --- a/core/web/jobs_controller.go +++ b/core/web/jobs_controller.go @@ -30,6 +30,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/streams" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" + "github.com/smartcontractkit/chainlink/v2/core/services/workflows" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -253,6 +254,8 @@ func (jc *JobsController) validateJobSpec(tomlString string) (jb job.Job, status jb, err = gateway.ValidatedGatewaySpec(tomlString) case job.Stream: jb, err = streams.ValidatedStreamSpec(tomlString) + case job.Workflow: + jb, err = workflows.ValidatedWorkflowSpec(tomlString) default: return jb, http.StatusUnprocessableEntity, errors.Errorf("unknown job type: %s", jobType) } diff --git a/core/web/resolver/mutation.go b/core/web/resolver/mutation.go index 996b3859a55..685fbe61ccb 100644 --- a/core/web/resolver/mutation.go +++ b/core/web/resolver/mutation.go @@ -38,6 +38,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" + "github.com/smartcontractkit/chainlink/v2/core/services/workflows" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" @@ -1047,6 +1048,8 @@ func (r *Resolver) CreateJob(ctx context.Context, args struct { jb, err = ocrbootstrap.ValidatedBootstrapSpecToml(args.Input.TOML) case job.Gateway: jb, err = gateway.ValidatedGatewaySpec(args.Input.TOML) + case job.Workflow: + jb, err = workflows.ValidatedWorkflowSpec(args.Input.TOML) default: return NewCreateJobPayload(r.App, nil, map[string]string{ "Job Type": fmt.Sprintf("unknown job type: %s", jbt), From 724d586ced537caa179d39fa02a429c70bb72ed6 Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal Date: Tue, 20 Feb 2024 16:05:33 +0000 Subject: [PATCH 58/98] Clean up todos (#12098) --- .../src/v0.8/automation/dev/chains/ArbitrumModule.sol | 7 ++++--- .../src/v0.8/automation/dev/chains/OptimismModule.sol | 8 ++++---- contracts/src/v0.8/automation/dev/chains/ScrollModule.sol | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol index 1bb4b45efc5..8b79dfaaafb 100644 --- a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol +++ b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol @@ -16,6 +16,9 @@ contract ArbitrumModule is ChainModuleBase { address private constant ARB_GAS_ADDR = 0x000000000000000000000000000000000000006C; ArbGasInfo private constant ARB_GAS = ArbGasInfo(ARB_GAS_ADDR); + uint256 private constant FIXED_GAS_OVERHEAD = 20000; + uint256 private constant PER_CALLDATA_BYTE_GAS_OVERHEAD = 20; + function blockHash(uint256 n) external view override returns (bytes32) { uint256 blockNum = ARB_SYS.arbBlockNumber(); if (n >= blockNum || blockNum - n > 256) { @@ -34,7 +37,6 @@ contract ArbitrumModule is ChainModuleBase { function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { (, uint256 perL1CalldataUnit, , , , ) = ARB_GAS.getPricesInWei(); - // TODO: Verify this is an accurate estimate return perL1CalldataUnit * dataSize * 16; } @@ -44,7 +46,6 @@ contract ArbitrumModule is ChainModuleBase { override returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) { - // TODO: Calculate - return (0, 0); + return (FIXED_GAS_OVERHEAD, PER_CALLDATA_BYTE_GAS_OVERHEAD); } } diff --git a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol b/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol index 0d6bc651683..c868deae625 100644 --- a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol +++ b/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol @@ -13,8 +13,10 @@ contract OptimismModule is ChainModuleBase { address private constant OVM_GASPRICEORACLE_ADDR = 0x420000000000000000000000000000000000000F; OVM_GasPriceOracle private constant OVM_GASPRICEORACLE = OVM_GasPriceOracle(OVM_GASPRICEORACLE_ADDR); + uint256 private constant FIXED_GAS_OVERHEAD = 20000; + uint256 private constant PER_CALLDATA_BYTE_GAS_OVERHEAD = 20; + function getCurrentL1Fee() external view override returns (uint256) { - // TODO: Verify this is accurate calculation with appropriate padding return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(msg.data, OP_L1_DATA_FEE_PADDING)); } @@ -22,7 +24,6 @@ contract OptimismModule is ChainModuleBase { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. bytes memory txCallData = new bytes(4 * dataSize); - // TODO: Verify this is an accurate estimate return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(txCallData, OP_L1_DATA_FEE_PADDING)); } @@ -32,7 +33,6 @@ contract OptimismModule is ChainModuleBase { override returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) { - // TODO: Calculate - return (0, 0); + return (FIXED_GAS_OVERHEAD, PER_CALLDATA_BYTE_GAS_OVERHEAD); } } diff --git a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol b/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol index 7029448637c..d5ea67fbc15 100644 --- a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol +++ b/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol @@ -15,8 +15,10 @@ contract ScrollModule is ChainModuleBase { address private constant SCROLL_ORACLE_ADDR = 0x5300000000000000000000000000000000000002; IScrollL1GasPriceOracle private constant SCROLL_ORACLE = IScrollL1GasPriceOracle(SCROLL_ORACLE_ADDR); + uint256 private constant FIXED_GAS_OVERHEAD = 20000; + uint256 private constant PER_CALLDATA_BYTE_GAS_OVERHEAD = 20; + function getCurrentL1Fee() external view override returns (uint256) { - // TODO: Verify this is accurate calculation with appropriate padding return SCROLL_ORACLE.getL1Fee(bytes.concat(msg.data, SCROLL_L1_FEE_DATA_PADDING)); } @@ -24,7 +26,6 @@ contract ScrollModule is ChainModuleBase { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. // this is the same as OP. - // TODO: Verify this is an accurate estimate bytes memory txCallData = new bytes(4 * dataSize); return SCROLL_ORACLE.getL1Fee(bytes.concat(txCallData, SCROLL_L1_FEE_DATA_PADDING)); } @@ -35,7 +36,6 @@ contract ScrollModule is ChainModuleBase { override returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) { - // TODO: Calculate - return (0, 0); + return (FIXED_GAS_OVERHEAD, PER_CALLDATA_BYTE_GAS_OVERHEAD); } } From 3ea44bd5ab3a34ae9125f2e685c263b9f71c7089 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 20 Feb 2024 11:39:19 -0500 Subject: [PATCH 59/98] feature/sql-tracing: adding tracing to our db (#12097) * feature/sql-tracing: adding tracing to our db * XSAM otelsql library * cleanup --- core/scripts/go.mod | 1 + core/scripts/go.sum | 4 ++++ core/services/pg/connection.go | 18 +++++++++++++++++- core/web/router.go | 4 +++- go.mod | 3 ++- go.sum | 4 ++++ integration-tests/go.mod | 1 + integration-tests/go.sum | 4 ++++ 8 files changed, 36 insertions(+), 3 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 854007e9b8e..97f8fda74e8 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -52,6 +52,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/XSAM/otelsql v0.27.0 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/avast/retry-go/v4 v4.5.1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 9d08d29f0b8..f52f3cac869 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -118,6 +118,8 @@ github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bw github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= +github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= @@ -1387,6 +1389,8 @@ go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ3 go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= diff --git a/core/services/pg/connection.go b/core/services/pg/connection.go index ee345bb6259..7848c0ed5e1 100644 --- a/core/services/pg/connection.go +++ b/core/services/pg/connection.go @@ -8,8 +8,12 @@ import ( _ "github.com/jackc/pgx/v4/stdlib" // need to make sure pgx driver is registered before opening connection "github.com/jmoiron/sqlx" "github.com/scylladb/go-reflectx" + "go.opentelemetry.io/otel" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "github.com/smartcontractkit/chainlink/v2/core/store/dialects" + + "github.com/XSAM/otelsql" ) type ConnectionConfig interface { @@ -32,10 +36,22 @@ func NewConnection(uri string, dialect dialects.DialectName, config ConnectionCo } // Initialize sql/sqlx - db, err = sqlx.Open(string(dialect), uri) + sqldb, err := otelsql.Open(string(dialect), uri, + otelsql.WithAttributes(semconv.DBSystemPostgreSQL), + otelsql.WithTracerProvider(otel.GetTracerProvider()), + otelsql.WithSQLCommenter(true), + otelsql.WithSpanOptions(otelsql.SpanOptions{ + OmitConnResetSession: true, + OmitConnPrepare: true, + OmitRows: true, + OmitConnectorConnect: true, + OmitConnQuery: false, + }), + ) if err != nil { return nil, err } + db = sqlx.NewDb(sqldb, string(dialect)) db.MapperFunc(reflectx.CamelToSnakeASCII) // Set default connection options diff --git a/core/web/router.go b/core/web/router.go index 6401622e192..c327583a005 100644 --- a/core/web/router.go +++ b/core/web/router.go @@ -33,6 +33,7 @@ import ( "github.com/ulule/limiter/v3/drivers/store/memory" "github.com/unrolled/secure" "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" + "go.opentelemetry.io/otel" "github.com/smartcontractkit/chainlink/v2/core/build" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -61,7 +62,8 @@ func NewRouter(app chainlink.Application, prometheus *ginprom.Prometheus) (*gin. tls := config.WebServer().TLS() engine.Use( - otelgin.Middleware("chainlink-web-routes"), + otelgin.Middleware("chainlink-web-routes", + otelgin.WithTracerProvider(otel.GetTracerProvider())), limits.RequestSizeLimiter(config.WebServer().HTTPMaxSize()), loggerFunc(app.GetLogger()), gin.Recovery(), diff --git a/go.mod b/go.mod index 401a19c8aa7..1d3799dc999 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/Depado/ginprom v1.8.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/sprig/v3 v3.2.3 + github.com/XSAM/otelsql v0.27.0 github.com/avast/retry-go/v4 v4.5.1 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/cometbft/cometbft v0.37.2 @@ -91,6 +92,7 @@ require ( go.dedis.ch/fixbuf v1.0.3 go.dedis.ch/kyber/v3 v3.1.0 go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.46.1 + go.opentelemetry.io/otel v1.21.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.19.0 @@ -305,7 +307,6 @@ require ( go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect go.opentelemetry.io/otel/metric v1.21.0 // indirect diff --git a/go.sum b/go.sum index e53d5a17755..1f2da19fe3b 100644 --- a/go.sum +++ b/go.sum @@ -123,6 +123,8 @@ github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bw github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= +github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= @@ -1382,6 +1384,8 @@ go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ3 go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 73da0e26234..39d17c0ae79 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -84,6 +84,7 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/XSAM/otelsql v0.27.0 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/armon/go-metrics v0.4.1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 74858d24794..2f695610301 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -164,6 +164,8 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd5wAKUHEO/k= github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= +github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= +github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= @@ -1756,6 +1758,8 @@ go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ3 go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= From 3aa93b2395091fa5cc56861573c6a0ccadac391c Mon Sep 17 00:00:00 2001 From: Jim W Date: Tue, 20 Feb 2024 14:43:01 -0500 Subject: [PATCH 60/98] missing tx attempt bug fix (#12036) * add code to handle if exceeds max fee is encountered * add partial fix but has testing bugs * separate tests * remove fallthrough * reword critical message * fix lint error --- common/txmgr/confirmer.go | 19 +++-- core/chains/evm/txmgr/confirmer_test.go | 104 +++++++++++++++--------- 2 files changed, 81 insertions(+), 42 deletions(-) diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index d55f982c11f..c28216467a1 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -718,7 +718,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Fin oldestBlocksBehind = blockNum - *oldestBlockNum } } else { - logger.Sugared(lggr).AssumptionViolationf("Expected tx for gas bump to have at least one attempt", "etxID", etx.ID, "blockNum", blockNum, "address", address) + logger.Sugared(lggr).AssumptionViolationw("Expected tx for gas bump to have at least one attempt", "etxID", etx.ID, "blockNum", blockNum, "address", address) } lggr.Infow(fmt.Sprintf("Found %d transactions to re-sent that have still not been confirmed after at least %d blocks. The oldest of these has not still not been confirmed after %d blocks. These transactions will have their gas price bumped. %s", len(etxBumps), gasBumpThreshold, oldestBlocksBehind, label.NodeConnectivityProblemWarning), "blockNum", blockNum, "address", address, "gasBumpThreshold", gasBumpThreshold) } @@ -858,10 +858,19 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han } return ec.handleInProgressAttempt(ctx, lggr, etx, replacementAttempt, blockHeight) case client.ExceedsMaxFee: - // Confirmer: The gas price was bumped too high. This transaction attempt cannot be accepted. - // Best thing we can do is to re-send the previous attempt at the old - // price and discard this bumped version. - fallthrough + // Confirmer: Note it is not guaranteed that all nodes share the same tx fee cap. + // So it is very likely that this attempt was successful on another node since + // it was already successfully broadcasted. So we assume it is successful and + // warn the operator that the RPC node is misconfigured. + // This failure scenario is a strong indication that the RPC node + // is misconfigured. This is a critical error and should be resolved by the + // node operator. + // If there is only one RPC node, or all RPC nodes have the same + // configured cap, this transaction will get stuck and keep repeating + // forever until the issue is resolved. + lggr.Criticalw(`RPC node rejected this tx as outside Fee Cap but it may have been accepted by another Node`, "attempt", attempt) + timeout := ec.dbConfig.DefaultQueryTimeout() + return ec.txStore.SaveSentAttempt(ctx, timeout, &attempt, now) case client.Fatal: // WARNING: This should never happen! // Should NEVER be fatal this is an invariant violation. The diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 9f267a8ea67..6cb14a8d618 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -1719,6 +1719,73 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing }) } +func TestEthConfirmer_RebroadcastWhereNecessary_MaxFeeScenario(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.EVM[0].GasEstimator.PriceMax = assets.GWei(500) + }) + txStore := cltest.NewTestTxStore(t, db, cfg.Database()) + + ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth() + + evmcfg := evmtest.NewChainScopedConfig(t, cfg) + + _, _ = cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) + _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) + + kst := ksmocks.NewEth(t) + addresses := []gethCommon.Address{fromAddress} + kst.On("EnabledAddressesForChain", &cltest.FixtureChainID).Return(addresses, nil).Maybe() + // Use a mock keystore for this test + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, kst, nil) + currentHead := int64(30) + oldEnough := int64(19) + nonce := int64(0) + + originalBroadcastAt := time.Unix(1616509100, 0) + etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress, originalBroadcastAt) + attempt1_1 := etx.TxAttempts[0] + var dbAttempt txmgr.DbEthTxAttempt + require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_1.ID)) + + t.Run("treats an exceeds max fee attempt as a success", func(t *testing.T) { + ethTx := *types.NewTx(&types.LegacyTx{}) + kst.On("SignTx", + fromAddress, + mock.MatchedBy(func(tx *types.Transaction) bool { + if tx.Nonce() != uint64(*etx.Sequence) { + return false + } + ethTx = *tx + return true + }), + mock.MatchedBy(func(chainID *big.Int) bool { + return chainID.Cmp(evmcfg.EVM().ChainID()) == 0 + })).Return(ðTx, nil).Once() + + // Once for the bumped attempt which exceeds limit + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { + return tx.Nonce() == uint64(*etx.Sequence) && tx.GasPrice().Int64() == int64(20000000000) + }), fromAddress).Return(commonclient.ExceedsMaxFee, errors.New("tx fee (1.10 ether) exceeds the configured cap (1.00 ether)")).Once() + + // Do the thing + require.NoError(t, ec.RebroadcastWhereNecessary(testutils.Context(t), currentHead)) + var err error + etx, err = txStore.FindTxWithAttempts(etx.ID) + require.NoError(t, err) + + // Check that the attempt is saved + require.Len(t, etx.TxAttempts, 2) + + // broadcast_at did change + require.Greater(t, etx.BroadcastAt.Unix(), originalBroadcastAt.Unix()) + require.Equal(t, etx.InitialBroadcastAt.Unix(), originalBroadcastAt.Unix()) + }) +} + func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { t.Parallel() @@ -1803,43 +1870,6 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { require.Len(t, etx.TxAttempts, 1) }) - ethClient = evmtest.NewEthClientMockWithDefaultChain(t) - ec.XXXTestSetClient(txmgr.NewEvmTxmClient(ethClient)) - - t.Run("does nothing and continues if bumped attempt transaction was too expensive", func(t *testing.T) { - ethTx := *types.NewTx(&types.LegacyTx{}) - kst.On("SignTx", - fromAddress, - mock.MatchedBy(func(tx *types.Transaction) bool { - if tx.Nonce() != uint64(*etx.Sequence) { - return false - } - ethTx = *tx - return true - }), - mock.MatchedBy(func(chainID *big.Int) bool { - return chainID.Cmp(evmcfg.EVM().ChainID()) == 0 - })).Return(ðTx, nil).Once() - - // Once for the bumped attempt which exceeds limit - ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { - return tx.Nonce() == uint64(*etx.Sequence) && tx.GasPrice().Int64() == int64(20000000000) - }), fromAddress).Return(commonclient.ExceedsMaxFee, errors.New("tx fee (1.10 ether) exceeds the configured cap (1.00 ether)")).Once() - - // Do the thing - require.NoError(t, ec.RebroadcastWhereNecessary(testutils.Context(t), currentHead)) - var err error - etx, err = txStore.FindTxWithAttempts(etx.ID) - require.NoError(t, err) - - // Did not create an additional attempt - require.Len(t, etx.TxAttempts, 1) - - // broadcast_at did not change - require.Equal(t, etx.BroadcastAt.Unix(), originalBroadcastAt.Unix()) - require.Equal(t, etx.InitialBroadcastAt.Unix(), originalBroadcastAt.Unix()) - }) - var attempt1_2 txmgr.TxAttempt ethClient = evmtest.NewEthClientMockWithDefaultChain(t) ec.XXXTestSetClient(txmgr.NewEvmTxmClient(ethClient)) From b5883718b03b99d46c67ee3a1fe2b3abf3e74385 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Tue, 20 Feb 2024 13:14:58 -0800 Subject: [PATCH 61/98] fix: goreleaser develop build for local and CI (#11847) * add updated goreleaser templates * update zig 0.11.0 * update goreleaser develop * add back ldflags and rename goreleaser config file * update goreleaser build gha workflow and pin new versions * add back pre/post hooks and updated goreleaser Dockerfile to include LOOP plugins * comment out integration-tests * add back goreleaser_wrapper * fix path in goreleaser_utils * add multi-line json output support * save * revert everthing and add go mod tidy * revert zig and goreleaser config * update * zig 0.10.1 * update go.mod go version * add -shared in goreleaser * use zig 0.11.0 and update bash fail * add to cc * update name * test * test * add LD_LIBRARY_PATH in dockerfile * add _transform_path func * fix post-hook cp * remove post hooks * use zig * use older zig version * try zig 0.12.0-dev * add back posthook * use zig 0.10.1 again * update go.mod to 1.21.5 * try older zig version * another older zig version * add ldd_fix script with patchelf * uncomment * add comments and remove unnecessary * update go.mod version * update go.mod to 1.21.7 for core/scripts * update all go.mod to 1.21.7 and remove artifact outputs --- .../goreleaser-build-sign-publish/action.yml | 15 +++++++---- .../action_utils | 4 +-- .../goreleaser-build-publish-develop.yml | 5 ++-- .goreleaser.develop.yaml | 12 ++++----- .tool-versions | 4 +-- core/chainlink.Dockerfile | 3 ++- core/chainlink.goreleaser.Dockerfile | 13 ++++++--- core/scripts/go.mod | 2 +- go.mod | 2 +- integration-tests/.tool-versions | 2 +- integration-tests/go.mod | 2 +- tools/bin/ldd_fix | 27 +++++++++++++++++++ 12 files changed, 64 insertions(+), 27 deletions(-) create mode 100755 tools/bin/ldd_fix diff --git a/.github/actions/goreleaser-build-sign-publish/action.yml b/.github/actions/goreleaser-build-sign-publish/action.yml index fdfcbd3711a..b8760e34dc1 100644 --- a/.github/actions/goreleaser-build-sign-publish/action.yml +++ b/.github/actions/goreleaser-build-sign-publish/action.yml @@ -3,7 +3,10 @@ description: A composite action that allows building and publishing signed chain inputs: goreleaser-version: description: The goreleaser version - default: 1.15.2 + default: 1.23.0 + required: false + goreleaser-key: + description: The goreleaser key required: false zig-version: description: The zig version @@ -11,13 +14,13 @@ inputs: required: false cosign-version: description: The cosign version - default: v1.13.1 + default: v2.2.2 required: false macos-sdk-dir: description: The macos sdk directory default: MacOSX12.3.sdk required: false - # publising inputs + # publishing inputs enable-docker-publish: description: Enable publishing of docker images / manifests default: "true" @@ -75,16 +78,18 @@ runs: - name: Setup goreleaser uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0 with: - distribution: goreleaser + distribution: goreleaser-pro install-only: true version: ${{ inputs.goreleaser-version }} + env: + GORELEASER_KEY: ${{ inputs.goreleaser-key }} - name: Setup zig uses: goto-bus-stop/setup-zig@7ab2955eb728f5440978d5824358023be3a2802d # v2.2.0 with: version: ${{ inputs.zig-version }} - name: Setup cosign if: inputs.enable-cosign == 'true' - uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 + uses: sigstore/cosign-installer@9614fae9e5c5eddabb09f90a270fcb487c9f7149 # v3.3.0 with: cosign-release: ${{ inputs.cosign-version }} - name: Login to docker registry diff --git a/.github/actions/goreleaser-build-sign-publish/action_utils b/.github/actions/goreleaser-build-sign-publish/action_utils index bf33d0cb4c6..4aac78d6fcc 100755 --- a/.github/actions/goreleaser-build-sign-publish/action_utils +++ b/.github/actions/goreleaser-build-sign-publish/action_utils @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -x +set -euo pipefail ENABLE_COSIGN=${ENABLE_COSIGN:-false} ENABLE_GORELEASER_SNAPSHOT=${ENABLE_GORELEASER_SNAPSHOT:-false} @@ -70,9 +71,6 @@ goreleaser_release() { rm -rf cosign.pub rm -rf cosign.key fi - - echo "metadata=$(cat dist/metadata.json)" >> "$GITHUB_OUTPUT" - echo "artifacts=$(cat dist/artifacts.json)" >> "$GITHUB_OUTPUT" } "$@" diff --git a/.github/workflows/goreleaser-build-publish-develop.yml b/.github/workflows/goreleaser-build-publish-develop.yml index 942f7d22432..5d4041bbc47 100644 --- a/.github/workflows/goreleaser-build-publish-develop.yml +++ b/.github/workflows/goreleaser-build-publish-develop.yml @@ -34,8 +34,8 @@ jobs: enable-goreleaser-snapshot: "true" goreleaser-exec: ./tools/bin/goreleaser_wrapper goreleaser-config: .goreleaser.develop.yaml - # ISSUE: https://github.com/golang/go/issues/52690 - zig-version: 0.11.0-dev.3380+7e0a02ee2 # TODO: update action to v0.11.x once released + goreleaser-key: ${{ secrets.GORELEASER_KEY }} + zig-version: 0.11.0 - name: Collect Metrics if: always() id: collect-gha-metrics @@ -46,6 +46,7 @@ jobs: hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} this-job-name: push-chainlink-develop-goreleaser continue-on-error: true + mercury-e2e-tests: needs: [push-chainlink-develop-goreleaser] runs-on: diff --git a/.goreleaser.develop.yaml b/.goreleaser.develop.yaml index 20312491651..60949eee72e 100644 --- a/.goreleaser.develop.yaml +++ b/.goreleaser.develop.yaml @@ -10,6 +10,7 @@ env: before: hooks: + - go mod tidy - ./tools/bin/goreleaser_utils before_hook # See https://goreleaser.com/customization/build/ @@ -62,6 +63,7 @@ dockers: goarch: amd64 extra_files: - tmp/linux_amd64/libs + - tools/bin/ldd_fix build_flag_templates: - "--platform=linux/amd64" - "--pull" @@ -84,6 +86,7 @@ dockers: goarch: arm64 extra_files: - tmp/linux_arm64/libs + - tools/bin/ldd_fix build_flag_templates: - "--platform=linux/arm64" - "--pull" @@ -106,6 +109,7 @@ dockers: goarch: amd64 extra_files: - tmp/linux_amd64/libs + - tools/bin/ldd_fix build_flag_templates: - "--platform=linux/amd64" - "--pull" @@ -129,6 +133,7 @@ dockers: goarch: arm64 extra_files: - tmp/linux_arm64/libs + - tools/bin/ldd_fix build_flag_templates: - "--platform=linux/arm64" - "--pull" @@ -170,13 +175,6 @@ docker_signs: - artifacts: all stdin: "{{ .Env.COSIGN_PASSWORD }}" -archives: - - rlcp: true - files: - - src: tmp/{{ .Os }}_{{ .Arch }}/libs/* - dst: libs - strip_parent: true - checksum: name_template: "checksums.txt" diff --git a/.tool-versions b/.tool-versions index e52a1f25a81..b3c9c6c56da 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,8 +1,8 @@ -golang 1.21.5 +golang 1.21.7 mockery 2.38.0 nodejs 16.16.0 postgres 13.3 helm 3.10.3 -zig 0.10.1 +zig 0.11.0 golangci-lint 1.55.2 protoc 25.1 diff --git a/core/chainlink.Dockerfile b/core/chainlink.Dockerfile index 22e65c0aa7a..f992ee76166 100644 --- a/core/chainlink.Dockerfile +++ b/core/chainlink.Dockerfile @@ -44,7 +44,8 @@ RUN apt-get update && apt-get install -y ca-certificates gnupg lsb-release curl RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ && echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |tee /etc/apt/sources.list.d/pgdg.list \ && apt-get update && apt-get install -y postgresql-client-15 \ - && apt-get clean all + && apt-get clean all \ + && rm -rf /var/lib/apt/lists/* COPY --from=buildgo /go/bin/chainlink /usr/local/bin/ diff --git a/core/chainlink.goreleaser.Dockerfile b/core/chainlink.goreleaser.Dockerfile index 26335a85bf1..7774c416f0e 100644 --- a/core/chainlink.goreleaser.Dockerfile +++ b/core/chainlink.goreleaser.Dockerfile @@ -6,18 +6,25 @@ FROM ubuntu:20.04 ARG CHAINLINK_USER=root ARG TARGETARCH ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update && apt-get install -y ca-certificates gnupg lsb-release curl +RUN apt-get update && apt-get install -y ca-certificates gnupg lsb-release curl patchelf # Install Postgres for CLI tools, needed specifically for DB backups RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ && echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |tee /etc/apt/sources.list.d/pgdg.list \ && apt-get update && apt-get install -y postgresql-client-15 \ - && apt-get clean all + && apt-get clean all \ + && rm -rf /var/lib/apt/lists/* -COPY . /usr/local/bin/ +COPY ./chainlink /usr/local/bin/ # Copy native libs if cgo is enabled COPY ./tmp/linux_${TARGETARCH}/libs /usr/local/bin/libs +# Temp fix to patch correctly link the libwasmvm.so +COPY ./tools/bin/ldd_fix /usr/local/bin/ldd_fix +RUN chmod +x /usr/local/bin/ldd_fix +RUN /usr/local/bin/ldd_fix +RUN apt-get remove -y patchelf + RUN if [ ${CHAINLINK_USER} != root ]; then \ useradd --uid 14933 --create-home ${CHAINLINK_USER}; \ fi diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 97f8fda74e8..b4d6860719d 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/chainlink/core/scripts -go 1.21.3 +go 1.21.7 // Make sure we're working with the latest chainlink libs replace github.com/smartcontractkit/chainlink/v2 => ../../ diff --git a/go.mod b/go.mod index 1d3799dc999..be354048dcd 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/chainlink/v2 -go 1.21.3 +go 1.21.7 require ( github.com/Depado/ginprom v1.8.0 diff --git a/integration-tests/.tool-versions b/integration-tests/.tool-versions index ac6300f9797..7f84d58b918 100644 --- a/integration-tests/.tool-versions +++ b/integration-tests/.tool-versions @@ -1,4 +1,4 @@ -golang 1.21.5 +golang 1.21.7 k3d 5.4.6 kubectl 1.25.5 nodejs 18.13.0 diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 39d17c0ae79..02857f31230 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/chainlink/integration-tests -go 1.21.4 +go 1.21.7 // Make sure we're working with the latest chainlink libs replace github.com/smartcontractkit/chainlink/v2 => ../ diff --git a/tools/bin/ldd_fix b/tools/bin/ldd_fix new file mode 100755 index 00000000000..dd48e9c3b30 --- /dev/null +++ b/tools/bin/ldd_fix @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# This script is used as a temp fix the ldd linking of cosm lib for binary +# Currently there is an issue with the go linker not working with zig +# https://github.com/ziglang/zig/issues/18922 + +chainlink_path="/usr/local/bin/chainlink" +libs_path="/usr/local/bin/libs" + +line=$(ldd ${chainlink_path} | grep "github.com/!cosm!wasm/wasmvm") + +if [ -z "$line" ]; then + echo "Error: Path containing 'github.com/!cosm!wasm/wasmvm' not found in the ldd output." + exit 1 +fi + +path=$(echo "$line" | awk '{print $1}') + +if [ -z "$path" ]; then + echo "Error: Failed to extract the path from the line." + exit 1 +fi + +trimmed_path=${path%.so*}.so +cosm_file=$(ls ${libs_path} | grep "\.so$" | head -n 1) + +patchelf --remove-needed "${trimmed_path}" "$chainlink_path" +patchelf --add-needed "$cosm_file" "$chainlink_path" From 8e145542a22b035e65ca6ed4179aa88fb86e3ada Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Wed, 21 Feb 2024 04:01:39 +0100 Subject: [PATCH 62/98] Wasp autobuild (#12056) * wip: migrate to WASP autobuild layout * WASP cluster integration: wip * update go.mod/sum * update go.mod/sum again * finally * works with local replaces * TOML config * version with a custom dockerignore * bump * exclude Sonar for duplication in load tests --- integration-tests/go.mod | 10 +- integration-tests/go.sum | 8 +- integration-tests/k8s/connect.go | 2 +- integration-tests/load/README.md | 17 + .../load}/connect.toml | 1 + .../{cmd => functionscmd}/dashboard.go | 0 integration-tests/load/go.mod | 499 ++++ integration-tests/load/go.sum | 2401 +++++++++++++++++ .../load/vrfv2/{cmd => vrfv2cmd}/dashboard.go | 0 .../{cmd => vrfv2pluscmd}/dashboard.go | 0 .../load/zcluster/cluster_entrypoint_test.go | 40 + integration-tests/testconfig/testconfig.go | 6 + sonar-project.properties | 3 +- 13 files changed, 2976 insertions(+), 11 deletions(-) rename {charts/chainlink-cluster => integration-tests/load}/connect.toml (84%) rename integration-tests/load/functions/{cmd => functionscmd}/dashboard.go (100%) create mode 100644 integration-tests/load/go.mod create mode 100644 integration-tests/load/go.sum rename integration-tests/load/vrfv2/{cmd => vrfv2cmd}/dashboard.go (100%) rename integration-tests/load/vrfv2plus/{cmd => vrfv2pluscmd}/dashboard.go (100%) create mode 100644 integration-tests/load/zcluster/cluster_entrypoint_test.go diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 02857f31230..38954c5b178 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -6,7 +6,6 @@ go 1.21.7 replace github.com/smartcontractkit/chainlink/v2 => ../ require ( - github.com/K-Phoen/grabana v0.22.1 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df github.com/cli/go-gh/v2 v2.0.0 github.com/ethereum/go-ethereum v1.13.8 @@ -25,19 +24,17 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 - github.com/smartcontractkit/chainlink-testing-framework v1.23.5 + github.com/smartcontractkit/chainlink-testing-framework v1.23.6 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a - github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 - github.com/smartcontractkit/wasp v0.4.2 + github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 github.com/test-go/testify v1.1.4 github.com/testcontainers/testcontainers-go v0.23.0 github.com/umbracle/ethgo v0.1.3 go.dedis.ch/kyber/v3 v3.1.0 - go.uber.org/ratelimit v0.2.0 go.uber.org/zap v1.26.0 golang.org/x/sync v0.6.0 golang.org/x/text v0.14.0 @@ -76,6 +73,7 @@ require ( github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect + github.com/K-Phoen/grabana v0.22.1 // indirect github.com/K-Phoen/sdk v0.12.4 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect @@ -377,6 +375,7 @@ require ( github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect + github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect @@ -434,6 +433,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect + go.uber.org/ratelimit v0.2.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.7.0 // indirect golang.org/x/crypto v0.19.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 2f695610301..77c335604cd 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1519,8 +1519,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= -github.com/smartcontractkit/chainlink-testing-framework v1.23.5 h1:bymN/mr4Tbx3DQ7EMB/z81+pCLhJkiYgxJDgAeTo9/w= -github.com/smartcontractkit/chainlink-testing-framework v1.23.5/go.mod h1:lGaqSnCB36n49fZNdTGXMrxhPu9w5+2n3c9V1Fqz1hM= +github.com/smartcontractkit/chainlink-testing-framework v1.23.6 h1:krjJswtgQ/J4kBgFpC7Tyh8wSFfWiGGUsADg6BG/EGw= +github.com/smartcontractkit/chainlink-testing-framework v1.23.6/go.mod h1:lGaqSnCB36n49fZNdTGXMrxhPu9w5+2n3c9V1Fqz1hM= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1533,8 +1533,8 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wasp v0.4.2 h1:MPErzwcOW84MKnA6/BjMnlsspQ0681XfoanGsJHOI7c= -github.com/smartcontractkit/wasp v0.4.2/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= +github.com/smartcontractkit/wasp v0.4.5 h1:pgiXwBci2m15eo33AzspzhpNG/gxg+8QGxl+I5LpfsQ= +github.com/smartcontractkit/wasp v0.4.5/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ= github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/integration-tests/k8s/connect.go b/integration-tests/k8s/connect.go index db9ccecb174..a543f8139c1 100644 --- a/integration-tests/k8s/connect.go +++ b/integration-tests/k8s/connect.go @@ -16,7 +16,7 @@ import ( ) const ( - DefaultConfigFilePath = "../../../charts/chainlink-cluster/connect.toml" + DefaultConfigFilePath = "connect.toml" ErrReadConnectionConfig = "failed to read TOML environment connection config" ErrUnmarshalConnectionConfig = "failed to unmarshal TOML environment connection config" ) diff --git a/integration-tests/load/README.md b/integration-tests/load/README.md index 3738a1d9ace..afcf633e5c3 100644 --- a/integration-tests/load/README.md +++ b/integration-tests/load/README.md @@ -68,3 +68,20 @@ To implement a standard e2e performance suite for a new product please look at ` Gun should be working with one instance of your product. VU(Virtual user) creates a new instance of your product and works with it in `Call()` + +### Cluster mode (k8s) +Add configuration to `overrides.toml` +``` +[WaspAutoBuild] +namespace = "wasp" +update_image = true +repo_image_version_uri = "${staging_ecr_registry}/wasp-tests:wb-core" +test_binary_name = "ocr.test" +test_name = "TestOCRLoad" +test_timeout = "24h" +wasp_log_level = "debug" +wasp_jobs = "1" +keep_jobs = true +``` + +And run your tests using `go test -v -run TestClusterEntrypoint` diff --git a/charts/chainlink-cluster/connect.toml b/integration-tests/load/connect.toml similarity index 84% rename from charts/chainlink-cluster/connect.toml rename to integration-tests/load/connect.toml index 9560be53adc..919c5102c84 100644 --- a/charts/chainlink-cluster/connect.toml +++ b/integration-tests/load/connect.toml @@ -1,3 +1,4 @@ +# this is a static configuration to connect with CRIB k8s environment (Default Geth) namespace = "cl-cluster" network_name = "geth" network_chain_id = 1337 diff --git a/integration-tests/load/functions/cmd/dashboard.go b/integration-tests/load/functions/functionscmd/dashboard.go similarity index 100% rename from integration-tests/load/functions/cmd/dashboard.go rename to integration-tests/load/functions/functionscmd/dashboard.go diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod new file mode 100644 index 00000000000..15753c05866 --- /dev/null +++ b/integration-tests/load/go.mod @@ -0,0 +1,499 @@ +module github.com/smartcontractkit/chainlink/load-tests + +go 1.21.7 + +// Make sure we're working with the latest chainlink libs +replace github.com/smartcontractkit/chainlink/v2 => ../../ + +replace github.com/smartcontractkit/chainlink/integration-tests => ../ + +require ( + github.com/K-Phoen/grabana v0.22.1 + github.com/ethereum/go-ethereum v1.13.8 + github.com/go-resty/resty/v2 v2.7.0 + github.com/pelletier/go-toml/v2 v2.1.1 + github.com/rs/zerolog v1.30.0 + github.com/slack-go/slack v0.12.2 + github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 + github.com/smartcontractkit/chainlink-testing-framework v1.23.6 + github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c + github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 + github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a + github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 + github.com/smartcontractkit/wasp v0.4.5 + github.com/stretchr/testify v1.8.4 + go.uber.org/ratelimit v0.2.0 +) + +// avoids ambigious imports of indirect dependencies +exclude github.com/hashicorp/consul v1.2.1 + +replace ( + github.com/testcontainers/testcontainers-go => github.com/Tofel/testcontainers-go v0.0.0-20231130110817-e6fbf9498b56 + // Pin K8s versions as their updates are highly disruptive and go mod keeps wanting to update them + k8s.io/api => k8s.io/api v0.25.11 + k8s.io/client-go => k8s.io/client-go v0.25.11 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d +) + +require ( + contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect + cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/errors v1.0.0 // indirect + cosmossdk.io/math v1.0.1 // indirect + dario.cat/mergo v1.0.0 // indirect + filippo.io/edwards25519 v1.0.0 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect + github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/CosmWasm/wasmd v0.40.1 // indirect + github.com/CosmWasm/wasmvm v1.2.4 // indirect + github.com/DataDog/zstd v1.5.2 // indirect + github.com/K-Phoen/sdk v0.12.4 // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.1 // indirect + github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/XSAM/otelsql v0.27.0 // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect + github.com/armon/go-metrics v0.4.1 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/avast/retry-go v3.0.0+incompatible // indirect + github.com/avast/retry-go/v4 v4.5.1 // indirect + github.com/aws/aws-sdk-go v1.45.25 // indirect + github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect + github.com/aws/jsii-runtime-go v1.75.0 // indirect + github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect + github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/bytedance/sonic v1.10.1 // indirect + github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b // indirect + github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8 // indirect + github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 // indirect + github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect + github.com/chenzhuoyu/iasm v0.9.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/cometbft/cometbft v0.37.2 // indirect + github.com/cometbft/cometbft-db v0.7.0 // indirect + github.com/confio/ics23/go v0.9.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/containerd/containerd v1.7.7 // indirect + github.com/containerd/continuity v0.4.3 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-sdk v0.47.4 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogoproto v1.4.11 // indirect + github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ibc-go/v7 v7.0.1 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect + github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set/v2 v2.3.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/dennwc/varint v1.0.0 // indirect + github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/edsrzf/mmap-go v1.1.0 // indirect + github.com/emicklei/go-restful/v3 v3.10.2 // indirect + github.com/esote/minmaxheap v1.0.0 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect + github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect + github.com/fatih/camelcase v1.0.0 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fvbommel/sortorder v1.0.2 // indirect + github.com/fxamacker/cbor/v2 v2.5.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gagliardetto/binary v0.7.1 // indirect + github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect + github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect + github.com/getsentry/sentry-go v0.19.0 // indirect + github.com/gin-contrib/sessions v0.0.5 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.9.1 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect + github.com/go-errors/errors v1.4.2 // indirect + github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-ldap/ldap/v3 v3.4.6 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-openapi/analysis v0.21.4 // indirect + github.com/go-openapi/errors v0.20.4 // indirect + github.com/go-openapi/jsonpointer v0.20.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/loads v0.21.2 // indirect + github.com/go-openapi/spec v0.20.9 // indirect + github.com/go-openapi/strfmt v0.21.7 // indirect + github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/validate v0.22.1 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-sql-driver/mysql v1.7.1 // indirect + github.com/go-webauthn/webauthn v0.9.4 // indirect + github.com/go-webauthn/x v0.1.5 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/googleapis v1.4.1 // indirect + github.com/gogo/protobuf v1.3.3 // indirect + github.com/gogo/status v1.1.1 // indirect + github.com/golang-jwt/jwt/v5 v5.2.0 // indirect + github.com/golang/glog v1.1.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/gnostic v0.6.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-github/v41 v41.0.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/go-tpm v0.9.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/google/uuid v1.4.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/gorilla/context v1.1.1 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/securecookie v1.1.2 // indirect + github.com/gorilla/sessions v1.2.2 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/gosimple/slug v1.13.1 // indirect + github.com/gosimple/unidecode v1.0.1 // indirect + github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f // indirect + github.com/grafana/gomemcache v0.0.0-20231023152154-6947259a0586 // indirect + github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect + github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect + github.com/grafana/pyroscope-go v1.0.4 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.4 // indirect + github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/consul/api v1.25.1 // indirect + github.com/hashicorp/consul/sdk v0.14.1 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-envparse v0.1.0 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/golang-lru v0.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/memberlist v0.5.0 // indirect + github.com/hashicorp/serf v0.10.1 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/hdevalence/ed25519consensus v0.1.0 // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgconn v1.14.1 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.3.2 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgtype v1.14.0 // indirect + github.com/jackc/pgx/v4 v4.18.1 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/julienschmidt/httprouter v1.3.0 // indirect + github.com/kelseyhightower/envconfig v1.4.0 // indirect + github.com/klauspost/compress v1.17.2 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/miekg/dns v1.1.56 // indirect + github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect + github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/opencontainers/runc v1.1.10 // indirect + github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect + github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/otiai10/copy v1.14.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/prometheus/alertmanager v0.26.0 // indirect + github.com/prometheus/client_golang v1.17.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/common/sigv4 v0.1.0 // indirect + github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/prometheus v0.48.1 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/russross/blackfriday v1.6.0 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/scylladb/go-reflectx v1.0.1 // indirect + github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/segmentio/ksuid v1.0.4 // indirect + github.com/sercand/kuberesolver/v5 v5.1.1 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/shirou/gopsutil/v3 v3.23.11 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect + github.com/smartcontractkit/chain-selectors v1.0.10 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect + github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 // indirect + github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect + github.com/smartcontractkit/wsrpc v0.7.2 // indirect + github.com/soheilhy/cmux v0.1.5 // indirect + github.com/sony/gobreaker v0.5.0 // indirect + github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.15.0 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/supranational/blst v0.3.11 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect + github.com/tendermint/go-amino v0.16.0 // indirect + github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect + github.com/testcontainers/testcontainers-go v0.23.0 // indirect + github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a // indirect + github.com/tidwall/btree v1.6.0 // indirect + github.com/tidwall/gjson v1.17.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/umbracle/ethgo v0.1.3 // indirect + github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect + github.com/valyala/fastjson v1.4.1 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/xlab/treeprint v1.1.0 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + github.com/zondax/hid v0.9.1 // indirect + github.com/zondax/ledger-go v0.14.1 // indirect + go.dedis.ch/fixbuf v1.0.3 // indirect + go.dedis.ch/kyber/v3 v3.1.0 // indirect + go.etcd.io/bbolt v1.3.7 // indirect + go.etcd.io/etcd/api/v3 v3.5.7 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect + go.etcd.io/etcd/client/v3 v3.5.7 // indirect + go.mongodb.org/mongo-driver v1.12.0 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect + go.opentelemetry.io/collector/semconv v0.87.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/sdk v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.starlark.net v0.0.0-20220817180228-f738f5508c12 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/goleak v1.3.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.26.0 // indirect + go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.18.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + gonum.org/v1/gonum v0.14.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/grpc v1.59.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/guregu/null.v2 v2.1.2 // indirect + gopkg.in/guregu/null.v4 v4.0.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.25.3 // indirect + k8s.io/apimachinery v0.28.2 // indirect + k8s.io/cli-runtime v0.25.11 // indirect + k8s.io/client-go v0.28.2 // indirect + k8s.io/component-base v0.26.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/kubectl v0.25.11 // indirect + k8s.io/utils v0.0.0-20230711102312-30195339c3c7 // indirect + nhooyr.io/websocket v1.8.7 // indirect + pgregory.net/rapid v0.5.5 // indirect + rsc.io/tmplfunc v0.0.3 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.12.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) + +replace ( + github.com/go-kit/log => github.com/go-kit/log v0.2.1 + + // replicating the replace directive on cosmos SDK + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + + // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 + + // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 + github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f + + // type func(a Label, b Label) bool of func(a, b Label) bool {…} does not match inferred type func(a Label, b Label) int for func(a E, b E) int + github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 +) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum new file mode 100644 index 00000000000..1aacb313ce5 --- /dev/null +++ b/integration-tests/load/go.sum @@ -0,0 +1,2401 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.110.9 h1:e7ITSqGFFk4rbz/JFIqZh3G4VEHguhAL4BQcFlWtU68= +cloud.google.com/go v0.110.9/go.mod h1:rpxevX/0Lqvlbc88b7Sc1SPNdyK1riNBTUU6JXhYNpM= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/iam v1.1.4 h1:K6n/GZHFTtEoKT5aUG3l9diPi0VduZNQ1PfdnpkkIFk= +cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= +contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= +contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= +contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= +contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= +cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= +cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= +cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= +cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= +cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= +cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= +cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= +cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= +filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= +github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= +github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= +github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= +github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= +github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= +github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= +github.com/CosmWasm/wasmvm v1.2.4/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Depado/ginprom v1.8.0 h1:zaaibRLNI1dMiiuj1MKzatm8qrcHzikMlCc1anqOdyo= +github.com/Depado/ginprom v1.8.0/go.mod h1:XBaKzeNBqPF4vxJpNLincSQZeMDnZp1tIbU0FU0UKgg= +github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= +github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/K-Phoen/grabana v0.22.1 h1:b/O+C3H2H6VNYSeMCYUO4X4wYuwFXgBcRkvYa+fjpQA= +github.com/K-Phoen/grabana v0.22.1/go.mod h1:3LTXrTzQzTKTgvKSXdRjlsJbizSOW/V23Q3iX00R5bU= +github.com/K-Phoen/sdk v0.12.4 h1:j2EYuBJm3zDTD0fGKACVFWxAXtkR0q5QzfVqxmHSeGQ= +github.com/K-Phoen/sdk v0.12.4/go.mod h1:qmM0wO23CtoDux528MXPpYvS4XkRWkWX6rvX9Za8EVU= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= +github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/Tofel/testcontainers-go v0.0.0-20231130110817-e6fbf9498b56 h1:HItfr1XKD/4xnsJE56m3uxnkMQ9lbg8xDnkf9qoZCH0= +github.com/Tofel/testcontainers-go v0.0.0-20231130110817-e6fbf9498b56/go.mod h1:ICriE9bLX5CLxL9OFQ2N+2N+f+803LNJ1utJb1+Inx0= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd5wAKUHEO/k= +github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= +github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= +github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI= +github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo= +github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= +github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= +github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= +github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= +github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= +github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= +github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= +github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= +github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= +github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= +github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= +github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df/go.mod h1:hiVxq5OP2bUGBRNS3Z/bt/reCLFNbdcST6gISi1fiOM= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= +github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.3 h1:SDlJ7bAm4ewvrmZtR0DaiYbQGdKPeaaIm7bM+qRhFeU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.3/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= +github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= +github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc= +github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= +github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b h1:6+ZFm0flnudZzdSE0JxlhR2hKnGPcNB35BjQf4RYQDY= +github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= +github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8 h1:SjZ2GvvOononHOpK84APFuMvxqsk3tEIaKH/z4Rpu3g= +github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8/go.mod h1:uEyr4WpAH4hio6LFriaPkL938XnrvLpNPmQHBdrmbIE= +github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 h1:rvc39Ol6z3MvaBzXkxFC6Nfsnixq/dRypushKDd7Nc0= +github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5/go.mod h1:R/pdNYDYFQk+tuuOo7QES1kkv6OLmp5ze2XBZQIVffM= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657 h1:CyuI+igIjadM/GRnE2o0q+WCwipDh0n2cUYFPAvxziM= +github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657/go.mod h1:JRiumF+RFsH1mrrP8FUsi9tExPylKkO/oSRWeQEUdLE= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= +github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= +github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= +github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= +github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= +github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= +github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= +github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4= +github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= +github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= +github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= +github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= +github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= +github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= +github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= +github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= +github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= +github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= +github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= +github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= +github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= +github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= +github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e h1:5jVSh2l/ho6ajWhSPNN84eHEdq3dp0T7+f6r3Tc6hsk= +github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e/go.mod h1:IJgIiGUARc4aOr4bOQ85klmjsShkEEfiRc6q/yBSfo8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= +github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= +github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= +github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= +github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= +github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= +github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= +github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= +github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= +github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= +github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= +github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= +github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM45eo= +github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= +github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= +github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI= +github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= +github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= +github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= +github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 h1:q2IztKyRQUxJ6abXRsawaBtvDFvM+szj4jDqV4od1gs= +github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27/go.mod h1:NFuoDwHPvw858ZMHUJr6bkhN8qHt4x6e+U3EYHxAwNY= +github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= +github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= +github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= +github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= +github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= +github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w= +github.com/gin-contrib/expvar v0.0.1/go.mod h1:8o2CznfQi1JjktORdHr2/abg3wSV6OCnXh0yGypvvVw= +github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE= +github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= +github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= +github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= +github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0 h1:ymLjT4f35nQbASLnvxEde4XOBL+Sn7rFuV+FOJqkljg= +github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A= +github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= +github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= +github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= +github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= +github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= +github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= +github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= +github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= +github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= +github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= +github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= +github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= +github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= +github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= +github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= +github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= +github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= +github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= +github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= +github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= +github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= +github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ= +github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= +github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= +github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= +github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= +github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= +github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= +github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f h1:gyojr97YeWZ70pKNakWv5/tKwBHuLy3icnIeCo9gQr4= +github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f/go.mod h1:8dsy5tQOkeNQyjXpm5mQsbCu3H5uzeBD35MzRQFznKU= +github.com/grafana/gomemcache v0.0.0-20231023152154-6947259a0586 h1:/of8Z8taCPftShATouOrBVy6GaTTjgQd/VfNiZp/VXQ= +github.com/grafana/gomemcache v0.0.0-20231023152154-6947259a0586/go.mod h1:PGk3RjYHpxMM8HFPhKKo+vve3DdlPUELZLSDEFehPuU= +github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qvPwZO5DC6QjnAW7uKJ9YXnoUmV8c= +github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo= +github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ= +github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= +github.com/grafana/pyroscope-go v1.0.4 h1:oyQX0BOkL+iARXzHuCdIF5TQ7/sRSel1YFViMHC7Bm0= +github.com/grafana/pyroscope-go v1.0.4/go.mod h1:0d7ftwSMBV/Awm7CCiYmHQEG8Y44Ma3YSjt+nWcWztY= +github.com/grafana/pyroscope-go/godeltaprof v0.1.4 h1:mDsJ3ngul7UfrHibGQpV66PbZ3q1T8glz/tK3bQKKEk= +github.com/grafana/pyroscope-go/godeltaprof v0.1.4/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko= +github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= +github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= +github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= +github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= +github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0 h1:f4tggROQKKcnh4eItay6z/HbHLqghBxS8g7pyMhmDio= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0/go.mod h1:hKAkSgNkL0FII46ZkJcpVEAai4KV+swlIWCKfekd1pA= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= +github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs= +github.com/hashicorp/consul/sdk v0.14.1/go.mod h1:vFt03juSzocLRFo59NkeQHHmQa6+g7oU0pfzdI1mUhg= +github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A= +github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-envparse v0.1.0 h1:bE++6bhIsNCPLvgDZkYqo3nA+/PFI51pkrHdmPSDFPY= +github.com/hashicorp/go-envparse v0.1.0/go.mod h1:OHheN1GoygLlAkTlXLXvAdnXdZxy8JUweQ1rAXx1xnc= +github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= +github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= +github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= +github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e h1:sr4lujmn9heD030xx/Pd4B/JSmvRhFzuotNXaaV0WLs= +github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e/go.mod h1:O23qLAZuCx4htdY9zBaO4cJPXgleSFEdq6D/sezGgYE= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= +github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= +github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/hetznercloud/hcloud-go/v2 v2.0.0 h1:Sg1DJ+MAKvbYAqaBaq9tPbwXBS2ckPIaMtVdUjKu+4g= +github.com/hetznercloud/hcloud-go/v2 v2.0.0/go.mod h1:4iUG2NG8b61IAwNx6UsMWQ6IfIf/i1RsG0BbsKAyR5Q= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/ionos-cloud/sdk-go/v6 v6.1.8 h1:493wE/BkZxJf7x79UCE0cYGPZoqQcPiEBALvt7uVGY0= +github.com/ionos-cloud/sdk-go/v6 v6.1.8/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= +github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4= +github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= +github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= +github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= +github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= +github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= +github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= +github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw= +github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= +github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= +github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= +github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40= +github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M= +github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= +github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= +github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w= +github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= +github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= +github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= +github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM= +github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= +github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/pressly/goose/v3 v3.16.0 h1:xMJUsZdHLqSnCqESyKSqEfcYVYsUuup1nrOhaEFftQg= +github.com/pressly/goose/v3 v3.16.0/go.mod h1:JwdKVnmCRhnF6XLQs2mHEQtucFD49cQBdRM4UiwkxsM= +github.com/prometheus/alertmanager v0.26.0 h1:uOMJWfIwJguc3NaM3appWNbbrh6G/OjvaHMk22aBBYc= +github.com/prometheus/alertmanager v0.26.0/go.mod h1:rVcnARltVjavgVaNnmevxK7kOn7IZavyf0KNgHkbEpU= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= +github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= +github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 h1:oHcfzdJnM/SFppy2aUlvomk37GI33x9vgJULihE5Dt8= +github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97/go.mod h1:LoBCZeRh+5hX+fSULNyFnagYlQG/gBsyA/deNzROkq8= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 h1:6ksZ7t1hNOzGPPs8DK7SvXQf6UfWzi+W5Z7PCBl8gx4= +github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510/go.mod h1:UC0TwJiF90m2T3iYPQBKnGu8gv3s55dF/EgpTq8gyvo= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw= +github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= +github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= +github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= +github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= +github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= +github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= +github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20 h1:a9hSJdJcd16e0HoMsnFvaHvxB3pxSD+SC7+CISp7xY0= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= +github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= +github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= +github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY= +github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= +github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.23.11 h1:i3jP9NjCPUz7FiZKxlMnODZkdSIp2gnzfrvsu9CuWEQ= +github.com/shirou/gopsutil/v3 v3.23.11/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= +github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= +github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= +github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= +github.com/smartcontractkit/chainlink-testing-framework v1.23.6 h1:krjJswtgQ/J4kBgFpC7Tyh8wSFfWiGGUsADg6BG/EGw= +github.com/smartcontractkit/chainlink-testing-framework v1.23.6/go.mod h1:lGaqSnCB36n49fZNdTGXMrxhPu9w5+2n3c9V1Fqz1hM= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= +github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= +github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a h1:nGkZ9uXS8lPIJOi68rdftEo2c9Q8qbRAi5+XMnKobVc= +github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a/go.mod h1:kC0qmVPUaVkFqGiZMNhmRmjdphuUmeyLEdlWFOQzFWI= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= +github.com/smartcontractkit/wasp v0.4.5 h1:pgiXwBci2m15eo33AzspzhpNG/gxg+8QGxl+I5LpfsQ= +github.com/smartcontractkit/wasp v0.4.5/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= +github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ= +github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= +github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= +github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= +github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= +github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w= +github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= +github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a h1:YuO+afVc3eqrjiCUizNCxI53bl/BnPiVwXqLzqYTqgU= +github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a/go.mod h1:/sfW47zCZp9FrtGcWyo1VjbgDaodxX9ovZvgLb/MxaA= +github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= +github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= +github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= +github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= +github.com/umbracle/ethgo v0.1.3/go.mod h1:g9zclCLixH8liBI27Py82klDkW7Oo33AxUOr+M9lzrU= +github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 h1:10Nbw6cACsnQm7r34zlpJky+IzxVLRk6MKTS2d3Vp0E= +github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722/go.mod h1:c8J0h9aULj2i3umrfyestM6jCq0LK0U6ly6bWy96nd4= +github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk= +github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= +github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= +github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= +github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= +github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= +go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= +go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= +go.dedis.ch/kyber/v3 v3.1.0 h1:ghu+kiRgM5JyD9TJ0hTIxTLQlJBR/ehjWvWwYW3XsC0= +go.dedis.ch/kyber/v3 v3.1.0/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U= +go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= +go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= +go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo= +go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY= +go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA= +go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg= +go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY= +go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4= +go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE= +go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 h1:qCPXSQCoD3qeWFb1RuIks8fw9Atxpk78bmtVdi15KhE= +go.opentelemetry.io/collector/pdata v1.0.0-rcv0016/go.mod h1:OdN0alYOlYhHXu6BDlGehrZWgtBuiDsz/rlNeJeXiNg= +go.opentelemetry.io/collector/semconv v0.87.0 h1:BsG1jdLLRCBRlvUujk4QA86af7r/ZXnizczQpEs/gg8= +go.opentelemetry.io/collector/semconv v0.87.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw= +go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.46.1 h1:mMv2jG58h6ZI5t5S9QCVGdzCmAsTakMa3oxVgpSD44g= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.46.1/go.mod h1:oqRuNKG0upTaDPbLVCG8AD0G2ETrfDtmh7jViy7ox6M= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.starlark.net v0.0.0-20220817180228-f738f5508c12 h1:xOBJXWGEDwU5xSDxH6macxO11Us0AH2fTa9rmsbbF7g= +go.starlark.net v0.0.0-20220817180228-f738f5508c12/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA= +go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= +go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.149.0 h1:b2CqT6kG+zqJIVKRQ3ELJVLN1PwHZ6DJ3dW8yl82rgY= +google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 h1:I6WNifs6pF9tNdSob2W24JtyxIYjzFB9qDlpUC76q+U= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/guregu/null.v2 v2.1.2 h1:YOuepWdYqGnrenzPyMi+ybCjeDzjdazynbwsXXOk4i8= +gopkg.in/guregu/null.v2 v2.1.2/go.mod h1:XORrx8tyS5ZDcyUboCIxQtta/Aujk/6pfWrn9Xe33mU= +gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= +gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/api v0.25.11 h1:4mjYDfE3yp22jrytjH0knwgzjXKkxHX4D01ZCAazvZM= +k8s.io/api v0.25.11/go.mod h1:bK4UvD4bthtutNlvensrfBX21PRQ/vs2cIYggHkOOAo= +k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= +k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/cli-runtime v0.25.11 h1:GE2yNZm1tN+MJtw1SGMOLesLF7Kp7NVAVqRSTbXfu4o= +k8s.io/cli-runtime v0.25.11/go.mod h1:r/nEINuHVEpgGhcd2WamU7hD1t/lMnSz8XM44Autltc= +k8s.io/client-go v0.25.11 h1:DJQ141UsbNRI6wYSlcYLP5J5BW5Wq7Bgm42Ztq2SW70= +k8s.io/client-go v0.25.11/go.mod h1:41Xs7p1SfhoReUnmjjYCfCNWFiq4xSkexwJfbxF2F7A= +k8s.io/component-base v0.26.2 h1:IfWgCGUDzrD6wLLgXEstJKYZKAFS2kO+rBRi0p3LqcI= +k8s.io/component-base v0.26.2/go.mod h1:DxbuIe9M3IZPRxPIzhch2m1eT7uFrSBJUBuVCQEBivs= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d h1:VcFq5n7wCJB2FQMCIHfC+f+jNcGgNMar1uKd6rVlifU= +k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY= +k8s.io/kubectl v0.25.11 h1:6bsft5Gan6BCvQ7cJbDRFjTm4Zfq8GuUYpsWAdVngYE= +k8s.io/kubectl v0.25.11/go.mod h1:8mIfgkFgT+yJ8/TlmPW1qoRh46H2si9q5nW8id7i9iM= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= +sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s= +sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= +sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= +sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= +sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/integration-tests/load/vrfv2/cmd/dashboard.go b/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go similarity index 100% rename from integration-tests/load/vrfv2/cmd/dashboard.go rename to integration-tests/load/vrfv2/vrfv2cmd/dashboard.go diff --git a/integration-tests/load/vrfv2plus/cmd/dashboard.go b/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go similarity index 100% rename from integration-tests/load/vrfv2plus/cmd/dashboard.go rename to integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go diff --git a/integration-tests/load/zcluster/cluster_entrypoint_test.go b/integration-tests/load/zcluster/cluster_entrypoint_test.go new file mode 100644 index 00000000000..03133071b36 --- /dev/null +++ b/integration-tests/load/zcluster/cluster_entrypoint_test.go @@ -0,0 +1,40 @@ +package zcluster + +import ( + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/wasp" + "github.com/stretchr/testify/require" + "testing" +) + +func TestClusterEntrypoint(t *testing.T) { + config, err := tc.GetConfig("Load", tc.OCR) + require.NoError(t, err) + cfgBase64, err := config.AsBase64() + require.NoError(t, err) + + p, err := wasp.NewClusterProfile(&wasp.ClusterConfig{ + // you set up these only once, no need to configure through TOML + DockerCmdExecPath: "../../..", + BuildCtxPath: "integration-tests/load", + + Namespace: *config.WaspConfig.Namespace, + KeepJobs: config.WaspConfig.KeepJobs, + UpdateImage: config.WaspConfig.UpdateImage, + HelmValues: map[string]string{ + "env.loki.url": *config.Logging.Loki.Endpoint, + "env.loki.tenant_id": *config.Logging.Loki.TenantId, + "image": *config.WaspConfig.RepoImageVersionURI, + "test.binaryName": *config.WaspConfig.TestBinaryName, + "test.name": *config.WaspConfig.TestName, + "test.timeout": *config.WaspConfig.TestTimeout, + "env.wasp.log_level": *config.WaspConfig.WaspLogLevel, + "jobs": *config.WaspConfig.WaspJobs, + // other test vars pass through + "test.BASE64_CONFIG_OVERRIDE": cfgBase64, + }, + }) + require.NoError(t, err) + err = p.Run() + require.NoError(t, err) +} diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 18249cd790e..16a56051da0 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -84,6 +84,7 @@ type TestConfig struct { Network *ctf_config.NetworkConfig `toml:"Network"` Pyroscope *ctf_config.PyroscopeConfig `toml:"Pyroscope"` PrivateEthereumNetwork *ctf_test_env.EthereumNetwork `toml:"PrivateEthereumNetwork"` + WaspConfig *ctf_config.WaspAutoBuildConfig `toml:"WaspAutoBuild"` Common *Common `toml:"Common"` Automation *a_config.Config `toml:"Automation"` @@ -519,6 +520,11 @@ func (c *TestConfig) Validate() error { } } + if c.WaspConfig != nil { + if err := c.WaspConfig.Validate(); err != nil { + return errors.Wrapf(err, "WaspAutoBuildConfig validation failed") + } + } return nil } diff --git a/sonar-project.properties b/sonar-project.properties index d4e263fdd3c..7d0c1be5fc5 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -52,7 +52,8 @@ sonar.cpd.exclusions=\ **/contracts/**/*.sol,\ **/config.go,\ **/core/services/ocr2/plugins/ocr2keeper/evm/**/*,\ -**/core/services/ocr2/plugins/mercury/plugin.go +**/core/services/ocr2/plugins/mercury/plugin.go,\ +**/integration-tests/load/**/* # Tests' root folder, inclusions (tests to check and count) and exclusions sonar.tests=. From 12d4dd6356c8fcd3bedd5a8c555ea2885a6b5db9 Mon Sep 17 00:00:00 2001 From: Jim W Date: Tue, 20 Feb 2024 23:59:41 -0500 Subject: [PATCH 63/98] nethermind error change bug (#12109) * initial attempt to fix bug * add tests * Update core/chains/evm/client/errors.go Co-authored-by: Vyzaldy Sanchez * change last line to critical * fix 503 error message --------- Co-authored-by: Vyzaldy Sanchez Co-authored-by: Prashant Yadav <34992934+prashantkumar1982@users.noreply.github.com> --- core/chains/evm/client/errors.go | 17 ++++++++++++++--- core/chains/evm/client/errors_test.go | 13 +++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 67197b764a0..e966e088678 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -62,6 +62,7 @@ const ( L2Full TransactionAlreadyMined Fatal + ServiceUnavailable ) type ClientErrors = map[int]*regexp.Regexp @@ -196,8 +197,9 @@ var nethermind = ClientErrors{ TransactionAlreadyInMempool: regexp.MustCompile(`(: |^)(AlreadyKnown|OwnNonceAlreadyUsed)$`), // InsufficientFunds: Sender account has not enough balance to execute this transaction. - InsufficientEth: regexp.MustCompile(`(: |^)InsufficientFunds(, Account balance: \d+, cumulative cost: \d+)?$`), - Fatal: nethermindFatal, + InsufficientEth: regexp.MustCompile(`(: |^)InsufficientFunds(, Account balance: \d+, cumulative cost: \d+|, Balance is \d+ less than sending value \+ gas \d+)?$`), + ServiceUnavailable: regexp.MustCompile(`(: |^)503 Service Unavailable: [\s\S]*$`), + Fatal: nethermindFatal, } // Harmony @@ -301,6 +303,11 @@ func (s *SendError) IsL2Full() bool { return s.is(L2Full) } +// IsServiceUnavailable indicates if the error was caused by a service being unavailable +func (s *SendError) IsServiceUnavailable() bool { + return s.is(ServiceUnavailable) +} + // IsTimeout indicates if the error was caused by an exceeded context deadline func (s *SendError) IsTimeout() bool { if s == nil { @@ -483,6 +490,10 @@ func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transacti ), "err", sendError, "etx", tx) return commonclient.InsufficientFunds } + if sendError.IsServiceUnavailable() { + lggr.Errorw("service unavailable while sending transaction %x", tx.Hash(), "err", sendError, "etx", tx) + return commonclient.Retryable + } if sendError.IsTimeout() { lggr.Errorw("timeout while sending transaction %x", tx.Hash(), "err", sendError, "etx", tx) return commonclient.Retryable @@ -499,6 +510,6 @@ func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transacti ) return commonclient.ExceedsMaxFee } - lggr.Errorw("Unknown error encountered when sending transaction", "err", err, "etx", tx) + lggr.Criticalw("Unknown error encountered when sending transaction", "err", err, "etx", tx) return commonclient.Unknown } diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index ad8079824ab..f47b93c0400 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -195,6 +195,7 @@ func Test_Eth_Errors(t *testing.T) { {"insufficient funds for gas * price + value: address 0xb68D832c1241bc50db1CF09e96c0F4201D5539C9 have 9934612900000000 want 9936662900000000", true, "Arbitrum"}, {"call failed: InsufficientFunds", true, "Nethermind"}, {"call failed: InsufficientFunds, Account balance: 4740799397601480913, cumulative cost: 22019342038993800000", true, "Nethermind"}, + {"call failed: InsufficientFunds, Balance is 1092404690719251702 less than sending value + gas 7165512000464000000", true, "Nethermind"}, {"insufficient funds", true, "Klaytn"}, {"insufficient funds for gas * price + value + gatewayFee", true, "celo"}, {"insufficient balance for transfer", true, "zkSync"}, @@ -208,6 +209,18 @@ func Test_Eth_Errors(t *testing.T) { } }) + t.Run("IsServiceUnavailable", func(t *testing.T) { + tests := []errorCase{ + {"call failed: 503 Service Unavailable: \r\n503 Service Temporarily Unavailable\r\n\r\n

503 Service Temporarily Unavailable

\r\n\r\n\r\n", true, "Nethermind"}, + } + for _, test := range tests { + err = evmclient.NewSendErrorS(test.message) + assert.Equal(t, err.IsServiceUnavailable(), test.expect) + err = newSendErrorWrapped(test.message) + assert.Equal(t, err.IsServiceUnavailable(), test.expect) + } + }) + t.Run("IsTxFeeExceedsCap", func(t *testing.T) { tests := []errorCase{ {"tx fee (1.10 ether) exceeds the configured cap (1.00 ether)", true, "geth"}, From 2cd4bc5508e240e2a989b4a20bb2370bf5016525 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Wed, 21 Feb 2024 00:28:56 -0500 Subject: [PATCH 64/98] (feat): FUN-1234 Functions USD denominated premium fees (#12104) --- .../gas-snapshots/functions.gas-snapshot | 154 +++++++++--------- .../functions/dev/v1_X/FunctionsBilling.sol | 118 ++++++++++---- .../dev/v1_X/FunctionsCoordinator.sol | 36 +++- .../dev/v1_X/interfaces/IFunctionsBilling.sol | 20 ++- .../tests/v1_X/FunctionsBilling.t.sol | 131 ++++++++++----- .../tests/v1_X/FunctionsCoordinator.t.sol | 7 +- .../tests/v1_X/FunctionsRouter.t.sol | 30 +++- .../tests/v1_X/FunctionsSubscriptions.t.sol | 12 +- .../src/v0.8/functions/tests/v1_X/Setup.t.sol | 92 ++++++++--- .../FunctionsCoordinatorHarness.sol | 22 ++- .../FunctionsCoordinatorTestHelper.sol | 24 +-- .../test/v0.8/functions/v1/RouterBase.test.ts | 3 + contracts/test/v0.8/functions/v1/utils.ts | 31 +++- .../functions_coordinator.go | 98 ++++++++--- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../v1/internal/testutils.go | 13 +- 16 files changed, 546 insertions(+), 247 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 279aa389e4f..fb24f678bc2 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,66 +1,68 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14860808) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14860786) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14860802) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14872224) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14872201) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14872173) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14872124) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14872113) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14872157) -FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) -FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32414) -FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 53763) -FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 53866) -FunctionsBilling_GetAdminFee:test_GetAdminFee_Success() (gas: 18226) -FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 23693) -FunctionsBilling_GetDONFee:test_GetDONFee_Success() (gas: 15792) -FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 31773) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70128) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertWithNoBalance() (gas: 106285) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceNoAmountGiven() (gas: 140164) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceValidAmountGiven() (gas: 142492) -FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13296) -FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 147278) -FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 18974) -FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 38273) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 15924776) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 15924754) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 15924770) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 15936218) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 15936195) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 15936167) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 15936118) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 15936107) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 15936151) +FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14823) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13260) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15875) +FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32436) +FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 88199) +FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 88302) +FunctionsBilling_GetAdminFeeJuels:test_GetAdminFeeJuels_Success() (gas: 18334) +FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 27553) +FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 40831) +FunctionsBilling_GetOperationFee:test_GetOperationFeeJuels_Success() (gas: 40211) +FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 29414) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70107) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertWithNoBalance() (gas: 106264) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessCoordinatorOwner() (gas: 129542) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceNoAmountGiven() (gas: 169241) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceValidAmountGiven() (gas: 142476) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13297) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 217168) +FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21521) +FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 49192) FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13302) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 180763) -FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 398400) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13375) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185974) +FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 523657) FunctionsClient_Constructor:test_Constructor_Success() (gas: 7573) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14623) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22923) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14617) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22917) FunctionsClient__SendRequest:test__SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 55059) -FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 12006) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15356) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 106528) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15313) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 656362) -FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20364) -FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 101307) +FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 12007) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15378) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 106551) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15356) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 656405) +FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20365) +FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 101330) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13892) -FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 651054) -FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22703) -FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 108804) -FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 18957) -FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 19690) +FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 651097) +FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22770) +FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 150311) +FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 12275) +FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 20107) FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 246) FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 223) FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 225) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12007) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 169829) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 160160) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 173026) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 163498) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38115) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35238) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 178305) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 181502) FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28086) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 153867) -FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321317) -FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334938) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2510364) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540803) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 157064) +FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 335516) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 349140) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2628028) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 658982) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17983) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12904) FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 37159) @@ -71,7 +73,7 @@ FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRo FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 25936) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 28103) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41093) -FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24626) +FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24620) FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13338) FunctionsRouter_Pause:test_Pause_Success() (gas: 20344) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14791) @@ -81,15 +83,15 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNe FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23392) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118479) FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59391) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 193436) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 217981) FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57904) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 187020) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 208541) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50947) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082) FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132) FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291) -FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 286199) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 317671) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65887) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896) @@ -97,8 +99,8 @@ FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalid FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27503) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 292746) -FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 193512) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 324108) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 214989) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30688) FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13293) @@ -111,7 +113,7 @@ FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOw FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61031) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 139404) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62781) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 215285) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239409) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 138025) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164969) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12946) @@ -123,7 +125,7 @@ FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubs FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102524) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89309) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20148) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 194369) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218493) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114541) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 125867) FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 75017) @@ -156,16 +158,16 @@ FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Reve FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 54867) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 49607) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 50896) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 164812) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186697) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17924) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 210) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 37396) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 52130) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54413) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 30996) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 28809) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 31092) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 31569) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14981) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 176478) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 200618) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27655) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57797) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15001) @@ -181,7 +183,7 @@ FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 102439) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87245) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18049) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191894) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 216026) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42023) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12891) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684) @@ -189,7 +191,7 @@ FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35594) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25955) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25261) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28242) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57754) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57732) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26434) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152708) @@ -206,12 +208,12 @@ FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 96 FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12253) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19199) FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 12995) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12239111) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13158901) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16571) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13301) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20448) FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 12931) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12239115) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13158905) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18493) @@ -228,10 +230,10 @@ FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79131) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) -Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20695) -Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MinimumGas() (gas: 20135) -Gas_FulfillRequest_Success:test_FulfillRequest_Success_MaximumGas() (gas: 498083) -Gas_FulfillRequest_Success:test_FulfillRequest_Success_MinimumGas() (gas: 199286) +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20717) +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MinimumGas() (gas: 20157) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MaximumGas() (gas: 501825) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MinimumGas() (gas: 203029) Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38546) -Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 979631) -Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 157578) \ No newline at end of file +Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 1003809) +Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 181701) \ No newline at end of file diff --git a/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol index 3abfd893186..b6b65c4e556 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol @@ -26,7 +26,9 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint96 juelsPerGas, uint256 l1FeeShareWei, uint96 callbackCostJuels, - uint96 totalCostJuels + uint72 donFeeJuels, + uint72 adminFeeJuels, + uint72 operationFeeJuels ); // ================================================================ @@ -47,6 +49,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { error UnauthorizedSender(); error MustBeSubOwner(address owner); error InvalidLinkWeiPrice(int256 linkWei); + error InvalidUsdLinkPrice(int256 usdLink); error PaymentTooLarge(); error NoTransmittersSet(); error InvalidCalldata(); @@ -61,12 +64,19 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint96 internal s_feePool; AggregatorV3Interface private s_linkToNativeFeed; + AggregatorV3Interface private s_linkToUsdFeed; // ================================================================ // | Initialization | // ================================================================ - constructor(address router, FunctionsBillingConfig memory config, address linkToNativeFeed) Routable(router) { + constructor( + address router, + FunctionsBillingConfig memory config, + address linkToNativeFeed, + address linkToUsdFeed + ) Routable(router) { s_linkToNativeFeed = AggregatorV3Interface(linkToNativeFeed); + s_linkToUsdFeed = AggregatorV3Interface(linkToUsdFeed); updateConfig(config); } @@ -95,22 +105,28 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // ================================================================ /// @inheritdoc IFunctionsBilling - function getDONFee(bytes memory /* requestData */) public view override returns (uint72) { - return s_config.donFee; + function getDONFeeJuels(bytes memory /* requestData */) public view override returns (uint72) { + // s_config.donFee is in cents of USD. Get Juel amount then convert to dollars. + return SafeCast.toUint72(_getJuelsFromUsd(s_config.donFeeCentsUsd) / 100); } /// @inheritdoc IFunctionsBilling - function getAdminFee() public view override returns (uint72) { + function getOperationFeeJuels() public view override returns (uint72) { + // s_config.donFee is in cents of USD. Get Juel amount then convert to dollars. + return SafeCast.toUint72(_getJuelsFromUsd(s_config.operationFeeCentsUsd) / 100); + } + + /// @inheritdoc IFunctionsBilling + function getAdminFeeJuels() public view override returns (uint72) { return _getRouter().getAdminFee(); } /// @inheritdoc IFunctionsBilling function getWeiPerUnitLink() public view returns (uint256) { - FunctionsBillingConfig memory config = s_config; (, int256 weiPerUnitLink, , uint256 timestamp, ) = s_linkToNativeFeed.latestRoundData(); // solhint-disable-next-line not-rely-on-time - if (config.feedStalenessSeconds < block.timestamp - timestamp && config.feedStalenessSeconds > 0) { - return config.fallbackNativePerUnitLink; + if (s_config.feedStalenessSeconds < block.timestamp - timestamp && s_config.feedStalenessSeconds > 0) { + return s_config.fallbackNativePerUnitLink; } if (weiPerUnitLink <= 0) { revert InvalidLinkWeiPrice(weiPerUnitLink); @@ -124,6 +140,26 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return SafeCast.toUint96((1e18 * amountWei) / getWeiPerUnitLink()); } + /// @inheritdoc IFunctionsBilling + function getUsdPerUnitLink() public view returns (uint256, uint8) { + (, int256 usdPerUnitLink, , uint256 timestamp, ) = s_linkToUsdFeed.latestRoundData(); + // solhint-disable-next-line not-rely-on-time + if (s_config.feedStalenessSeconds < block.timestamp - timestamp && s_config.feedStalenessSeconds > 0) { + return (s_config.fallbackUsdPerUnitLink, s_config.fallbackUsdPerUnitLinkDecimals); + } + if (usdPerUnitLink <= 0) { + revert InvalidUsdLinkPrice(usdPerUnitLink); + } + return (uint256(usdPerUnitLink), s_linkToUsdFeed.decimals()); + } + + function _getJuelsFromUsd(uint256 amountUsd) private view returns (uint96) { + (uint256 usdPerLink, uint8 decimals) = getUsdPerUnitLink(); + // (usd) * (10**18 juels/link) * (10**decimals) / (link / usd) = juels + // There are only 1e9*1e18 = 1e27 juels in existence, should not exceed uint96 (2^96 ~ 7e28) + return SafeCast.toUint96((amountUsd * 10 ** (18 + decimals)) / usdPerLink); + } + // ================================================================ // | Cost Estimation | // ================================================================ @@ -140,9 +176,10 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { if (gasPriceWei > REASONABLE_GAS_PRICE_CEILING) { revert InvalidCalldata(); } - uint72 adminFee = getAdminFee(); - uint72 donFee = getDONFee(data); - return _calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee); + uint72 adminFee = getAdminFeeJuels(); + uint72 donFee = getDONFeeJuels(data); + uint72 operationFee = getOperationFeeJuels(); + return _calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee, operationFee); } /// @notice Estimate the cost in Juels of LINK @@ -151,8 +188,9 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { function _calculateCostEstimate( uint32 callbackGasLimit, uint256 gasPriceWei, - uint72 donFee, - uint72 adminFee + uint72 donFeeJuels, + uint72 adminFeeJuels, + uint72 operationFeeJuels ) internal view returns (uint96) { // If gas price is less than the minimum fulfillment gas price, override to using the minimum if (gasPriceWei < s_config.minimumEstimateGasPriceWei) { @@ -167,7 +205,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint256 l1FeeWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); uint96 estimatedGasReimbursementJuels = _getJuelsFromWei((gasPriceWithOverestimation * executionGas) + l1FeeWei); - uint96 feesJuels = uint96(donFee) + uint96(adminFee); + uint96 feesJuels = uint96(donFeeJuels) + uint96(adminFeeJuels) + uint96(operationFeeJuels); return estimatedGasReimbursementJuels + feesJuels; } @@ -182,20 +220,20 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { /// @return commitment - The parameters of the request that must be held consistent at response time function _startBilling( FunctionsResponse.RequestMeta memory request - ) internal returns (FunctionsResponse.Commitment memory commitment) { - FunctionsBillingConfig memory config = s_config; - + ) internal returns (FunctionsResponse.Commitment memory commitment, uint72 operationFee) { // Nodes should support all past versions of the structure - if (request.dataVersion > config.maxSupportedRequestDataVersion) { + if (request.dataVersion > s_config.maxSupportedRequestDataVersion) { revert UnsupportedRequestDataVersion(); } - uint72 donFee = getDONFee(request.data); + uint72 donFee = getDONFeeJuels(request.data); + operationFee = getOperationFeeJuels(); uint96 estimatedTotalCostJuels = _calculateCostEstimate( request.callbackGasLimit, tx.gasprice, donFee, - request.adminFee + request.adminFee, + operationFee ); // Check that subscription can afford the estimated cost @@ -203,7 +241,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { revert InsufficientBalance(); } - uint32 timeoutTimestamp = uint32(block.timestamp + config.requestTimeoutSeconds); + uint32 timeoutTimestamp = uint32(block.timestamp + s_config.requestTimeoutSeconds); bytes32 requestId = keccak256( abi.encode( address(this), @@ -230,13 +268,13 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { timeoutTimestamp: timeoutTimestamp, requestId: requestId, donFee: donFee, - gasOverheadBeforeCallback: config.gasOverheadBeforeCallback, - gasOverheadAfterCallback: config.gasOverheadAfterCallback + gasOverheadBeforeCallback: s_config.gasOverheadBeforeCallback, + gasOverheadAfterCallback: s_config.gasOverheadAfterCallback }); s_requestCommitments[requestId] = keccak256(abi.encode(commitment)); - return commitment; + return (commitment, operationFee); } /// @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription @@ -268,9 +306,24 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { response, err, juelsPerGas, - gasOverheadJuels + commitment.donFee, // cost without callback or admin fee, those will be added by the Router + // The following line represents: "cost without callback or admin fee, those will be added by the Router" + // But because the _offchain_ Commitment is using operation fee in the place of the admin fee, this now adds admin fee (actually operation fee) + // Admin fee is configured to 0 in the Router + gasOverheadJuels + commitment.donFee + commitment.adminFee, msg.sender, - commitment + FunctionsResponse.Commitment({ + adminFee: 0, // The Router should have adminFee set to 0. If it does not this will cause fulfillments to fail with INVALID_COMMITMENT instead of carrying out incorrect bookkeeping. + coordinator: commitment.coordinator, + client: commitment.client, + subscriptionId: commitment.subscriptionId, + callbackGasLimit: commitment.callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels, + timeoutTimestamp: commitment.timeoutTimestamp, + requestId: commitment.requestId, + donFee: commitment.donFee, + gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: commitment.gasOverheadAfterCallback + }) ); // The router will only pay the DON on successfully processing the fulfillment @@ -282,19 +335,23 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { ) { delete s_requestCommitments[requestId]; // Reimburse the transmitter for the fulfillment gas cost - s_withdrawableTokens[msg.sender] = gasOverheadJuels + callbackCostJuels; + s_withdrawableTokens[msg.sender] += gasOverheadJuels + callbackCostJuels; // Put donFee into the pool of fees, to be split later // Saves on storage writes that would otherwise be charged to the user s_feePool += commitment.donFee; + // Pay the operation fee to the Coordinator owner + s_withdrawableTokens[_owner()] += commitment.adminFee; // OperationFee is used in the slot for Admin Fee in the Offchain Commitment. Admin Fee is set to 0 in the Router (enforced by line 316 in FunctionsBilling.sol). emit RequestBilled({ requestId: requestId, juelsPerGas: juelsPerGas, l1FeeShareWei: l1FeeShareWei, callbackCostJuels: callbackCostJuels, - totalCostJuels: gasOverheadJuels + callbackCostJuels + commitment.donFee + commitment.adminFee + donFeeJuels: commitment.donFee, + // The following two lines are because of OperationFee being used in the Offchain Commitment + adminFeeJuels: 0, + operationFeeJuels: commitment.adminFee }); } - return resultCode; } @@ -377,4 +434,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { function _isExistingRequest(bytes32 requestId) internal view returns (bool) { return s_requestCommitments[requestId] != bytes32(0); } + + // Overriden in FunctionsCoordinator.sol + function _owner() internal view virtual returns (address owner); } diff --git a/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol index 9b3e0cc7d7b..a70a8a752bb 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol @@ -17,7 +17,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli /// @inheritdoc ITypeAndVersion // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - string public constant override typeAndVersion = "Functions Coordinator v1.2.0"; + string public constant override typeAndVersion = "Functions Coordinator v1.3.0"; event OracleRequest( bytes32 indexed requestId, @@ -43,8 +43,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli constructor( address router, FunctionsBillingConfig memory config, - address linkToNativeFeed - ) OCR2Base() FunctionsBilling(router, config, linkToNativeFeed) {} + address linkToNativeFeed, + address linkToUsdFeed + ) OCR2Base() FunctionsBilling(router, config, linkToNativeFeed, linkToUsdFeed) {} /// @inheritdoc IFunctionsCoordinator function getThresholdPublicKey() external view override returns (bytes memory) { @@ -80,10 +81,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli /// @dev check if node is in current transmitter list function _isTransmitter(address node) internal view returns (bool) { - address[] memory nodes = s_transmitters; // Bounded by "maxNumOracles" on OCR2Abstract.sol - for (uint256 i = 0; i < nodes.length; ++i) { - if (nodes[i] == node) { + for (uint256 i = 0; i < s_transmitters.length; ++i) { + if (s_transmitters[i] == node) { return true; } } @@ -94,7 +94,8 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli function startRequest( FunctionsResponse.RequestMeta calldata request ) external override onlyRouter returns (FunctionsResponse.Commitment memory commitment) { - commitment = _startBilling(request); + uint72 operationFee; + (commitment, operationFee) = _startBilling(request); emit OracleRequest( commitment.requestId, @@ -107,7 +108,21 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli request.dataVersion, request.flags, request.callbackGasLimit, - commitment + FunctionsResponse.Commitment({ + coordinator: commitment.coordinator, + client: commitment.client, + subscriptionId: commitment.subscriptionId, + callbackGasLimit: commitment.callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels, + timeoutTimestamp: commitment.timeoutTimestamp, + requestId: commitment.requestId, + donFee: commitment.donFee, + gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: commitment.gasOverheadAfterCallback, + // The following line is done to use the Coordinator's operationFee in place of the Router's operation fee + // With this in place the Router.adminFee must be set to 0 in the Router. + adminFee: operationFee + }) ); return commitment; @@ -205,4 +220,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli function _onlyOwner() internal view override { _validateOwnership(); } + + /// @dev Used in FunctionsBilling.sol + function _owner() internal view override returns (address owner) { + return this.owner(); + } } diff --git a/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol index 0bd7817f779..79806f1eb18 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol @@ -7,14 +7,23 @@ interface IFunctionsBilling { /// @return weiPerUnitLink - The amount of WEI in one LINK function getWeiPerUnitLink() external view returns (uint256); + /// @notice Return the current conversion from LINK to USD from the configured Chainlink data feed + /// @return weiPerUnitLink - The amount of USD that one LINK is worth + /// @return decimals - The number of decimals that should be represented in the price feed's response + function getUsdPerUnitLink() external view returns (uint256, uint8); + /// @notice Determine the fee that will be split between Node Operators for servicing a request /// @param requestCBOR - CBOR encoded Chainlink Functions request data, use FunctionsRequest library to encode a request /// @return fee - Cost in Juels (1e18) of LINK - function getDONFee(bytes memory requestCBOR) external view returns (uint72); + function getDONFeeJuels(bytes memory requestCBOR) external view returns (uint72); + + /// @notice Determine the fee that will be paid to the Coordinator owner for operating the network + /// @return fee - Cost in Juels (1e18) of LINK + function getOperationFeeJuels() external view returns (uint72); /// @notice Determine the fee that will be paid to the Router owner for operating the network /// @return fee - Cost in Juels (1e18) of LINK - function getAdminFee() external view returns (uint72); + function getAdminFeeJuels() external view returns (uint72); /// @notice Estimate the total cost that will be charged to a subscription to make a request: transmitter gas re-reimbursement, plus DON fee, plus Registry fee /// @param - subscriptionId An identifier of the billing account @@ -53,9 +62,12 @@ struct FunctionsBillingConfig { uint32 feedStalenessSeconds; // ║ How long before we consider the feed price to be stale and fallback to fallbackNativePerUnitLink. uint32 gasOverheadBeforeCallback; // ║ Represents the average gas execution cost before the fulfillment callback. This amount is always billed for every request. uint32 gasOverheadAfterCallback; // ║ Represents the average gas execution cost after the fulfillment callback. This amount is always billed for every request. - uint72 donFee; // ║ Additional flat fee (in Juels of LINK) that will be split between Node Operators. Max value is 2^80 - 1 == 1.2m LINK. uint40 minimumEstimateGasPriceWei; // ║ The lowest amount of wei that will be used as the tx.gasprice when estimating the cost to fulfill the request - uint16 maxSupportedRequestDataVersion; // ═══════╝ The highest support request data version supported by the node. All lower versions should also be supported. + uint16 maxSupportedRequestDataVersion; // ║ The highest support request data version supported by the node. All lower versions should also be supported. + uint64 fallbackUsdPerUnitLink; // ║ Fallback LINK / USD conversion rate if the data feed is stale + uint8 fallbackUsdPerUnitLinkDecimals; // ════════╝ Fallback LINK / USD conversion rate decimal places if the data feed is stale uint224 fallbackNativePerUnitLink; // ═══════════╗ Fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale uint32 requestTimeoutSeconds; // ════════════════╝ How many seconds it takes before we consider a request to be timed out + uint16 donFeeCentsUsd; // ═══════════════════════════════╗ Additional flat fee (denominated in cents of USD, paid as LINK) that will be split between Node Operators. + uint16 operationFeeCentsUsd; // ═════════════════════════╝ Additional flat fee (denominated in cents of USD, paid as LINK) that will be paid to the owner of the Coordinator contract. } diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol index 66640003427..774fe4e875c 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol @@ -32,7 +32,7 @@ contract FunctionsBilling_GetConfig is FunctionsRouterSetup { assertEq(config.gasOverheadBeforeCallback, getCoordinatorConfig().gasOverheadBeforeCallback); assertEq(config.gasOverheadAfterCallback, getCoordinatorConfig().gasOverheadAfterCallback); assertEq(config.requestTimeoutSeconds, getCoordinatorConfig().requestTimeoutSeconds); - assertEq(config.donFee, getCoordinatorConfig().donFee); + assertEq(config.donFeeCentsUsd, getCoordinatorConfig().donFeeCentsUsd); assertEq(config.maxSupportedRequestDataVersion, getCoordinatorConfig().maxSupportedRequestDataVersion); assertEq(config.fulfillmentGasPriceOverEstimationBP, getCoordinatorConfig().fulfillmentGasPriceOverEstimationBP); assertEq(config.fallbackNativePerUnitLink, getCoordinatorConfig().fallbackNativePerUnitLink); @@ -46,15 +46,19 @@ contract FunctionsBilling_UpdateConfig is FunctionsRouterSetup { function setUp() public virtual override { FunctionsRouterSetup.setUp(); + // Multiply all config values by 2 to confirm that they change configToSet = FunctionsBillingConfig({ feedStalenessSeconds: getCoordinatorConfig().feedStalenessSeconds * 2, gasOverheadAfterCallback: getCoordinatorConfig().gasOverheadAfterCallback * 2, gasOverheadBeforeCallback: getCoordinatorConfig().gasOverheadBeforeCallback * 2, requestTimeoutSeconds: getCoordinatorConfig().requestTimeoutSeconds * 2, - donFee: getCoordinatorConfig().donFee * 2, + donFeeCentsUsd: getCoordinatorConfig().donFeeCentsUsd * 2, + operationFeeCentsUsd: getCoordinatorConfig().operationFeeCentsUsd * 2, maxSupportedRequestDataVersion: getCoordinatorConfig().maxSupportedRequestDataVersion * 2, fulfillmentGasPriceOverEstimationBP: getCoordinatorConfig().fulfillmentGasPriceOverEstimationBP * 2, fallbackNativePerUnitLink: getCoordinatorConfig().fallbackNativePerUnitLink * 2, + fallbackUsdPerUnitLink: getCoordinatorConfig().fallbackUsdPerUnitLink * 2, + fallbackUsdPerUnitLinkDecimals: getCoordinatorConfig().fallbackUsdPerUnitLinkDecimals * 2, minimumEstimateGasPriceWei: getCoordinatorConfig().minimumEstimateGasPriceWei * 2 }); } @@ -86,34 +90,53 @@ contract FunctionsBilling_UpdateConfig is FunctionsRouterSetup { assertEq(config.gasOverheadAfterCallback, configToSet.gasOverheadAfterCallback); assertEq(config.gasOverheadBeforeCallback, configToSet.gasOverheadBeforeCallback); assertEq(config.requestTimeoutSeconds, configToSet.requestTimeoutSeconds); - assertEq(config.donFee, configToSet.donFee); + assertEq(config.donFeeCentsUsd, configToSet.donFeeCentsUsd); + assertEq(config.operationFeeCentsUsd, configToSet.operationFeeCentsUsd); assertEq(config.maxSupportedRequestDataVersion, configToSet.maxSupportedRequestDataVersion); assertEq(config.fulfillmentGasPriceOverEstimationBP, configToSet.fulfillmentGasPriceOverEstimationBP); assertEq(config.fallbackNativePerUnitLink, configToSet.fallbackNativePerUnitLink); assertEq(config.minimumEstimateGasPriceWei, configToSet.minimumEstimateGasPriceWei); + assertEq(config.fallbackUsdPerUnitLink, configToSet.fallbackUsdPerUnitLink); + assertEq(config.fallbackUsdPerUnitLinkDecimals, configToSet.fallbackUsdPerUnitLinkDecimals); } } /// @notice #getDONFee -contract FunctionsBilling_GetDONFee is FunctionsRouterSetup { - function test_GetDONFee_Success() public { +contract FunctionsBilling_GetDONFeeJuels is FunctionsRouterSetup { + function test_GetDONFeeJuels_Success() public { // Send as stranger vm.stopPrank(); vm.startPrank(STRANGER_ADDRESS); - uint72 donFee = s_functionsCoordinator.getDONFee(new bytes(0)); - assertEq(donFee, s_donFee); + uint72 donFee = s_functionsCoordinator.getDONFeeJuels(new bytes(0)); + uint72 expectedDonFee = uint72(((s_donFee * 10 ** (18 + LINK_USD_DECIMALS)) / uint256(LINK_USD_RATE)) / 100); + assertEq(donFee, expectedDonFee); + } +} + +/// @notice #getOperationFee +contract FunctionsBilling_GetOperationFee is FunctionsRouterSetup { + function test_GetOperationFeeJuels_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint72 operationFee = s_functionsCoordinator.getOperationFeeJuels(); + uint72 expectedOperationFee = uint72( + ((s_operationFee * 10 ** (18 + LINK_USD_DECIMALS)) / uint256(LINK_USD_RATE)) / 100 + ); + assertEq(operationFee, expectedOperationFee); } } /// @notice #getAdminFee -contract FunctionsBilling_GetAdminFee is FunctionsRouterSetup { - function test_GetAdminFee_Success() public { +contract FunctionsBilling_GetAdminFeeJuels is FunctionsRouterSetup { + function test_GetAdminFeeJuels_Success() public { // Send as stranger vm.stopPrank(); vm.startPrank(STRANGER_ADDRESS); - uint72 adminFee = s_functionsCoordinator.getAdminFee(); + uint72 adminFee = s_functionsCoordinator.getAdminFeeJuels(); assertEq(adminFee, s_adminFee); } } @@ -183,7 +206,10 @@ contract FunctionsBilling_EstimateCost is FunctionsSubscriptionSetup { callbackGasLimit, gasPriceWei ); - uint96 expectedCostEstimate = 51110500000000200; + uint96 expectedCostEstimate = 51110500000000000 + + s_adminFee + + s_functionsCoordinator.getDONFeeJuels(requestData) + + s_functionsCoordinator.getOperationFeeJuels(); assertEq(costEstimate, expectedCostEstimate); } @@ -208,7 +234,10 @@ contract FunctionsBilling_EstimateCost is FunctionsSubscriptionSetup { callbackGasLimit, gasPriceWei ); - uint96 expectedCostEstimate = 255552500000000200; + uint96 expectedCostEstimate = 255552500000000000 + + s_adminFee + + s_functionsCoordinator.getDONFeeJuels(requestData) + + s_functionsCoordinator.getOperationFeeJuels(); assertEq(costEstimate, expectedCostEstimate); } } @@ -276,17 +305,15 @@ contract FunctionsBilling__FulfillAndBill is FunctionsClientRequestSetup { uint96 juelsPerGas, uint256 l1FeeShareWei, uint96 callbackCostJuels, - uint96 totalCostJuels + uint72 donFee, + uint72 adminFee, + uint72 operationFee ); function test__FulfillAndBill_Success() public { uint96 juelsPerGas = uint96((1e18 * TX_GASPRICE_START) / uint256(LINK_ETH_RATE)); uint96 callbackCostGas = 5072; // Taken manually uint96 callbackCostJuels = juelsPerGas * callbackCostGas; - uint96 gasOverheadJuels = juelsPerGas * - (getCoordinatorConfig().gasOverheadBeforeCallback + getCoordinatorConfig().gasOverheadAfterCallback); - - uint96 totalCostJuels = gasOverheadJuels + callbackCostJuels + s_donFee + s_adminFee; // topic0 (function signature, always checked), check topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true). bool checkTopic1 = true; @@ -294,7 +321,15 @@ contract FunctionsBilling__FulfillAndBill is FunctionsClientRequestSetup { bool checkTopic3 = false; bool checkData = true; vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); - emit RequestBilled(s_requests[1].requestId, juelsPerGas, 0, callbackCostJuels, totalCostJuels); + emit RequestBilled( + s_requests[1].requestId, + juelsPerGas, + 0, + callbackCostJuels, + s_functionsCoordinator.getDONFeeJuels(new bytes(0)), + s_adminFee, + s_functionsCoordinator.getOperationFeeJuels() + ); FunctionsResponse.FulfillResult resultCode = s_functionsCoordinator.fulfillAndBill_HARNESS( s_requests[1].requestId, @@ -377,7 +412,7 @@ contract FunctionsBilling_OracleWithdraw is FunctionsMultipleFulfillmentsSetup { vm.stopPrank(); vm.startPrank(NOP_TRANSMITTER_ADDRESS_1); - uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / 3; + uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / s_requestsFulfilled; // Attempt to withdraw half of balance uint96 halfBalance = expectedTransmitterBalance / 2; @@ -394,33 +429,49 @@ contract FunctionsBilling_OracleWithdraw is FunctionsMultipleFulfillmentsSetup { uint256[4] memory transmitterBalancesBefore = _getTransmitterBalances(); _assertTransmittersAllHaveBalance(transmitterBalancesBefore, 0); - // Send as transmitter 1, which has transmitted 1 report + // Send as transmitter 1, which has transmitted 2 reports vm.stopPrank(); vm.startPrank(NOP_TRANSMITTER_ADDRESS_1); // Attempt to withdraw with no amount, which will withdraw the full balance s_functionsCoordinator.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, 0); - // 3 report transmissions have been made - uint96 totalDonFees = s_donFee * 3; - // 4 transmitters will share the DON fees - uint96 donFeeShare = totalDonFees / 4; - uint96 expectedTransmitterBalance = ((s_fulfillmentCoordinatorBalance - totalDonFees) / 3) + donFeeShare; + uint96 totalOperationFees = s_functionsCoordinator.getOperationFeeJuels() * s_requestsFulfilled; + uint96 totalDonFees = s_functionsCoordinator.getDONFeeJuels(new bytes(0)) * s_requestsFulfilled; + uint96 donFeeShare = totalDonFees / uint8(s_transmitters.length); + uint96 expectedBalancePerFulfillment = ((s_fulfillmentCoordinatorBalance - totalOperationFees - totalDonFees) / + s_requestsFulfilled); uint256[4] memory transmitterBalancesAfter = _getTransmitterBalances(); - assertEq(transmitterBalancesAfter[0], expectedTransmitterBalance); + // Transmitter 1 has transmitted twice + assertEq(transmitterBalancesAfter[0], (expectedBalancePerFulfillment * 2) + donFeeShare); assertEq(transmitterBalancesAfter[1], 0); assertEq(transmitterBalancesAfter[2], 0); assertEq(transmitterBalancesAfter[3], 0); } + + function test_OracleWithdraw_SuccessCoordinatorOwner() public { + // Send as Coordinator Owner + address coordinatorOwner = s_functionsCoordinator.owner(); + vm.stopPrank(); + vm.startPrank(coordinatorOwner); + + uint256 coordinatorOwnerBalanceBefore = s_linkToken.balanceOf(coordinatorOwner); + + // Attempt to withdraw with no amount, which will withdraw the full balance + s_functionsCoordinator.oracleWithdraw(coordinatorOwner, 0); + + // 4 report transmissions have been made + uint96 totalOperationFees = s_functionsCoordinator.getOperationFeeJuels() * s_requestsFulfilled; + + uint256 coordinatorOwnerBalanceAfter = s_linkToken.balanceOf(coordinatorOwner); + assertEq(coordinatorOwnerBalanceBefore + totalOperationFees, coordinatorOwnerBalanceAfter); + } } /// @notice #oracleWithdrawAll contract FunctionsBilling_OracleWithdrawAll is FunctionsMultipleFulfillmentsSetup { function setUp() public virtual override { - // Use no DON fee so that a transmitter has a balance of 0 - s_donFee = 0; - FunctionsMultipleFulfillmentsSetup.setUp(); } @@ -439,22 +490,28 @@ contract FunctionsBilling_OracleWithdrawAll is FunctionsMultipleFulfillmentsSetu s_functionsCoordinator.oracleWithdrawAll(); - uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / 3; + uint96 totalOperationFees = s_functionsCoordinator.getOperationFeeJuels() * s_requestsFulfilled; + uint96 totalDonFees = s_functionsCoordinator.getDONFeeJuels(new bytes(0)) * s_requestsFulfilled; + uint96 donFeeShare = totalDonFees / uint8(s_transmitters.length); + uint96 expectedBalancePerFulfillment = ((s_fulfillmentCoordinatorBalance - totalOperationFees - totalDonFees) / + s_requestsFulfilled); uint256[4] memory transmitterBalancesAfter = _getTransmitterBalances(); - assertEq(transmitterBalancesAfter[0], expectedTransmitterBalance); - assertEq(transmitterBalancesAfter[1], expectedTransmitterBalance); - assertEq(transmitterBalancesAfter[2], expectedTransmitterBalance); - // Transmitter 4 has no balance - assertEq(transmitterBalancesAfter[3], 0); + // Transmitter 1 has transmitted twice + assertEq(transmitterBalancesAfter[0], (expectedBalancePerFulfillment * 2) + donFeeShare); + // Transmitter 2 and 3 have transmitted once + assertEq(transmitterBalancesAfter[1], expectedBalancePerFulfillment + donFeeShare); + assertEq(transmitterBalancesAfter[2], expectedBalancePerFulfillment + donFeeShare); + // Transmitter 4 only not transmitted, it only has its share of the DON fees + assertEq(transmitterBalancesAfter[3], donFeeShare); } } /// @notice #_disperseFeePool contract FunctionsBilling__DisperseFeePool is FunctionsRouterSetup { function test__DisperseFeePool_RevertIfNotSet() public { - // Manually set s_feePool (at slot 11) to 1 to get past first check in _disperseFeePool - vm.store(address(s_functionsCoordinator), bytes32(uint256(11)), bytes32(uint256(1))); + // Manually set s_feePool (at slot 12) to 1 to get past first check in _disperseFeePool + vm.store(address(s_functionsCoordinator), bytes32(uint256(12)), bytes32(uint256(1))); vm.expectRevert(FunctionsBilling.NoTransmittersSet.selector); s_functionsCoordinator.disperseFeePool_HARNESS(); diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol index c21a2c090f7..3944c5873b1 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol @@ -14,7 +14,7 @@ import {FunctionsRouterSetup, FunctionsDONSetup, FunctionsSubscriptionSetup} fro /// @notice #constructor contract FunctionsCoordinator_Constructor is FunctionsRouterSetup { function test_Constructor_Success() public { - assertEq(s_functionsCoordinator.typeAndVersion(), "Functions Coordinator v1.2.0"); + assertEq(s_functionsCoordinator.typeAndVersion(), "Functions Coordinator v1.3.0"); assertEq(s_functionsCoordinator.owner(), OWNER_ADDRESS); } } @@ -189,8 +189,9 @@ contract FunctionsCoordinator_StartRequest is FunctionsSubscriptionSetup { ) ); + // WARNING: Kludge in place. Remove in contracts v2.0.0 FunctionsResponse.Commitment memory expectedComittment = FunctionsResponse.Commitment({ - adminFee: s_adminFee, + adminFee: s_functionsCoordinator.getOperationFeeJuels(), coordinator: address(s_functionsCoordinator), client: address(s_functionsClient), subscriptionId: s_subscriptionId, @@ -198,7 +199,7 @@ contract FunctionsCoordinator_StartRequest is FunctionsSubscriptionSetup { estimatedTotalCostJuels: costEstimate, timeoutTimestamp: timeoutTimestamp, requestId: expectedRequestId, - donFee: s_donFee, + donFee: s_functionsCoordinator.getDONFeeJuels(_requestData), gasOverheadBeforeCallback: getCoordinatorConfig().gasOverheadBeforeCallback, gasOverheadAfterCallback: getCoordinatorConfig().gasOverheadAfterCallback }); diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol index 43540ba02b8..62db3e467d6 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol @@ -518,7 +518,8 @@ contract FunctionsRouter_SendRequestToProposed is FunctionsSubscriptionSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1085,7 +1086,20 @@ contract FunctionsRouter_Fulfill is FunctionsClientRequestSetup { callbackGasLimit: callbackGasLimit }), requestId: requestId, - commitment: _commitment + commitment: _commitment, // This commitment contains the operationFee in place of adminFee + commitmentOnchain: FunctionsResponse.Commitment({ + coordinator: _commitment.coordinator, + client: _commitment.client, + subscriptionId: _commitment.subscriptionId, + callbackGasLimit: _commitment.callbackGasLimit, + estimatedTotalCostJuels: _commitment.estimatedTotalCostJuels, + timeoutTimestamp: _commitment.timeoutTimestamp, + requestId: _commitment.requestId, + donFee: _commitment.donFee, + gasOverheadBeforeCallback: _commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: _commitment.gasOverheadAfterCallback, + adminFee: s_adminFee + }) }); // Fulfill @@ -1271,7 +1285,8 @@ contract FunctionsRouter_GetProposedContractById is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1317,7 +1332,8 @@ contract FunctionsRouter_GetProposedContractSet is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1357,7 +1373,8 @@ contract FunctionsRouter_ProposeContractsUpdate is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1459,7 +1476,8 @@ contract FunctionsRouter_UpdateContracts is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol index d036b5354ef..a6dda5a94df 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol @@ -1233,15 +1233,15 @@ contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup { vm.expectRevert("Pausable: paused"); FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; s_functionsRouter.timeoutRequests(commitments); } function test_TimeoutRequests_RevertInvalidRequest() public { // Modify the commitment so that it doesn't match - s_requests[1].commitment.donFee = 123456789; + s_requests[1].commitmentOnchain.donFee = 123456789; FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); s_functionsRouter.timeoutRequests(commitments); } @@ -1249,7 +1249,7 @@ contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup { function test_TimeoutRequests_RevertIfTimeoutNotExceeded() public { vm.expectRevert(FunctionsSubscriptions.TimeoutNotExceeded.selector); FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; s_functionsRouter.timeoutRequests(commitments); } @@ -1269,10 +1269,10 @@ contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup { emit RequestTimedOut(s_requests[1].requestId); // Jump ahead in time past timeout timestamp - vm.warp(s_requests[1].commitment.timeoutTimestamp + 1); + vm.warp(s_requests[1].commitmentOnchain.timeoutTimestamp + 1); FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; s_functionsRouter.timeoutRequests(commitments); // Releases blocked balance and increments completed requests diff --git a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol index 296e61c040c..32dc53e42ab 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol @@ -20,17 +20,22 @@ contract FunctionsRouterSetup is BaseTest { FunctionsRouterHarness internal s_functionsRouter; FunctionsCoordinatorHarness internal s_functionsCoordinator; MockV3Aggregator internal s_linkEthFeed; + MockV3Aggregator internal s_linkUsdFeed; TermsOfServiceAllowList internal s_termsOfServiceAllowList; MockLinkToken internal s_linkToken; uint16 internal s_maxConsumersPerSubscription = 3; - uint72 internal s_adminFee = 100; - uint72 internal s_donFee = 100; + uint72 internal s_adminFee = 0; // Keep as 0. Setting this to anything else will cause fulfillments to fail with INVALID_COMMITMENT + uint16 internal s_donFee = 100; // $1 + uint16 internal s_operationFee = 100; // $1 bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175; uint16 s_subscriptionDepositMinimumRequests = 1; uint72 s_subscriptionDepositJuels = 11 * JUELS_PER_LINK; - int256 internal LINK_ETH_RATE = 6000000000000000; + int256 internal LINK_ETH_RATE = 6_000_000_000_000_000; + uint8 internal LINK_ETH_DECIMALS = 18; + int256 internal LINK_USD_RATE = 1_500_000_000; + uint8 internal LINK_USD_DECIMALS = 8; uint256 internal TOS_SIGNER_PRIVATE_KEY = 0x3; address internal TOS_SIGNER = vm.addr(TOS_SIGNER_PRIVATE_KEY); @@ -39,11 +44,13 @@ contract FunctionsRouterSetup is BaseTest { BaseTest.setUp(); s_linkToken = new MockLinkToken(); s_functionsRouter = new FunctionsRouterHarness(address(s_linkToken), getRouterConfig()); - s_linkEthFeed = new MockV3Aggregator(0, LINK_ETH_RATE); + s_linkEthFeed = new MockV3Aggregator(LINK_ETH_DECIMALS, LINK_ETH_RATE); + s_linkUsdFeed = new MockV3Aggregator(LINK_USD_DECIMALS, LINK_USD_RATE); s_functionsCoordinator = new FunctionsCoordinatorHarness( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); address[] memory initialAllowedSenders; address[] memory initialBlockedSenders; @@ -79,10 +86,13 @@ contract FunctionsRouterSetup is BaseTest { gasOverheadAfterCallback: 93_942, gasOverheadBeforeCallback: 105_000, requestTimeoutSeconds: 60 * 5, // 5 minutes - donFee: s_donFee, + donFeeCentsUsd: s_donFee, + operationFeeCentsUsd: s_operationFee, maxSupportedRequestDataVersion: 1, fulfillmentGasPriceOverEstimationBP: 5000, fallbackNativePerUnitLink: 5000000000000000, + fallbackUsdPerUnitLink: 1400000000, + fallbackUsdPerUnitLinkDecimals: 8, minimumEstimateGasPriceWei: 1000000000 // 1 gwei }); } @@ -94,22 +104,22 @@ contract FunctionsRouterSetup is BaseTest { /// @notice Set up to set the OCR configuration of the Coordinator contract contract FunctionsDONSetup is FunctionsRouterSetup { - uint256 internal NOP_SIGNER_PRIVATE_KEY_1 = 0x100; + uint256 internal NOP_SIGNER_PRIVATE_KEY_1 = 0x400; address internal NOP_SIGNER_ADDRESS_1 = vm.addr(NOP_SIGNER_PRIVATE_KEY_1); - uint256 internal NOP_SIGNER_PRIVATE_KEY_2 = 0x101; + uint256 internal NOP_SIGNER_PRIVATE_KEY_2 = 0x401; address internal NOP_SIGNER_ADDRESS_2 = vm.addr(NOP_SIGNER_PRIVATE_KEY_2); - uint256 internal NOP_SIGNER_PRIVATE_KEY_3 = 0x102; + uint256 internal NOP_SIGNER_PRIVATE_KEY_3 = 0x402; address internal NOP_SIGNER_ADDRESS_3 = vm.addr(NOP_SIGNER_PRIVATE_KEY_3); - uint256 internal NOP_SIGNER_PRIVATE_KEY_4 = 0x103; + uint256 internal NOP_SIGNER_PRIVATE_KEY_4 = 0x403; address internal NOP_SIGNER_ADDRESS_4 = vm.addr(NOP_SIGNER_PRIVATE_KEY_4); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_1 = 0x104; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_1 = 0x404; address internal NOP_TRANSMITTER_ADDRESS_1 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_1); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_2 = 0x105; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_2 = 0x405; address internal NOP_TRANSMITTER_ADDRESS_2 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_2); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_3 = 0x106; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_3 = 0x406; address internal NOP_TRANSMITTER_ADDRESS_3 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_3); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_4 = 0x107; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_4 = 0x407; address internal NOP_TRANSMITTER_ADDRESS_4 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_4); address[] internal s_signers; @@ -251,7 +261,8 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { struct Request { RequestData requestData; bytes32 requestId; - FunctionsResponse.Commitment commitment; + FunctionsResponse.Commitment commitment; // Offchain commitment that contains operation fee in the place of admin fee + FunctionsResponse.Commitment commitmentOnchain; // Commitment that is persisted as a hash in the Router } mapping(uint256 requestNumber => Request) s_requests; @@ -264,6 +275,8 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { uint96 s_fulfillmentRouterOwnerBalance = 0; uint96 s_fulfillmentCoordinatorBalance = 0; + uint8 s_requestsSent = 0; + uint8 s_requestsFulfilled = 0; function setUp() public virtual override { FunctionsSubscriptionSetup.setUp(); @@ -289,7 +302,13 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { uint96 gasOverheadJuels = juelsPerGas * ((getCoordinatorConfig().gasOverheadBeforeCallback + getCoordinatorConfig().gasOverheadAfterCallback)); uint96 callbackGasCostJuels = uint96(juelsPerGas * callbackGas); - return gasOverheadJuels + s_donFee + s_adminFee + callbackGasCostJuels; + bytes memory emptyData = new bytes(0); + return + gasOverheadJuels + + s_functionsCoordinator.getDONFeeJuels(emptyData) + + s_adminFee + + s_functionsCoordinator.getOperationFeeJuels() + + callbackGasCostJuels; } /// @notice Predicts the actual cost of a request @@ -299,7 +318,13 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { uint96 gasOverheadJuels = juelsPerGas * (getCoordinatorConfig().gasOverheadBeforeCallback + getCoordinatorConfig().gasOverheadAfterCallback); uint96 callbackGasCostJuels = uint96(juelsPerGas * gasUsed); - return gasOverheadJuels + s_donFee + s_adminFee + callbackGasCostJuels; + bytes memory emptyData = new bytes(0); + return + gasOverheadJuels + + s_functionsCoordinator.getDONFeeJuels(emptyData) + + s_adminFee + + s_functionsCoordinator.getOperationFeeJuels() + + callbackGasCostJuels; } /// @notice Send a request and store information about it in s_requests @@ -350,8 +375,22 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { callbackGasLimit: callbackGasLimit }), requestId: requestId, - commitment: commitment + commitment: commitment, // Has operationFee in place of adminFee + commitmentOnchain: FunctionsResponse.Commitment({ + coordinator: commitment.coordinator, + client: commitment.client, + subscriptionId: commitment.subscriptionId, + callbackGasLimit: commitment.callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels, + timeoutTimestamp: commitment.timeoutTimestamp, + requestId: commitment.requestId, + donFee: commitment.donFee, + gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: commitment.gasOverheadAfterCallback, + adminFee: s_adminFee + }) }); + s_requestsSent += 1; } /// @notice Send a request and store information about it in s_requests @@ -505,7 +544,7 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { // Send as transmitter vm.stopPrank(); - vm.startPrank(transmitter); + vm.startPrank(transmitter, transmitter); // Send report vm.recordLogs(); @@ -530,6 +569,7 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { // TODO: handle multiple requests s_fulfillmentCoordinatorBalance += totalCostJuels - s_adminFee; } + s_requestsFulfilled += 1; // Return prank to Owner vm.stopPrank(); @@ -632,7 +672,7 @@ contract FunctionsMultipleFulfillmentsSetup is FunctionsFulfillmentSetup { function setUp() public virtual override { FunctionsFulfillmentSetup.setUp(); - // Make 2 additional requests (1 already complete) + // Make 3 additional requests (1 already complete) // *** Request #2 *** // Send @@ -662,5 +702,17 @@ contract FunctionsMultipleFulfillmentsSetup is FunctionsFulfillmentSetup { bytes[] memory errors2 = new bytes[](1); errors2[0] = new bytes(0); _reportAndStore(requestNumberKeys2, results2, errors2, NOP_TRANSMITTER_ADDRESS_3, true); + + // *** Request #4 *** + // Send + _sendAndStoreRequest(4, sourceCode, secrets, args, bytesArgs, callbackGasLimit); + // Fulfill as transmitter #1 + uint256[] memory requestNumberKeys3 = new uint256[](1); + requestNumberKeys3[0] = 4; + string[] memory results3 = new string[](1); + results3[0] = "hello world!"; + bytes[] memory errors3 = new bytes[](1); + errors3[0] = new bytes(0); + _reportAndStore(requestNumberKeys3, results3, errors3, NOP_TRANSMITTER_ADDRESS_1, true); } } diff --git a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol index e4e9f7279a7..0de449f3a0e 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol @@ -10,14 +10,17 @@ import {FunctionsBillingConfig} from "../../../dev/v1_X/interfaces/IFunctionsBil /// @notice Contract to expose internal functions for testing purposes contract FunctionsCoordinatorHarness is FunctionsCoordinator { address s_linkToNativeFeed_HARNESS; + address s_linkToUsdFeed_HARNESS; address s_router_HARNESS; constructor( address router, FunctionsBillingConfig memory config, - address linkToNativeFeed - ) FunctionsCoordinator(router, config, linkToNativeFeed) { + address linkToNativeFeed, + address linkToUsdFeed + ) FunctionsCoordinator(router, config, linkToNativeFeed, linkToUsdFeed) { s_linkToNativeFeed_HARNESS = linkToNativeFeed; + s_linkToUsdFeed_HARNESS = linkToUsdFeed; s_router_HARNESS = router; } @@ -50,6 +53,10 @@ contract FunctionsCoordinatorHarness is FunctionsCoordinator { return s_linkToNativeFeed_HARNESS; } + function getLinkToUsdFeed_HARNESS() external view returns (address) { + return s_linkToUsdFeed_HARNESS; + } + function getRouter_HARNESS() external view returns (address) { return s_router_HARNESS; } @@ -58,14 +65,15 @@ contract FunctionsCoordinatorHarness is FunctionsCoordinator { uint32 callbackGasLimit, uint256 gasPriceWei, uint72 donFee, - uint72 adminFee + uint72 adminFee, + uint72 operationFee ) external view returns (uint96) { - return super._calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee); + return super._calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee, operationFee); } function startBilling_HARNESS( FunctionsResponse.RequestMeta memory request - ) external returns (FunctionsResponse.Commitment memory commitment) { + ) external returns (FunctionsResponse.Commitment memory commitment, uint72 operationFee) { return super._startBilling(request); } @@ -84,6 +92,10 @@ contract FunctionsCoordinatorHarness is FunctionsCoordinator { return super._disperseFeePool(); } + function owner_HARNESS() external view returns (address owner) { + return super._owner(); + } + // ================================================================ // | OCR2 | // ================================================================ diff --git a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol index abfec4c2de5..8703d2b254e 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol @@ -9,8 +9,9 @@ contract FunctionsCoordinatorTestHelper is FunctionsCoordinator { constructor( address router, FunctionsBillingConfig memory config, - address linkToNativeFeed - ) FunctionsCoordinator(router, config, linkToNativeFeed) {} + address linkToNativeFeed, + address linkToUsdFeed + ) FunctionsCoordinator(router, config, linkToNativeFeed, linkToUsdFeed) {} function callReport(bytes calldata report) external { address[MAX_NUM_ORACLES] memory signers; @@ -54,23 +55,4 @@ contract FunctionsCoordinatorTestHelper is FunctionsCoordinator { }) ); } - - function callReportWithSigners(bytes calldata report, address[MAX_NUM_ORACLES] memory /* signers */) external { - ( - bytes32[] memory requestIds, - bytes[] memory results, - bytes[] memory errors, - bytes[] memory onchainMetadata, - bytes[] memory offchainMetadata - ) = abi.decode(report, (bytes32[], bytes[], bytes[], bytes[], bytes[])); - _report( - DecodedReport({ - requestIds: requestIds, - results: results, - errors: errors, - onchainMetadata: onchainMetadata, - offchainMetadata: offchainMetadata - }) - ); - } } diff --git a/contracts/test/v0.8/functions/v1/RouterBase.test.ts b/contracts/test/v0.8/functions/v1/RouterBase.test.ts index 3a3b58b8f6b..92f9c7d320b 100644 --- a/contracts/test/v0.8/functions/v1/RouterBase.test.ts +++ b/contracts/test/v0.8/functions/v1/RouterBase.test.ts @@ -31,6 +31,7 @@ describe('FunctionsRouter - Base', () => { contracts.router.address, coordinatorConfig, contracts.mockLinkEth.address, + contracts.mockLinkUsd.address, ) const coordinator3 = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) @@ -38,6 +39,7 @@ describe('FunctionsRouter - Base', () => { contracts.router.address, coordinatorConfig, contracts.mockLinkEth.address, + contracts.mockLinkUsd.address, ) const coordinator4 = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) @@ -45,6 +47,7 @@ describe('FunctionsRouter - Base', () => { contracts.router.address, coordinatorConfig, contracts.mockLinkEth.address, + contracts.mockLinkUsd.address, ) await expect( diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts index ffe5468f136..dd3853c2d9d 100644 --- a/contracts/test/v0.8/functions/v1/utils.ts +++ b/contracts/test/v0.8/functions/v1/utils.ts @@ -26,6 +26,7 @@ export type FunctionsContracts = { client: Contract linkToken: Contract mockLinkEth: Contract + mockLinkUsd: Contract accessControl: Contract } @@ -94,11 +95,14 @@ export type CoordinatorConfig = { gasOverheadBeforeCallback: number gasOverheadAfterCallback: number requestTimeoutSeconds: number - donFee: number + donFeeCentsUsd: number maxSupportedRequestDataVersion: number fulfillmentGasPriceOverEstimationBP: number fallbackNativePerUnitLink: BigNumber minimumEstimateGasPriceWei: number + operationFeeCentsUsd: number + fallbackUsdPerUnitLink: number + fallbackUsdPerUnitLinkDecimals: number } const fallbackNativePerUnitLink = 5000000000000000 export const coordinatorConfig: CoordinatorConfig = { @@ -106,12 +110,18 @@ export const coordinatorConfig: CoordinatorConfig = { gasOverheadBeforeCallback: 44_615, gasOverheadAfterCallback: 44_615, requestTimeoutSeconds: 300, - donFee: 0, + donFeeCentsUsd: 0, maxSupportedRequestDataVersion: 1, fulfillmentGasPriceOverEstimationBP: 0, fallbackNativePerUnitLink: BigNumber.from(fallbackNativePerUnitLink), minimumEstimateGasPriceWei: 1000000000, + operationFeeCentsUsd: 0, + fallbackUsdPerUnitLink: 1500000000, + fallbackUsdPerUnitLinkDecimals: 8, } +const linkEthRate = '5021530000000000' +const linkUsdRate = '1500000000' + export const accessControlMockPublicKey = ethers.utils.getAddress( '0x32237412cC0321f56422d206e505dB4B3871AF5c', ) @@ -237,8 +247,6 @@ export function getSetupFactory(): () => { }) beforeEach(async () => { - const linkEthRate = BigNumber.from(5021530000000000) - // Deploy const linkToken = await factories.linkTokenFactory .connect(roles.defaultAccount) @@ -246,7 +254,12 @@ export function getSetupFactory(): () => { const mockLinkEth = await factories.mockAggregatorV3Factory.deploy( 0, - linkEthRate, + BigNumber.from(linkEthRate), + ) + + const mockLinkUsd = await factories.mockAggregatorV3Factory.deploy( + 0, + BigNumber.from(linkUsdRate), ) const router = await factories.functionsRouterFactory @@ -255,7 +268,12 @@ export function getSetupFactory(): () => { const coordinator = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) - .deploy(router.address, coordinatorConfig, mockLinkEth.address) + .deploy( + router.address, + coordinatorConfig, + mockLinkEth.address, + mockLinkUsd.address, + ) const initialAllowedSenders: string[] = [] const initialBlockedSenders: string[] = [] @@ -290,6 +308,7 @@ export function getSetupFactory(): () => { router, linkToken, mockLinkEth, + mockLinkUsd, accessControl, } }) diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index 07b1b5e1720..6099c541c69 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -35,11 +35,14 @@ type FunctionsBillingConfig struct { FeedStalenessSeconds uint32 GasOverheadBeforeCallback uint32 GasOverheadAfterCallback uint32 - DonFee *big.Int MinimumEstimateGasPriceWei *big.Int MaxSupportedRequestDataVersion uint16 + FallbackUsdPerUnitLink uint64 + FallbackUsdPerUnitLinkDecimals uint8 FallbackNativePerUnitLink *big.Int RequestTimeoutSeconds uint32 + DonFeeCentsUsd uint16 + OperationFeeCentsUsd uint16 } type FunctionsResponseCommitment struct { @@ -71,15 +74,15 @@ type FunctionsResponseRequestMeta struct { } var FunctionsCoordinatorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"type\":\"event\"},{\"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\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1FeeShareWei\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"callbackCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestBilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620057a9380380620057a983398101604081905262000034916200046d565b8282828233806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000139565b5050506001600160a01b038116620000ed57604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03908116608052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200012d82620001e4565b5050505050506200062c565b336001600160a01b03821603620001935760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee62000342565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160f01b026001600160f01b0364ffffffffff909216600160c81b0264ffffffffff60c81b196001600160481b03909416600160801b0293909316600160801b600160f01b031963ffffffff9586166c010000000000000000000000000263ffffffff60601b19978716680100000000000000000297909716600160401b600160801b0319998716640100000000026001600160401b0319909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e0830151610100840151909216600160e01b026001600160e01b0390921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906200033790839062000576565b60405180910390a150565b6200034c6200034e565b565b6000546001600160a01b031633146200034c5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000086565b80516001600160a01b0381168114620003c257600080fd5b919050565b60405161012081016001600160401b0381118282101715620003f957634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff81168114620003c257600080fd5b80516001600160481b0381168114620003c257600080fd5b805164ffffffffff81168114620003c257600080fd5b805161ffff81168114620003c257600080fd5b80516001600160e01b0381168114620003c257600080fd5b60008060008385036101608112156200048557600080fd5b6200049085620003aa565b935061012080601f1983011215620004a757600080fd5b620004b1620003c7565b9150620004c160208701620003ff565b8252620004d160408701620003ff565b6020830152620004e460608701620003ff565b6040830152620004f760808701620003ff565b60608301526200050a60a0870162000414565b60808301526200051d60c087016200042c565b60a08301526200053060e0870162000442565b60c08301526101006200054581880162000455565b60e084015262000557828801620003ff565b908301525091506200056d6101408501620003aa565b90509250925092565b815163ffffffff908116825260208084015182169083015260408084015182169083015260608084015191821690830152610120820190506080830151620005c960808401826001600160481b03169052565b5060a0830151620005e360a084018264ffffffffff169052565b5060c0830151620005fa60c084018261ffff169052565b5060e08301516200061660e08401826001600160e01b03169052565b506101009283015163ffffffff16919092015290565b6080516151376200067260003960008181610845015281816109d301528181610ca601528181610f3a0152818161104501528181611790015261357001526151376000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806381ff7048116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610560578063e4ddcea614610573578063f2fde38b1461058957600080fd5b8063c3f909d4146103b0578063d227d24514610528578063d328a91e1461055857600080fd5b8063a631571e116100bd578063a631571e1461035d578063afcb95d71461037d578063b1dc65a41461039d57600080fd5b806381ff7048146102b557806385b214cf146103225780638da5cb5b1461033557600080fd5b806366316d8d116101455780637f15e1661161011f5780637f15e16614610285578063814118341461029857806381f1b938146102ad57600080fd5b806366316d8d1461026257806379ba5097146102755780637d4807871461027d57600080fd5b8063181f5a7711610176578063181f5a77146101ba5780632a905ccc1461020c57806359b5b7ac1461022e57600080fd5b8063083a5466146101925780631112dadc146101a7575b600080fd5b6101a56101a0366004613aad565b61059c565b005b6101a56101b5366004613c56565b6105f1565b6101f66040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e322e300000000081525081565b6040516102039190613d7a565b60405180910390f35b610214610841565b60405168ffffffffffffffffff9091168152602001610203565b61021461023c366004613e1b565b50600854700100000000000000000000000000000000900468ffffffffffffffffff1690565b6101a5610270366004613eaa565b6108d7565b6101a5610a90565b6101a5610b92565b6101a5610293366004613aad565b610d92565b6102a0610de2565b6040516102039190613f34565b6101f6610e51565b6102ff60015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610203565b6101a5610330366004613f47565b610f22565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b61037061036b366004613f60565b610fd4565b60405161020391906140b5565b604080516001815260006020820181905291810191909152606001610203565b6101a56103ab366004614109565b611175565b61051b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830152700100000000000000000000000000000000810468ffffffffffffffffff166080830152790100000000000000000000000000000000000000000000000000810464ffffffffff1660a08301527e01000000000000000000000000000000000000000000000000000000000000900461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08301527c0100000000000000000000000000000000000000000000000000000000900490911661010082015290565b60405161020391906141c0565b61053b6105363660046142b0565b61178c565b6040516bffffffffffffffffffffffff9091168152602001610203565b6101f66118ec565b6101a561056e3660046143c9565b611943565b61057b6124bf565b604051908152602001610203565b6101a5610597366004614496565b612718565b6105a461272c565b60008190036105df576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105ec82848361454c565b505050565b6105f96127af565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff64ffffffffff909216790100000000000000000000000000000000000000000000000000027fffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90941670010000000000000000000000000000000002939093167fffff0000000000000000000000000000ffffffffffffffffffffffffffffffff63ffffffff9586166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9787166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e08301516101008401519092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906108369083906141c0565b60405180910390a150565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d29190614672565b905090565b6108df6127b7565b806bffffffffffffffffffffffff166000036109195750336000908152600a60205260409020546bffffffffffffffffffffffff16610973565b336000908152600a60205260409020546bffffffffffffffffffffffff80831691161015610973576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906109a09084906bffffffffffffffffffffffff166146be565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506109f57f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610a7457600080fd5b505af1158015610a88573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b9a6127af565b610ba26127b7565b6000610bac610de2565b905060005b8151811015610d8e576000600a6000848481518110610bd257610bd26146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610d7d576000600a6000858581518110610c3157610c316146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610cc87f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610cf557610cf56146e3565b6020026020010151836040518363ffffffff1660e01b8152600401610d4a92919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d6457600080fd5b505af1158015610d78573d6000803e3d6000fd5b505050505b50610d8781614712565b9050610bb1565b5050565b610d9a61272c565b6000819003610dd5576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105ec82848361454c565b60606006805480602002602001604051908101604052809291908181526020018280548015610e4757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e1c575b5050505050905090565b6060600d8054610e60906144b3565b9050600003610e9b576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610ea8906144b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed4906144b3565b8015610e475780601f10610ef657610100808354040283529160200191610e47565b820191906000526020600020905b815481529060010190602001808311610f0457509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f91576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416906108369083815260200190565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461109c576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110ad6110a88361474a565b612963565b90506110bf6060830160408401614496565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261110d60c0870160a08801614837565b61111f61016088016101408901614496565b6111298880614854565b61113b6101208b016101008c016148b9565b60208b01356111516101008d0160e08e016148d4565b8b604051611167999897969594939291906148f1565b60405180910390a35b919050565b6000806111828989612e01565b915091508115611193575050611782565b604080518b3580825262ffffff6020808f0135600881901c9290921690840152909290917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16111f08b8b8b8b8b8b612f8a565b60035460009060029061120e9060ff80821691610100900416614999565b61121891906149e1565b611223906001614999565b60ff169050888114611291576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610b0d565b888714611320576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f7265706f727420727320616e64207373206d757374206265206f66206571756160448201527f6c206c656e6774680000000000000000000000000000000000000000000000006064820152608401610b0d565b3360009081526004602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561136357611363614a03565b600281111561137457611374614a03565b905250905060028160200151600281111561139157611391614a03565b141580156113da57506006816000015160ff16815481106113b4576113b46146e3565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b15611441576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610b0d565b5050505061144d613a4c565b60008a8a60405161145f929190614a32565b604051908190038120611476918e90602001614a42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117725760006001848984602081106114df576114df6146e3565b6114ec91901a601b614999565b8e8e868181106114fe576114fe6146e3565b905060200201358d8d87818110611517576115176146e3565b9050602002013560405160008152602001604052604051611554949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611576573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156115f6576115f6614a03565b600281111561160757611607614a03565b905250925060018360200151600281111561162457611624614a03565b1461168b576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610b0d565b8251600090869060ff16601f81106116a5576116a56146e3565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611727576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610b0d565b8085846000015160ff16601f8110611741576117416146e3565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201525061176b81614712565b90506114c0565b50505061177e82613041565b5050505b5050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b15801561182c57600080fd5b505afa158015611840573d6000803e3d6000fd5b5050505066038d7ea4c68000821115611885576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061188f610841565b905060006118d287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061023c92505050565b90506118e085858385613190565b98975050505050505050565b6060600c80546118fb906144b3565b9050600003611936576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610ea8906144b3565b855185518560ff16601f8311156119b6576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610b0d565b80600003611a20576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610b0d565b818314611aae576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610b0d565b611ab9816003614a56565b8311611b21576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610b0d565b611b2961272c565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611b7090886132fd565b60055415611d2557600554600090611b8a90600190614a6d565b9050600060058281548110611ba157611ba16146e3565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611bdb57611bdb6146e3565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611c5b57611c5b614a80565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611cc457611cc4614a80565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611b70915050565b60005b8151518110156122dc57815180516000919083908110611d4a57611d4a6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611dcf576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7369676e6572206d757374206e6f7420626520656d70747900000000000000006044820152606401610b0d565b600073ffffffffffffffffffffffffffffffffffffffff1682602001518281518110611dfd57611dfd6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611e82576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d7074790000006044820152606401610b0d565b60006004600084600001518481518110611e9e57611e9e6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611ee857611ee8614a03565b14611f4f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610b0d565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611f8057611f806146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561202157612021614a03565b0217905550600091506120319050565b600460008460200151848151811061204b5761204b6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561209557612095614a03565b146120fc576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610b0d565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061212f5761212f6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156121d0576121d0614a03565b0217905550508251805160059250839081106121ee576121ee6146e3565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600691908390811061226a5761226a6146e3565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055806122d481614712565b915050611d28565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161239491849174010000000000000000000000000000000000000000900416614aaf565b92506101000a81548163ffffffff021916908363ffffffff1602179055506123f34630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613316565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986124aa988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614acc565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000080830482166060850152700100000000000000000000000000000000830468ffffffffffffffffff166080850152790100000000000000000000000000000000000000000000000000830464ffffffffff1660a0808601919091527e0100000000000000000000000000000000000000000000000000000000000090930461ffff1660c08501526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08601527c01000000000000000000000000000000000000000000000000000000009004909116610100840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa15801561264d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126719190614b7c565b5093505092505080426126849190614a6d565b836020015163ffffffff161080156126a657506000836020015163ffffffff16115b156126d457505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b60008213612711576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610b0d565b5092915050565b61272061272c565b612729816133c1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146127ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b0d565b565b6127ad61272c565b600b546bffffffffffffffffffffffff166000036127d157565b60006127db610de2565b8051909150600081900361281b576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b5460009061283a9083906bffffffffffffffffffffffff16614bcc565b905060005b828110156129055781600a600086848151811061285e5761285e6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166128c69190614bf7565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806128fe90614712565b905061283f565b506129108282614c1c565b600b80546000906129309084906bffffffffffffffffffffffff166146be565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c0100000000000000000000000081048316606083015268ffffffffffffffffff700100000000000000000000000000000000820416608083015264ffffffffff79010000000000000000000000000000000000000000000000000082041660a083015261ffff7e01000000000000000000000000000000000000000000000000000000000000909104811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08501527c0100000000000000000000000000000000000000000000000000000000900490931661010080840191909152850151919291161115612b1e576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854600090700100000000000000000000000000000000900468ffffffffffffffffff1690506000612b5b8560e001513a848860800151613190565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612bb7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083610100015163ffffffff1642612bd09190614c44565b905060003087604001518860a001518960c001516001612bf09190614c57565b8a5180516020918201206101008d015160e08e0151604051612ca498979695948c918c9132910173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a015267ffffffffffffffff97881660408a0152959096166060880152608087019390935261ffff9190911660a086015263ffffffff90811660c08601526bffffffffffffffffffffffff9190911660e0850152919091166101008301529091166101208201526101400190565b6040516020818303038152906040528051906020012090506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001846bffffffffffffffffffffffff168152602001886040015173ffffffffffffffffffffffffffffffffffffffff1681526020018860a0015167ffffffffffffffff1681526020018860e0015163ffffffff168152602001886080015168ffffffffffffffffff1681526020018568ffffffffffffffffff168152602001866040015163ffffffff1664ffffffffff168152602001866060015163ffffffff1664ffffffffff1681526020018363ffffffff16815250955085604051602001612db391906140b5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009384526007909252909120555092949350505050565b6000612e356040518060a0016040528060608152602001606081526020016060815260200160608152602001606081525090565b600080808080612e47888a018a614d53565b84519499509297509095509350915060ff16801580612e67575084518114155b80612e73575083518114155b80612e7f575082518114155b80612e8b575081518114155b15612ef2576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4669656c6473206d75737420626520657175616c206c656e67746800000000006044820152606401610b0d565b60005b81811015612f5857612f2e878281518110612f1257612f126146e3565b6020026020010151600090815260076020526040902054151590565b612f5857612f3d600183614a6d565b8103612f4857600198505b612f5181614712565b9050612ef5565b50506040805160a0810182529586526020860194909452928401919091526060830152608082015290505b9250929050565b6000612f97826020614a56565b612fa2856020614a56565b612fae88610144614c44565b612fb89190614c44565b612fc29190614c44565b612fcd906000614c44565b9050368114613038576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610b0d565b50505050505050565b80515160ff1660005b818110156105ec5760006130f38460000151838151811061306d5761306d6146e3565b60200260200101518560200151848151811061308b5761308b6146e3565b6020026020010151866040015185815181106130a9576130a96146e3565b6020026020010151876060015186815181106130c7576130c76146e3565b6020026020010151886080015187815181106130e5576130e56146e3565b6020026020010151886134b6565b9050600081600681111561310957613109614a03565b14806131265750600181600681111561312457613124614a03565b145b1561317f57835180518390811061313f5761313f6146e3565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b5061318981614712565b905061304a565b600854600090790100000000000000000000000000000000000000000000000000900464ffffffffff168410156131eb57600854790100000000000000000000000000000000000000000000000000900464ffffffffff1693505b600854600090612710906132059063ffffffff1687614a56565b61320f9190614e25565b6132199086614c44565b60085490915060009087906132529063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614aaf565b61325c9190614aaf565b63ffffffff16905060006132a66000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137ca92505050565b905060006132c7826132b88587614a56565b6132c29190614c44565b61390c565b905060006132e368ffffffffffffffffff808916908a16614bf7565b90506132ef8183614bf7565b9a9950505050505050505050565b6000613307610de2565b511115610d8e57610d8e6127b7565b6000808a8a8a8a8a8a8a8a8a60405160200161333a99989796959493929190614e39565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b0d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080848060200190518101906134cd9190614f05565b905060003a8261012001518361010001516134e89190614fcd565b64ffffffffff166134f99190614a56565b905060008460ff166135416000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137ca92505050565b61354b9190614e25565b9050600061355c6132c28385614c44565b905060006135693a61390c565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298e8e868b60e0015168ffffffffffffffffff16896135c89190614bf7565b338d6040518763ffffffff1660e01b81526004016135eb96959493929190614feb565b60408051808303816000875af1158015613609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362d9190615067565b9092509050600082600681111561364657613646614a03565b14806136635750600182600681111561366157613661614a03565b145b156137b95760008e8152600760205260408120556136818185614bf7565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0890151600b805468ffffffffffffffffff909216939092916136ed91859116614bf7565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508d7f90815c2e624694e8010bffad2bcefaf96af282ef1bc2ebc0042d1b89a585e0468487848b60c0015168ffffffffffffffffff168c60e0015168ffffffffffffffffff16878b61376c9190614bf7565b6137769190614bf7565b6137809190614bf7565b604080516bffffffffffffffffffffffff9586168152602081019490945291841683830152909216606082015290519081900360800190a25b509c9b505050505050505050505050565b6000466137d681613940565b1561385257606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384b919061509a565b9392505050565b61385b81613963565b156139035773420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e846040518060800160405280604881526020016150e3604891396040516020016138bb9291906150b3565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016138e69190613d7a565b602060405180830381865afa158015613827573d6000803e3d6000fd5b50600092915050565b600061393a6139196124bf565b61392b84670de0b6b3a7640000614a56565b6139359190614e25565b6139aa565b92915050565b600061a4b1821480613954575062066eed82145b8061393a57505062066eee1490565b6000600a82148061397557506101a482145b80613982575062aa37dc82145b8061398e575061210582145b8061399b575062014a3382145b8061393a57505062014a341490565b60006bffffffffffffffffffffffff821115613a48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610b0d565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f840112613a7d57600080fd5b50813567ffffffffffffffff811115613a9557600080fd5b602083019150836020828501011115612f8357600080fd5b60008060208385031215613ac057600080fd5b823567ffffffffffffffff811115613ad757600080fd5b613ae385828601613a6b565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715613b4257613b42613aef565b60405290565b604051610160810167ffffffffffffffff81118282101715613b4257613b42613aef565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bb357613bb3613aef565b604052919050565b63ffffffff8116811461272957600080fd5b803561117081613bbb565b68ffffffffffffffffff8116811461272957600080fd5b803561117081613bd8565b64ffffffffff8116811461272957600080fd5b803561117081613bfa565b803561ffff8116811461117057600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461117057600080fd5b60006101208284031215613c6957600080fd5b613c71613b1e565b613c7a83613bcd565b8152613c8860208401613bcd565b6020820152613c9960408401613bcd565b6040820152613caa60608401613bcd565b6060820152613cbb60808401613bef565b6080820152613ccc60a08401613c0d565b60a0820152613cdd60c08401613c18565b60c0820152613cee60e08401613c2a565b60e0820152610100613d01818501613bcd565b908201529392505050565b60005b83811015613d27578181015183820152602001613d0f565b50506000910152565b60008151808452613d48816020860160208601613d0c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061384b6020830184613d30565b600082601f830112613d9e57600080fd5b813567ffffffffffffffff811115613db857613db8613aef565b613de960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613b6c565b818152846020838601011115613dfe57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e2d57600080fd5b813567ffffffffffffffff811115613e4457600080fd5b613e5084828501613d8d565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461272957600080fd5b803561117081613e58565b6bffffffffffffffffffffffff8116811461272957600080fd5b803561117081613e85565b60008060408385031215613ebd57600080fd5b8235613ec881613e58565b91506020830135613ed881613e85565b809150509250929050565b600081518084526020808501945080840160005b83811015613f2957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613ef7565b509495945050505050565b60208152600061384b6020830184613ee3565b600060208284031215613f5957600080fd5b5035919050565b600060208284031215613f7257600080fd5b813567ffffffffffffffff811115613f8957600080fd5b8201610160818503121561384b57600080fd5b805182526020810151613fc7602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613fe760408401826bffffffffffffffffffffffff169052565b50606081015161400f606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50608081015161402b608084018267ffffffffffffffff169052565b5060a081015161404360a084018263ffffffff169052565b5060c081015161406060c084018268ffffffffffffffffff169052565b5060e081015161407d60e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161393a8284613f9c565b60008083601f8401126140d657600080fd5b50813567ffffffffffffffff8111156140ee57600080fd5b6020830191508360208260051b8501011115612f8357600080fd5b60008060008060008060008060e0898b03121561412557600080fd5b606089018a81111561413657600080fd5b8998503567ffffffffffffffff8082111561415057600080fd5b61415c8c838d01613a6b565b909950975060808b013591508082111561417557600080fd5b6141818c838d016140c4565b909750955060a08b013591508082111561419a57600080fd5b506141a78b828c016140c4565b999c989b50969995989497949560c00135949350505050565b815163ffffffff908116825260208084015182169083015260408084015182169083015260608084015191821690830152610120820190506080830151614214608084018268ffffffffffffffffff169052565b5060a083015161422d60a084018264ffffffffff169052565b5060c083015161424360c084018261ffff169052565b5060e083015161427360e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b506101008381015163ffffffff8116848301525b505092915050565b67ffffffffffffffff8116811461272957600080fd5b80356111708161428f565b6000806000806000608086880312156142c857600080fd5b85356142d38161428f565b9450602086013567ffffffffffffffff8111156142ef57600080fd5b6142fb88828901613a6b565b909550935050604086013561430f81613bbb565b949793965091946060013592915050565b600067ffffffffffffffff82111561433a5761433a613aef565b5060051b60200190565b600082601f83011261435557600080fd5b8135602061436a61436583614320565b613b6c565b82815260059290921b8401810191818101908684111561438957600080fd5b8286015b848110156143ad5780356143a081613e58565b835291830191830161438d565b509695505050505050565b803560ff8116811461117057600080fd5b60008060008060008060c087890312156143e257600080fd5b863567ffffffffffffffff808211156143fa57600080fd5b6144068a838b01614344565b9750602089013591508082111561441c57600080fd5b6144288a838b01614344565b965061443660408a016143b8565b9550606089013591508082111561444c57600080fd5b6144588a838b01613d8d565b945061446660808a016142a5565b935060a089013591508082111561447c57600080fd5b5061448989828a01613d8d565b9150509295509295509295565b6000602082840312156144a857600080fd5b813561384b81613e58565b600181811c908216806144c757607f821691505b602082108103614500577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105ec57600081815260208120601f850160051c8101602086101561452d5750805b601f850160051c820191505b81811015610a8857828155600101614539565b67ffffffffffffffff83111561456457614564613aef565b6145788361457283546144b3565b83614506565b6000601f8411600181146145ca57600085156145945750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614660565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561461957868501358255602094850194600190920191016145f9565b5086821015614654577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b805161117081613bd8565b60006020828403121561468457600080fd5b815161384b81613bd8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8281168282160390808211156127115761271161468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036147435761474361468f565b5060010190565b6000610160823603121561475d57600080fd5b614765613b48565b823567ffffffffffffffff81111561477c57600080fd5b61478836828601613d8d565b825250602083013560208201526147a160408401613e7a565b60408201526147b260608401613e9f565b60608201526147c360808401613bef565b60808201526147d460a084016142a5565b60a08201526147e560c084016142a5565b60c08201526147f660e08401613bcd565b60e0820152610100614809818501613c18565b9082015261012061481b8482016142a5565b9082015261014061482d848201613e7a565b9082015292915050565b60006020828403121561484957600080fd5b813561384b8161428f565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261488957600080fd5b83018035915067ffffffffffffffff8211156148a457600080fd5b602001915036819003821315612f8357600080fd5b6000602082840312156148cb57600080fd5b61384b82613c18565b6000602082840312156148e657600080fd5b813561384b81613bbb565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01683010190506132ef60e0830184613f9c565b60ff818116838216019081111561393a5761393a61468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806149f4576149f46149b2565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761393a5761393a61468f565b8181038181111561393a5761393a61468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff8181168382160190808211156127115761271161468f565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614afc8184018a613ee3565b90508281036080840152614b108189613ee3565b905060ff871660a084015282810360c0840152614b2d8187613d30565b905067ffffffffffffffff851660e0840152828103610100840152614b528185613d30565b9c9b505050505050505050505050565b805169ffffffffffffffffffff8116811461117057600080fd5b600080600080600060a08688031215614b9457600080fd5b614b9d86614b62565b9450602086015193506040860151925060608601519150614bc060808701614b62565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614beb57614beb6149b2565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156127115761271161468f565b6bffffffffffffffffffffffff8181168382160280821691908281146142875761428761468f565b8082018082111561393a5761393a61468f565b67ffffffffffffffff8181168382160190808211156127115761271161468f565b600082601f830112614c8957600080fd5b81356020614c9961436583614320565b82815260059290921b84018101918181019086841115614cb857600080fd5b8286015b848110156143ad5780358352918301918301614cbc565b600082601f830112614ce457600080fd5b81356020614cf461436583614320565b82815260059290921b84018101918181019086841115614d1357600080fd5b8286015b848110156143ad57803567ffffffffffffffff811115614d375760008081fd5b614d458986838b0101613d8d565b845250918301918301614d17565b600080600080600060a08688031215614d6b57600080fd5b853567ffffffffffffffff80821115614d8357600080fd5b614d8f89838a01614c78565b96506020880135915080821115614da557600080fd5b614db189838a01614cd3565b95506040880135915080821115614dc757600080fd5b614dd389838a01614cd3565b94506060880135915080821115614de957600080fd5b614df589838a01614cd3565b93506080880135915080821115614e0b57600080fd5b50614e1888828901614cd3565b9150509295509295909350565b600082614e3457614e346149b2565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614e808285018b613ee3565b91508382036080850152614e94828a613ee3565b915060ff881660a085015283820360c0850152614eb18288613d30565b90861660e08501528381036101008501529050614b528185613d30565b805161117081613e58565b805161117081613e85565b80516111708161428f565b805161117081613bbb565b805161117081613bfa565b60006101608284031215614f1857600080fd5b614f20613b48565b82518152614f3060208401614ece565b6020820152614f4160408401614ed9565b6040820152614f5260608401614ece565b6060820152614f6360808401614ee4565b6080820152614f7460a08401614eef565b60a0820152614f8560c08401614667565b60c0820152614f9660e08401614667565b60e0820152610100614fa9818501614efa565b90820152610120614fbb848201614efa565b90820152610140613d01848201614eef565b64ffffffffff8181168382160190808211156127115761271161468f565b6000610200808352614fff8184018a613d30565b905082810360208401526150138189613d30565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff86166080850152915061505c905060a0830184613f9c565b979650505050505050565b6000806040838503121561507a57600080fd5b82516007811061508957600080fd5b6020840151909250613ed881613e85565b6000602082840312156150ac57600080fd5b5051919050565b600083516150c5818460208801613d0c565b8351908301906150d9818360208801613d0c565b0194935050505056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkToUsdFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"usdLink\",\"type\":\"int256\"}],\"name\":\"InvalidUsdLinkPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"type\":\"event\"},{\"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\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1FeeShareWei\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"callbackCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint72\",\"name\":\"donFeeJuels\",\"type\":\"uint72\"},{\"indexed\":false,\"internalType\":\"uint72\",\"name\":\"adminFeeJuels\",\"type\":\"uint72\"},{\"indexed\":false,\"internalType\":\"uint72\",\"name\":\"operationFeeJuels\",\"type\":\"uint72\"}],\"name\":\"RequestBilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFeeJuels\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFeeJuels\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOperationFeeJuels\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getUsdPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200601f3803806200601f8339810160408190526200003491620004db565b83838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200014e565b5050506001600160a01b038116620000ee57604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03908116608052600c80546001600160601b03166c0100000000000000000000000085841602179055600d80546001600160a01b0319169183169190911790556200014083620001f9565b505050505050505062000742565b336001600160a01b03821603620001a85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620002036200039e565b80516008805460208401516040808601516060870151608088015160a089015160c08a015160e08b015160ff16600160f81b026001600160f81b036001600160401b03909216600160b81b02919091166001600160b81b0361ffff938416600160a81b0261ffff60a81b1964ffffffffff909616600160801b029590951666ffffffffffffff60801b1963ffffffff9788166c010000000000000000000000000263ffffffff60601b19998916680100000000000000000299909916600160401b600160801b03199b8916640100000000026001600160401b0319909d169e89169e909e179b909b17999099169b909b1795909517979097169590951717969096161792909217909255610100840151610120850151909316600160e01b026001600160e01b0390931692909217600955610140830151600a80546101608601518416620100000263ffffffff19919091169290931691909117919091179055517f2e2c8535dcc25459d519f2300c114d2d2128bf6399722d04eca078461a3bf33a906200039390839062000639565b60405180910390a150565b620003a8620003aa565b565b6000546001600160a01b03163314620003a85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000087565b80516001600160a01b03811681146200041e57600080fd5b919050565b60405161018081016001600160401b03811182821017156200045557634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff811681146200041e57600080fd5b805164ffffffffff811681146200041e57600080fd5b805161ffff811681146200041e57600080fd5b80516001600160401b03811681146200041e57600080fd5b805160ff811681146200041e57600080fd5b80516001600160e01b03811681146200041e57600080fd5b6000806000808486036101e0811215620004f457600080fd5b620004ff8662000406565b945061018080601f19830112156200051657600080fd5b6200052062000423565b915062000530602088016200045b565b825262000540604088016200045b565b602083015262000553606088016200045b565b604083015262000566608088016200045b565b60608301526200057960a0880162000470565b60808301526200058c60c0880162000486565b60a08301526200059f60e0880162000499565b60c0830152610100620005b4818901620004b1565b60e0840152610120620005c9818a01620004c3565b828501526101409150620005df828a016200045b565b90840152610160620005f389820162000486565b8285015262000604838a0162000486565b90840152509093506200061d90506101a0860162000406565b91506200062e6101c0860162000406565b905092959194509250565b815163ffffffff1681526101808101602083015162000660602084018263ffffffff169052565b50604083015162000679604084018263ffffffff169052565b50606083015162000692606084018263ffffffff169052565b506080830151620006ac608084018264ffffffffff169052565b5060a0830151620006c360a084018261ffff169052565b5060c0830151620006df60c08401826001600160401b03169052565b5060e0830151620006f560e084018260ff169052565b50610100838101516001600160e01b0316908301526101208084015163ffffffff16908301526101408084015161ffff908116918401919091526101609384015116929091019190915290565b608051615897620007886000396000818161079c01528181610c7d01528181610f110152818161102701528181611b2d015281816129eb015261396901526158976000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80638da5cb5b116100ee578063d227d24511610097578063e4ddcea611610071578063e4ddcea6146105d5578063f2f22ef1146105eb578063f2fde38b146105f3578063f6ea41f61461060657600080fd5b8063d227d2451461058a578063d328a91e146105ba578063e3d0e712146105c257600080fd5b8063b1dc65a4116100c8578063b1dc65a414610396578063ba9c924d146103a9578063c3f909d4146103bc57600080fd5b80638da5cb5b1461032e578063a631571e14610356578063afcb95d71461037657600080fd5b80637d4807871161015057806381f1b9381161012a57806381f1b938146102a657806381ff7048146102ae57806385b214cf1461031b57600080fd5b80637d480787146102765780637f15e1661461027e578063814118341461029157600080fd5b806366316d8d1161018157806366316d8d1461023c5780637212762f1461024f57806379ba50971461026e57600080fd5b8063083a5466146101a8578063181f5a77146101bd578063626f458c1461020f575b600080fd5b6101bb6101b6366004614010565b61060e565b005b6101f96040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e332e300000000081525081565b60405161020691906140c0565b60405180910390f35b61022261021d36600461422d565b610663565b60405168ffffffffffffffffff9091168152602001610206565b6101bb61024a3660046142b4565b6106a0565b610257610859565b6040805192835260ff909116602083015201610206565b6101bb610a6c565b6101bb610b69565b6101bb61028c366004614010565b610d69565b610299610db9565b604051610206919061433e565b6101f9610e28565b6102f860015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610206565b6101bb610329366004614351565b610ef9565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610206565b61036961036436600461436a565b610fb6565b60405161020691906144bf565b604080516001815260006020820181905291810191909152606001610206565b6101bb6103a4366004614513565b611247565b6101bb6103b736600461467e565b61185e565b61057d6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081019190915250604080516101808101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830152700100000000000000000000000000000000810464ffffffffff1660808301527501000000000000000000000000000000000000000000810461ffff90811660a084015277010000000000000000000000000000000000000000000000820467ffffffffffffffff1660c08401527f010000000000000000000000000000000000000000000000000000000000000090910460ff1660e08301526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166101008401527c01000000000000000000000000000000000000000000000000000000009004909216610120820152600a5480831661014083015262010000900490911661016082015290565b604051610206919061476a565b61059d610598366004614887565b611b29565b6040516bffffffffffffffffffffffff9091168152602001610206565b6101f9611c97565b6101bb6105d036600461498f565b611cee565b6105dd61286a565b604051908152602001610206565b6102226129ae565b6101bb610601366004614a5c565b6129d3565b6102226129e7565b610616612a78565b6000819003610651576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f61065e828483614b0c565b505050565b600a5460009061069a9060649061067d9061ffff16612afb565b6106879190614c85565b6bffffffffffffffffffffffff16612b48565b92915050565b6106a8612be7565b806bffffffffffffffffffffffff166000036106e25750336000908152600b60205260409020546bffffffffffffffffffffffff1661073c565b336000908152600b60205260409020546bffffffffffffffffffffffff8083169116101561073c576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b6020526040812080548392906107699084906bffffffffffffffffffffffff16614cb0565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506107be7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b15801561083d57600080fd5b505af1158015610851573d6000803e3d6000fd5b505050505050565b600080600080600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156108cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f09190614cf6565b5093505092505080426109039190614d46565b600854640100000000900463ffffffff161080156109305750600854640100000000900463ffffffff1615155b1561098d57505060085477010000000000000000000000000000000000000000000000810467ffffffffffffffff16937f010000000000000000000000000000000000000000000000000000000000000090910460ff1692509050565b600082136109cf576040517f56b22ab8000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b600d54604080517f313ce5670000000000000000000000000000000000000000000000000000000081529051849273ffffffffffffffffffffffffffffffffffffffff169163313ce5679160048083019260209291908290030181865afa158015610a3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a629190614d59565b9350935050509091565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016109c6565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b71612d93565b610b79612be7565b6000610b83610db9565b905060005b8151811015610d65576000600b6000848481518110610ba957610ba9614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610d54576000600b6000858581518110610c0857610c08614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610c9f7f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610ccc57610ccc614d76565b6020026020010151836040518363ffffffff1660e01b8152600401610d2192919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d3b57600080fd5b505af1158015610d4f573d6000803e3d6000fd5b505050505b50610d5e81614da5565b9050610b88565b5050565b610d71612a78565b6000819003610dac576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e61065e828483614b0c565b60606006805480602002602001604051908101604052809291908181526020018280548015610e1e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610df3575b5050505050905090565b6060600f8054610e3790614a79565b9050600003610e72576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f8054610e7f90614a79565b80601f0160208091040260200160405190810160405280929190818152602001828054610eab90614a79565b8015610e1e5780601f10610ecd57610100808354040283529160200191610e1e565b820191906000526020600020905b815481529060010190602001808311610edb57509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f68576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610fab9083815260200190565b60405180910390a150565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461107e576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061109161108c84614dff565b612d9b565b90925090506110a66060840160408501614a5c565b825173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff326110f460c0880160a08901614eec565b61110661016089016101408a01614a5c565b6111108980614f09565b6111226101208c016101008d01614f6e565b60208c01356111386101008e0160e08f01614f89565b6040518061016001604052808e6000015181526020018e6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018e604001516bffffffffffffffffffffffff1681526020018e6060015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6080015167ffffffffffffffff1681526020018e60a0015163ffffffff1681526020018d68ffffffffffffffffff1681526020018e60e0015168ffffffffffffffffff1681526020018e610100015164ffffffffff1681526020018e610120015164ffffffffff1681526020018e610140015163ffffffff1681525060405161123899989796959493929190614fa6565b60405180910390a3505b919050565b600080611254898961314d565b915091508115611265575050611854565b604080518b3580825262ffffff6020808f0135600881901c9290921690840152909290917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16112c28b8b8b8b8b8b6132d6565b6003546000906002906112e09060ff8082169161010090041661505c565b6112ea9190615075565b6112f590600161505c565b60ff169050888114611363576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e61747572657300000000000060448201526064016109c6565b8887146113f2576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f7265706f727420727320616e64207373206d757374206265206f66206571756160448201527f6c206c656e67746800000000000000000000000000000000000000000000000060648201526084016109c6565b3360009081526004602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561143557611435615097565b600281111561144657611446615097565b905250905060028160200151600281111561146357611463615097565b141580156114ac57506006816000015160ff168154811061148657611486614d76565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b15611513576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d6974746572000000000000000060448201526064016109c6565b5050505061151f613faf565b60008a8a6040516115319291906150c6565b604051908190038120611548918e906020016150d6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156118445760006001848984602081106115b1576115b1614d76565b6115be91901a601b61505c565b8e8e868181106115d0576115d0614d76565b905060200201358d8d878181106115e9576115e9614d76565b9050602002013560405160008152602001604052604051611626949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611648573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156116c8576116c8615097565b60028111156116d9576116d9615097565b90525092506001836020015160028111156116f6576116f6615097565b1461175d576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e000060448201526064016109c6565b8251600090869060ff16601f811061177757611777614d76565b602002015173ffffffffffffffffffffffffffffffffffffffff16146117f9576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e617475726500000000000000000000000060448201526064016109c6565b8085846000015160ff16601f811061181357611813614d76565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201525061183d81614da5565b9050611592565b5050506118508261338d565b5050505b5050505050505050565b611866612d93565b80516008805460208401516040808601516060870151608088015160a089015160c08a015160e08b015160ff167f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff90921677010000000000000000000000000000000000000000000000029190911676ffffffffffffffffffffffffffffffffffffffffffffff61ffff9384167501000000000000000000000000000000000000000000027fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff64ffffffffff90961670010000000000000000000000000000000002959095167fffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffff63ffffffff9788166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9989166801000000000000000002999099167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9b8916640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909d169e89169e909e179b909b17999099169b909b17959095179790971695909517179690961617929092179092556101008401516101208501519093167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90931692909217600955610140830151600a8054610160860151841662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000919091169290931691909117919091179055517f2e2c8535dcc25459d519f2300c114d2d2128bf6399722d04eca078461a3bf33a90610fab90839061476a565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b158015611bc957600080fd5b505afa158015611bdd573d6000803e3d6000fd5b5050505066038d7ea4c68000821115611c22576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611c2c6129e7565b90506000611c6f87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066392505050565b90506000611c7b6129ae565b9050611c8a86868486856134dc565b9998505050505050505050565b6060600e8054611ca690614a79565b9050600003611ce1576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e8054610e7f90614a79565b855185518560ff16601f831115611d61576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064016109c6565b80600003611dcb576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f736974697665000000000000000000000000000060448201526064016109c6565b818314611e59576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e0000000000000000000000000000000000000000000000000000000060648201526084016109c6565b611e648160036150ea565b8311611ecc576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f2068696768000000000000000060448201526064016109c6565b611ed4612a78565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611f1b9088613658565b600554156120d057600554600090611f3590600190614d46565b9050600060058281548110611f4c57611f4c614d76565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611f8657611f86614d76565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009081169091559290911680845292208054909116905560058054919250908061200657612006615101565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600680548061206f5761206f615101565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f1b915050565b60005b815151811015612687578151805160009190839081106120f5576120f5614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff160361217a576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7369676e6572206d757374206e6f7420626520656d707479000000000000000060448201526064016109c6565b600073ffffffffffffffffffffffffffffffffffffffff16826020015182815181106121a8576121a8614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff160361222d576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d70747900000060448201526064016109c6565b6000600460008460000151848151811061224957612249614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561229357612293615097565b146122fa576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e6572206164647265737300000000000000000060448201526064016109c6565b6040805180820190915260ff8216815260016020820152825180516004916000918590811061232b5761232b614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156123cc576123cc615097565b0217905550600091506123dc9050565b60046000846020015184815181106123f6576123f6614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561244057612440615097565b146124a7576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d697474657220616464726573730000000060448201526064016109c6565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106124da576124da614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561257b5761257b615097565b02179055505082518051600592508390811061259957612599614d76565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600691908390811061261557612615614d76565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061267f81614da5565b9150506120d3565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161273f91849174010000000000000000000000000000000000000000900416615130565b92506101000a81548163ffffffff021916908363ffffffff16021790555061279e4630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613671565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612855988b9891977401000000000000000000000000000000000000000090920463ffffffff1696909591949193919261514d565b60405180910390a15050505050505050505050565b6000806000600c8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156128da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fe9190614cf6565b5093505092505080426129119190614d46565b600854640100000000900463ffffffff1610801561293e5750600854640100000000900463ffffffff1615155b1561296b5750506009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b600082136129a8576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018390526024016109c6565b50919050565b600a546000906129ce9060649061067d9062010000900461ffff16612afb565b905090565b6129db612a78565b6129e48161371c565b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a54573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ce91906151ee565b60005473ffffffffffffffffffffffffffffffffffffffff163314612af9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109c6565b565b6000806000612b08610859565b9092509050612b4082612b1c83601261505c565b612b2790600a61532b565b612b3190876150ea565b612b3b919061533a565b613811565b949350505050565b600068ffffffffffffffffff821115612be3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203760448201527f322062697473000000000000000000000000000000000000000000000000000060648201526084016109c6565b5090565b600c546bffffffffffffffffffffffff16600003612c0157565b6000612c0b610db9565b80519091506000819003612c4b576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c54600090612c6a9083906bffffffffffffffffffffffff16614c85565b905060005b82811015612d355781600b6000868481518110612c8e57612c8e614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff16612cf6919061534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080612d2e90614da5565b9050612c6f565b50612d408282615373565b600c8054600090612d609084906bffffffffffffffffffffffff16614cb0565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b612af9612a78565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260085461010083015160009161ffff7501000000000000000000000000000000000000000000909104811691161115612e59576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612e688460000151610663565b9050612e726129ae565b91506000612e8b8560e001513a848860800151876134dc565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612ee7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954600090612f1d907c0100000000000000000000000000000000000000000000000000000000900463ffffffff164261539b565b905060003087604001518860a001518960c001516001612f3d91906153ae565b8a5180516020918201206101008d015160e08e0151604051612ff198979695948c918c9132910173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a015267ffffffffffffffff97881660408a0152959096166060880152608087019390935261ffff9190911660a086015263ffffffff90811660c08601526bffffffffffffffffffffffff9190911660e0850152919091166101008301529091166101208201526101400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206101608401835280845230848301526bffffffffffffffffffffffff8716848401528a83015173ffffffffffffffffffffffffffffffffffffffff16606085015260a0808c015167ffffffffffffffff1660808087019190915260e0808e015163ffffffff90811693880193909352908d015168ffffffffffffffffff90811660c08801528a169086015260085468010000000000000000810482166101008701526c0100000000000000000000000090048116610120860152861661014085015291519298509092506130fd918891016144bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550929491935090915050565b60006131816040518060a0016040528060608152602001606081526020016060815260200160608152602001606081525090565b600080808080613193888a018a6154aa565b84519499509297509095509350915060ff168015806131b3575084518114155b806131bf575083518114155b806131cb575082518114155b806131d7575081518114155b1561323e576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4669656c6473206d75737420626520657175616c206c656e677468000000000060448201526064016109c6565b60005b818110156132a45761327a87828151811061325e5761325e614d76565b6020026020010151600090815260076020526040902054151590565b6132a457613289600183614d46565b810361329457600198505b61329d81614da5565b9050613241565b50506040805160a0810182529586526020860194909452928401919091526060830152608082015290505b9250929050565b60006132e38260206150ea565b6132ee8560206150ea565b6132fa8861014461539b565b613304919061539b565b61330e919061539b565b61331990600061539b565b9050368114613384576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d61746368000000000000000060448201526064016109c6565b50505050505050565b80515160ff1660005b8181101561065e57600061343f846000015183815181106133b9576133b9614d76565b6020026020010151856020015184815181106133d7576133d7614d76565b6020026020010151866040015185815181106133f5576133f5614d76565b60200260200101518760600151868151811061341357613413614d76565b60200260200101518860800151878151811061343157613431614d76565b6020026020010151886138af565b9050600081600681111561345557613455615097565b14806134725750600181600681111561347057613470615097565b145b156134cb57835180518390811061348b5761348b614d76565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b506134d581614da5565b9050613396565b600854600090700100000000000000000000000000000000900464ffffffffff1685101561352557600854700100000000000000000000000000000000900464ffffffffff1694505b6008546000906127109061353f9063ffffffff16886150ea565b613549919061533a565b613553908761539b565b600854909150600090889061358c9063ffffffff6c01000000000000000000000000820481169168010000000000000000900416615130565b6135969190615130565b63ffffffff16905060006135e06000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613d7392505050565b90506000613601826135f285876150ea565b6135fc919061539b565b613eb5565b905060008668ffffffffffffffffff168868ffffffffffffffffff168a68ffffffffffffffffff16613633919061534e565b61363d919061534e565b9050613649818361534e565b9b9a5050505050505050505050565b6000613662610db9565b511115610d6557610d65612be7565b6000808a8a8a8a8a8a8a8a8a6040516020016136959998979695949392919061557c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361379b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109c6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006bffffffffffffffffffffffff821115612be3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016109c6565b600080848060200190518101906138c69190615648565b905060003a8261012001518361010001516138e19190615710565b64ffffffffff166138f291906150ea565b905060008460ff1661393a6000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613d7392505050565b613944919061533a565b905060006139556135fc838561539b565b905060006139623a613eb5565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298e8e868b60c0015168ffffffffffffffffff168c60e0015168ffffffffffffffffff168a6139d1919061534e565b6139db919061534e565b336040518061016001604052808f6000015181526020018f6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018f604001516bffffffffffffffffffffffff1681526020018f6060015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6080015167ffffffffffffffff1681526020018f60a0015163ffffffff168152602001600068ffffffffffffffffff1681526020018f60e0015168ffffffffffffffffff1681526020018f610100015164ffffffffff1681526020018f610120015164ffffffffff1681526020018f610140015163ffffffff168152506040518763ffffffff1660e01b8152600401613ae99695949392919061572e565b60408051808303816000875af1158015613b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b2b91906157aa565b90925090506000826006811115613b4457613b44615097565b1480613b6157506001826006811115613b5f57613b5f615097565b145b15613d625760008e815260076020526040812055613b7f818561534e565b336000908152600b602052604081208054909190613bac9084906bffffffffffffffffffffffff1661534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508660e0015168ffffffffffffffffff16600c60008282829054906101000a90046bffffffffffffffffffffffff16613c12919061534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508660c0015168ffffffffffffffffff16600b6000613c5c613ed4565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081208054909190613ca29084906bffffffffffffffffffffffff1661534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508d7f08a4a0761e3c98d288cb4af9342660f49550d83139fb3b762b70d34bed6273688487848b60e0015160008d60c00151604051613d59969594939291906bffffffffffffffffffffffff9687168152602081019590955292909416604084015268ffffffffffffffffff9081166060840152928316608083015290911660a082015260c00190565b60405180910390a25b509c9b505050505050505050505050565b600046613d7f81613f45565b15613dfb57606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613df491906157dd565b9392505050565b613e0481613f68565b15613eac5773420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e8460405180608001604052806048815260200161584360489139604051602001613e649291906157f6565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613e8f91906140c0565b602060405180830381865afa158015613dd0573d6000803e3d6000fd5b50600092915050565b600061069a613ec261286a565b612b3184670de0b6b3a76400006150ea565b60003073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f21573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ce9190615825565b600061a4b1821480613f59575062066eed82145b8061069a57505062066eee1490565b6000600a821480613f7a57506101a482145b80613f87575062aa37dc82145b80613f93575061210582145b80613fa0575062014a3382145b8061069a57505062014a341490565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f840112613fe057600080fd5b50813567ffffffffffffffff811115613ff857600080fd5b6020830191508360208285010111156132cf57600080fd5b6000806020838503121561402357600080fd5b823567ffffffffffffffff81111561403a57600080fd5b61404685828601613fce565b90969095509350505050565b60005b8381101561406d578181015183820152602001614055565b50506000910152565b6000815180845261408e816020860160208601614052565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613df46020830184614076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610180810167ffffffffffffffff81118282101715614126576141266140d3565b60405290565b604051610160810167ffffffffffffffff81118282101715614126576141266140d3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614197576141976140d3565b604052919050565b600082601f8301126141b057600080fd5b813567ffffffffffffffff8111156141ca576141ca6140d3565b6141fb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614150565b81815284602083860101111561421057600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561423f57600080fd5b813567ffffffffffffffff81111561425657600080fd5b612b408482850161419f565b73ffffffffffffffffffffffffffffffffffffffff811681146129e457600080fd5b803561124281614262565b6bffffffffffffffffffffffff811681146129e457600080fd5b80356112428161428f565b600080604083850312156142c757600080fd5b82356142d281614262565b915060208301356142e28161428f565b809150509250929050565b600081518084526020808501945080840160005b8381101561433357815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614301565b509495945050505050565b602081526000613df460208301846142ed565b60006020828403121561436357600080fd5b5035919050565b60006020828403121561437c57600080fd5b813567ffffffffffffffff81111561439357600080fd5b82016101608185031215613df457600080fd5b8051825260208101516143d1602084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408101516143f160408401826bffffffffffffffffffffffff169052565b506060810151614419606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151614435608084018267ffffffffffffffff169052565b5060a081015161444d60a084018263ffffffff169052565b5060c081015161446a60c084018268ffffffffffffffffff169052565b5060e081015161448760e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161069a82846143a6565b60008083601f8401126144e057600080fd5b50813567ffffffffffffffff8111156144f857600080fd5b6020830191508360208260051b85010111156132cf57600080fd5b60008060008060008060008060e0898b03121561452f57600080fd5b606089018a81111561454057600080fd5b8998503567ffffffffffffffff8082111561455a57600080fd5b6145668c838d01613fce565b909950975060808b013591508082111561457f57600080fd5b61458b8c838d016144ce565b909750955060a08b01359150808211156145a457600080fd5b506145b18b828c016144ce565b999c989b50969995989497949560c00135949350505050565b63ffffffff811681146129e457600080fd5b8035611242816145ca565b64ffffffffff811681146129e457600080fd5b8035611242816145e7565b803561ffff8116811461124257600080fd5b67ffffffffffffffff811681146129e457600080fd5b803561124281614617565b60ff811681146129e457600080fd5b803561124281614638565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461124257600080fd5b6000610180828403121561469157600080fd5b614699614102565b6146a2836145dc565b81526146b0602084016145dc565b60208201526146c1604084016145dc565b60408201526146d2606084016145dc565b60608201526146e3608084016145fa565b60808201526146f460a08401614605565b60a082015261470560c0840161462d565b60c082015261471660e08401614647565b60e0820152610100614729818501614652565b9082015261012061473b8482016145dc565b9082015261014061474d848201614605565b9082015261016061475f848201614605565b908201529392505050565b815163ffffffff16815261018081016020830151614790602084018263ffffffff169052565b5060408301516147a8604084018263ffffffff169052565b5060608301516147c0606084018263ffffffff169052565b5060808301516147d9608084018264ffffffffff169052565b5060a08301516147ef60a084018261ffff169052565b5060c083015161480b60c084018267ffffffffffffffff169052565b5060e083015161482060e084018260ff169052565b50610100838101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16908301526101208084015163ffffffff16908301526101408084015161ffff908116918401919091526101608085015191821681850152905b505092915050565b60008060008060006080868803121561489f57600080fd5b85356148aa81614617565b9450602086013567ffffffffffffffff8111156148c657600080fd5b6148d288828901613fce565b90955093505060408601356148e6816145ca565b949793965091946060013592915050565b600067ffffffffffffffff821115614911576149116140d3565b5060051b60200190565b600082601f83011261492c57600080fd5b8135602061494161493c836148f7565b614150565b82815260059290921b8401810191818101908684111561496057600080fd5b8286015b8481101561498457803561497781614262565b8352918301918301614964565b509695505050505050565b60008060008060008060c087890312156149a857600080fd5b863567ffffffffffffffff808211156149c057600080fd5b6149cc8a838b0161491b565b975060208901359150808211156149e257600080fd5b6149ee8a838b0161491b565b96506149fc60408a01614647565b95506060890135915080821115614a1257600080fd5b614a1e8a838b0161419f565b9450614a2c60808a0161462d565b935060a0890135915080821115614a4257600080fd5b50614a4f89828a0161419f565b9150509295509295509295565b600060208284031215614a6e57600080fd5b8135613df481614262565b600181811c90821680614a8d57607f821691505b6020821081036129a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f82111561065e57600081815260208120601f850160051c81016020861015614aed5750805b601f850160051c820191505b8181101561085157828155600101614af9565b67ffffffffffffffff831115614b2457614b246140d3565b614b3883614b328354614a79565b83614ac6565b6000601f841160018114614b8a5760008515614b545750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614c20565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614bd95786850135825560209485019460019092019101614bb9565b5086821015614c14577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80841680614ca457614ca4614c27565b92169190910492915050565b6bffffffffffffffffffffffff828116828216039080821115614cd557614cd5614c56565b5092915050565b805169ffffffffffffffffffff8116811461124257600080fd5b600080600080600060a08688031215614d0e57600080fd5b614d1786614cdc565b9450602086015193506040860151925060608601519150614d3a60808701614cdc565b90509295509295909350565b8181038181111561069a5761069a614c56565b600060208284031215614d6b57600080fd5b8151613df481614638565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614dd657614dd6614c56565b5060010190565b68ffffffffffffffffff811681146129e457600080fd5b803561124281614ddd565b60006101608236031215614e1257600080fd5b614e1a61412c565b823567ffffffffffffffff811115614e3157600080fd5b614e3d3682860161419f565b82525060208301356020820152614e5660408401614284565b6040820152614e67606084016142a9565b6060820152614e7860808401614df4565b6080820152614e8960a0840161462d565b60a0820152614e9a60c0840161462d565b60c0820152614eab60e084016145dc565b60e0820152610100614ebe818501614605565b90820152610120614ed084820161462d565b90820152610140614ee2848201614284565b9082015292915050565b600060208284031215614efe57600080fd5b8135613df481614617565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614f3e57600080fd5b83018035915067ffffffffffffffff821115614f5957600080fd5b6020019150368190038213156132cf57600080fd5b600060208284031215614f8057600080fd5b613df482614605565b600060208284031215614f9b57600080fd5b8135613df4816145ca565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016830101905061504e60e08301846143a6565b9a9950505050505050505050565b60ff818116838216019081111561069a5761069a614c56565b600060ff83168061508857615088614c27565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761069a5761069a614c56565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff818116838216019080821115614cd557614cd5614c56565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261517d8184018a6142ed565b9050828103608084015261519181896142ed565b905060ff871660a084015282810360c08401526151ae8187614076565b905067ffffffffffffffff851660e08401528281036101008401526151d38185614076565b9c9b505050505050505050505050565b805161124281614ddd565b60006020828403121561520057600080fd5b8151613df481614ddd565b600181815b8085111561526457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561524a5761524a614c56565b8085161561525757918102915b93841c9390800290615210565b509250929050565b60008261527b5750600161069a565b816152885750600061069a565b816001811461529e57600281146152a8576152c4565b600191505061069a565b60ff8411156152b9576152b9614c56565b50506001821b61069a565b5060208310610133831016604e8410600b84101617156152e7575081810a61069a565b6152f1838361520b565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561532357615323614c56565b029392505050565b6000613df460ff84168361526c565b60008261534957615349614c27565b500490565b6bffffffffffffffffffffffff818116838216019080821115614cd557614cd5614c56565b6bffffffffffffffffffffffff81811683821602808216919082811461487f5761487f614c56565b8082018082111561069a5761069a614c56565b67ffffffffffffffff818116838216019080821115614cd557614cd5614c56565b600082601f8301126153e057600080fd5b813560206153f061493c836148f7565b82815260059290921b8401810191818101908684111561540f57600080fd5b8286015b848110156149845780358352918301918301615413565b600082601f83011261543b57600080fd5b8135602061544b61493c836148f7565b82815260059290921b8401810191818101908684111561546a57600080fd5b8286015b8481101561498457803567ffffffffffffffff81111561548e5760008081fd5b61549c8986838b010161419f565b84525091830191830161546e565b600080600080600060a086880312156154c257600080fd5b853567ffffffffffffffff808211156154da57600080fd5b6154e689838a016153cf565b965060208801359150808211156154fc57600080fd5b61550889838a0161542a565b9550604088013591508082111561551e57600080fd5b61552a89838a0161542a565b9450606088013591508082111561554057600080fd5b61554c89838a0161542a565b9350608088013591508082111561556257600080fd5b5061556f8882890161542a565b9150509295509295909350565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526155c38285018b6142ed565b915083820360808501526155d7828a6142ed565b915060ff881660a085015283820360c08501526155f48288614076565b90861660e085015283810361010085015290506151d38185614076565b805161124281614262565b80516112428161428f565b805161124281614617565b8051611242816145ca565b8051611242816145e7565b6000610160828403121561565b57600080fd5b61566361412c565b8251815261567360208401615611565b60208201526156846040840161561c565b604082015261569560608401615611565b60608201526156a660808401615627565b60808201526156b760a08401615632565b60a08201526156c860c084016151e3565b60c08201526156d960e084016151e3565b60e08201526101006156ec81850161563d565b908201526101206156fe84820161563d565b9082015261014061475f848201615632565b64ffffffffff818116838216019080821115614cd557614cd5614c56565b60006102008083526157428184018a614076565b905082810360208401526157568189614076565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff86166080850152915061579f905060a08301846143a6565b979650505050505050565b600080604083850312156157bd57600080fd5b8251600781106157cc57600080fd5b60208401519092506142e28161428f565b6000602082840312156157ef57600080fd5b5051919050565b60008351615808818460208801614052565b83519083019061581c818360208801614052565b01949350505050565b60006020828403121561583757600080fd5b8151613df48161426256fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI var FunctionsCoordinatorBin = FunctionsCoordinatorMetaData.Bin -func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config FunctionsBillingConfig, linkToNativeFeed common.Address) (common.Address, *types.Transaction, *FunctionsCoordinator, error) { +func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config FunctionsBillingConfig, linkToNativeFeed common.Address, linkToUsdFeed common.Address) (common.Address, *types.Transaction, *FunctionsCoordinator, error) { parsed, err := FunctionsCoordinatorMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -88,7 +91,7 @@ func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBa return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FunctionsCoordinatorBin), backend, router, config, linkToNativeFeed) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FunctionsCoordinatorBin), backend, router, config, linkToNativeFeed, linkToUsdFeed) if err != nil { return common.Address{}, nil, nil, err } @@ -233,9 +236,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(sub return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceWei) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFeeJuels(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getAdminFee") + err := _FunctionsCoordinator.contract.Call(opts, &out, "getAdminFeeJuels") if err != nil { return *new(*big.Int), err @@ -247,12 +250,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind. } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAdminFee() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAdminFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetAdminFeeJuels(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFee() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetAdminFeeJuels(&_FunctionsCoordinator.CallOpts) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error) { @@ -277,9 +280,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfig() (Fun return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFeeJuels(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONFee", arg0) + err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONFeeJuels", arg0) if err != nil { return *new(*big.Int), err @@ -291,12 +294,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.Ca } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONFee(arg0 []byte) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONFeeJuels(arg0 []byte) (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetDONFeeJuels(&_FunctionsCoordinator.CallOpts, arg0) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONFee(arg0 []byte) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONFeeJuels(arg0 []byte) (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetDONFeeJuels(&_FunctionsCoordinator.CallOpts, arg0) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) { @@ -321,6 +324,28 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONPublicKey( return _FunctionsCoordinator.Contract.GetDONPublicKey(&_FunctionsCoordinator.CallOpts) } +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetOperationFeeJuels(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FunctionsCoordinator.contract.Call(opts, &out, "getOperationFeeJuels") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetOperationFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetOperationFeeJuels(&_FunctionsCoordinator.CallOpts) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetOperationFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetOperationFeeJuels(&_FunctionsCoordinator.CallOpts) +} + func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) { var out []interface{} err := _FunctionsCoordinator.contract.Call(opts, &out, "getThresholdPublicKey") @@ -343,6 +368,29 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetThresholdPubl return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) } +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetUsdPerUnitLink(opts *bind.CallOpts) (*big.Int, uint8, error) { + var out []interface{} + err := _FunctionsCoordinator.contract.Call(opts, &out, "getUsdPerUnitLink") + + if err != nil { + return *new(*big.Int), *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out1 := *abi.ConvertType(out[1], new(uint8)).(*uint8) + + return out0, out1, err + +} + +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetUsdPerUnitLink() (*big.Int, uint8, error) { + return _FunctionsCoordinator.Contract.GetUsdPerUnitLink(&_FunctionsCoordinator.CallOpts) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetUsdPerUnitLink() (*big.Int, uint8, error) { + return _FunctionsCoordinator.Contract.GetUsdPerUnitLink(&_FunctionsCoordinator.CallOpts) +} + func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _FunctionsCoordinator.contract.Call(opts, &out, "getWeiPerUnitLink") @@ -1593,7 +1641,9 @@ type FunctionsCoordinatorRequestBilled struct { JuelsPerGas *big.Int L1FeeShareWei *big.Int CallbackCostJuels *big.Int - TotalCostJuels *big.Int + DonFeeJuels *big.Int + AdminFeeJuels *big.Int + OperationFeeJuels *big.Int Raw types.Log } @@ -1823,7 +1873,7 @@ func (FunctionsCoordinatorConfigSet) Topic() common.Hash { } func (FunctionsCoordinatorConfigUpdated) Topic() common.Hash { - return common.HexToHash("0x5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862") + return common.HexToHash("0x2e2c8535dcc25459d519f2300c114d2d2128bf6399722d04eca078461a3bf33a") } func (FunctionsCoordinatorOracleRequest) Topic() common.Hash { @@ -1843,7 +1893,7 @@ func (FunctionsCoordinatorOwnershipTransferred) Topic() common.Hash { } func (FunctionsCoordinatorRequestBilled) Topic() common.Hash { - return common.HexToHash("0x90815c2e624694e8010bffad2bcefaf96af282ef1bc2ebc0042d1b89a585e046") + return common.HexToHash("0x08a4a0761e3c98d288cb4af9342660f49550d83139fb3b762b70d34bed627368") } func (FunctionsCoordinatorTransmitted) Topic() common.Hash { @@ -1857,16 +1907,20 @@ func (_FunctionsCoordinator *FunctionsCoordinator) Address() common.Address { type FunctionsCoordinatorInterface interface { EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) - GetAdminFee(opts *bind.CallOpts) (*big.Int, error) + GetAdminFeeJuels(opts *bind.CallOpts) (*big.Int, error) GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error) - GetDONFee(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) + GetDONFeeJuels(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) + GetOperationFeeJuels(opts *bind.CallOpts) (*big.Int, error) + GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) + GetUsdPerUnitLink(opts *bind.CallOpts) (*big.Int, uint8, error) + GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 102e377859c..7f441a59284 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -4,7 +4,7 @@ functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServ functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.bin 9686bdf83a0ce09ad07e81f6af52889735ea5af5709ffd018bb7b75e5d284c5e +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.bin 292d4742d039a154ed7875a0167c9725e2a90674ad9a05f152377819bb991082 functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsLoadTestClient.bin c8dbbd5ebb34435800d6674700068837c3a252db60046a14b0e61e829db517de functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c functions_router: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRouter.bin 1f6d18f9e0846ad74b37a0a6acef5942ab73ace1e84307f201899f69e732e776 diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go index 7f75717feba..3061d818bf1 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -186,6 +186,10 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, linkEthFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(owner, b, 18, big.NewInt(5_000_000_000_000_000)) require.NoError(t, err) + // Deploy mock LINK/USD price feed + linkUsdFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(owner, b, 18, big.NewInt(1_500_00_000)) + require.NoError(t, err) + // Deploy Router contract handleOracleFulfillmentSelectorSlice, err := hex.DecodeString("0ca76175") require.NoError(t, err) @@ -222,16 +226,19 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, GasOverheadBeforeCallback: uint32(325_000), GasOverheadAfterCallback: uint32(50_000), RequestTimeoutSeconds: uint32(300), - DonFee: big.NewInt(0), + DonFeeCentsUsd: uint16(0), MaxSupportedRequestDataVersion: uint16(1), FulfillmentGasPriceOverEstimationBP: uint32(1_000), FallbackNativePerUnitLink: big.NewInt(5_000_000_000_000_000), MinimumEstimateGasPriceWei: big.NewInt(1_000_000_000), + OperationFeeCentsUsd: uint16(0), + FallbackUsdPerUnitLink: uint64(1_400_000_000), + FallbackUsdPerUnitLinkDecimals: uint8(8), } require.NoError(t, err) - coordinatorAddress, _, coordinatorContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr) + coordinatorAddress, _, coordinatorContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr, linkUsdFeedAddr) require.NoError(t, err) - proposalAddress, _, proposalContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr) + proposalAddress, _, proposalContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr, linkUsdFeedAddr) require.NoError(t, err) // Deploy Client contracts From b84bdb5936d8a72970757a5b0dfe870e16cd26a2 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Wed, 21 Feb 2024 16:52:00 +0100 Subject: [PATCH 65/98] build load package differently (#12117) * build load package differently * unpack back to the integration-tests dir * Handle new load go project for tests that use it --------- Co-authored-by: Tate --- .github/actions/build-test-image/action.yml | 2 +- .github/workflows/automation-benchmark-tests.yml | 2 +- .github/workflows/automation-load-tests.yml | 4 ++-- .github/workflows/on-demand-vrfv2-performance-test.yml | 2 +- .github/workflows/on-demand-vrfv2plus-performance-test.yml | 2 +- integration-tests/scripts/buildTests | 7 ++++++- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/actions/build-test-image/action.yml b/.github/actions/build-test-image/action.yml index 0c48c43b772..d2ebeaa39b9 100644 --- a/.github/actions/build-test-image/action.yml +++ b/.github/actions/build-test-image/action.yml @@ -15,7 +15,7 @@ inputs: required: false suites: description: The test suites to build into the image - default: chaos migration reorg smoke soak benchmark load/automationv2_1 + default: chaos migration reorg smoke soak benchmark load required: false QA_AWS_ROLE_TO_ASSUME: description: The AWS role to assume as the CD user, if any. Used in configuring the docker/login-action diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index 70725511883..3b6bf6384fa 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -64,7 +64,7 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: benchmark load/automationv2_1 chaos reorg + suites: benchmark load chaos reorg - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 env: diff --git a/.github/workflows/automation-load-tests.yml b/.github/workflows/automation-load-tests.yml index ad68e470a4d..7c2b737da88 100644 --- a/.github/workflows/automation-load-tests.yml +++ b/.github/workflows/automation-load-tests.yml @@ -80,7 +80,7 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: benchmark load/automationv2_1 chaos reorg + suites: benchmark load chaos reorg - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 env: @@ -94,7 +94,7 @@ jobs: PYROSCOPE_SERVER: ${{ secrets.QA_PYROSCOPE_INSTANCE }} PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} with: - test_command_to_run: cd integration-tests && go test -timeout 1h -v -run TestLogTrigger ./load/automationv2_1 -count=1 + test_command_to_run: cd integration-tests/load && go test -timeout 1h -v -run TestLogTrigger ./automationv2_1 -count=1 test_download_vendor_packages_command: make gomod cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index 5887d8ec9a2..1e82d8ab02c 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -69,7 +69,7 @@ jobs: - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 with: - test_command_to_run: cd ./integration-tests && go test -v -count=1 -timeout 24h -run TestVRFV2Performance/vrfv2_performance_test ./load/vrfv2 + test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run TestVRFV2Performance/vrfv2_performance_test ./vrfv2 test_download_vendor_packages_command: cd ./integration-tests && go mod download cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index 36a75704895..2c2e11b6cb3 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -70,7 +70,7 @@ jobs: - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 with: - test_command_to_run: cd ./integration-tests && go test -v -count=1 -timeout 24h -run TestVRFV2PlusPerformance/vrfv2plus_performance_test ./load/vrfv2plus + test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run TestVRFV2PlusPerformance/vrfv2plus_performance_test ./vrfv2plus test_download_vendor_packages_command: cd ./integration-tests && go mod download cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} diff --git a/integration-tests/scripts/buildTests b/integration-tests/scripts/buildTests index 749bb545110..27378bdf43f 100755 --- a/integration-tests/scripts/buildTests +++ b/integration-tests/scripts/buildTests @@ -21,6 +21,11 @@ OIFS=$IFS IFS=' ' for x in $tosplit do - go test -c -tags embed ./"${x}" + if [ "$x" = "load" ]; then + echo "Changing directory and executing go test -c ./... for 'load' package" + cd "load" && go test -c -tags embed -o .. ./... + else + go test -c -tags embed ./"${x}" + fi done IFS=$OIFS From 216efed063abb3d779f6c941f2e139c539c77a0e Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:47:39 -0800 Subject: [PATCH 66/98] [KS-55] Engine and Registry improvements (#12115) 1. Move registry operations into a separate goroutine launched at Start() and supporting re-tries, to avoid race conditions on node init. 2. Move most of the hardcoded workflow into Engine constructor, for clarity. 3. Add missing call to consensus.RegisterToWorkflow(). 4. Add logger to Registry. --- core/capabilities/registry.go | 13 +- core/capabilities/registry_test.go | 7 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/chainlink/application.go | 2 +- core/services/job/spawner_test.go | 2 +- core/services/workflows/engine.go | 214 +++++++++++++++---------- core/services/workflows/engine_test.go | 28 ++-- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- 12 files changed, 174 insertions(+), 110 deletions(-) diff --git a/core/capabilities/registry.go b/core/capabilities/registry.go index 02c08ae8dc3..4865116196e 100644 --- a/core/capabilities/registry.go +++ b/core/capabilities/registry.go @@ -6,13 +6,15 @@ import ( "sync" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/logger" ) // Registry is a struct for the registry of capabilities. // Registry is safe for concurrent use. type Registry struct { - m map[string]capabilities.BaseCapability - mu sync.RWMutex + m map[string]capabilities.BaseCapability + mu sync.RWMutex + lggr logger.Logger } // Get gets a capability from the registry. @@ -20,6 +22,7 @@ func (r *Registry) Get(_ context.Context, id string) (capabilities.BaseCapabilit r.mu.RLock() defer r.mu.RUnlock() + r.lggr.Debugw("get capability", "id", id) c, ok := r.m[id] if !ok { return nil, fmt.Errorf("capability not found with id %s", id) @@ -142,13 +145,15 @@ func (r *Registry) Add(ctx context.Context, c capabilities.BaseCapability) error } r.m[id] = c + r.lggr.Infow("capability added", "id", id, "type", info.CapabilityType, "description", info.Description, "version", info.Version) return nil } // NewRegistry returns a new Registry. -func NewRegistry() *Registry { +func NewRegistry(lggr logger.Logger) *Registry { return &Registry{ - m: map[string]capabilities.BaseCapability{}, + m: map[string]capabilities.BaseCapability{}, + lggr: lggr.Named("CapabilityRegistry"), } } diff --git a/core/capabilities/registry_test.go b/core/capabilities/registry_test.go index 8af91d133a2..3f8ca397495 100644 --- a/core/capabilities/registry_test.go +++ b/core/capabilities/registry_test.go @@ -12,6 +12,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers" coreCapabilities "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" ) type mockCapability struct { @@ -33,7 +34,7 @@ func (m *mockCapability) UnregisterFromWorkflow(ctx context.Context, request cap func TestRegistry(t *testing.T) { ctx := testutils.Context(t) - r := coreCapabilities.NewRegistry() + r := coreCapabilities.NewRegistry(logger.TestLogger(t)) id := "capability-1" ci, err := capabilities.NewCapabilityInfo( @@ -61,7 +62,7 @@ func TestRegistry(t *testing.T) { func TestRegistry_NoDuplicateIDs(t *testing.T) { ctx := testutils.Context(t) - r := coreCapabilities.NewRegistry() + r := coreCapabilities.NewRegistry(logger.TestLogger(t)) id := "capability-1" ci, err := capabilities.NewCapabilityInfo( @@ -172,7 +173,7 @@ func TestRegistry_ChecksExecutionAPIByType(t *testing.T) { } ctx := testutils.Context(t) - reg := coreCapabilities.NewRegistry() + reg := coreCapabilities.NewRegistry(logger.TestLogger(t)) for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { id, err := tc.newCapability(ctx, reg) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index b4d6860719d..9cf5111cf52 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240215150045-fe2ba71b2f0a diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f52f3cac869..b6432cbe3fe 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1173,8 +1173,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c h1:ielGD+tVCB+irZ+nDt5VDTYJauJI88tirkLLaHWLaTs= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index de2fe789396..eebb70534c0 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -185,7 +185,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { keyStore := opts.KeyStore restrictedHTTPClient := opts.RestrictedHTTPClient unrestrictedHTTPClient := opts.UnrestrictedHTTPClient - registry := capabilities.NewRegistry() + registry := capabilities.NewRegistry(globalLogger) // LOOPs can be created as options, in the case of LOOP relayers, or // as OCR2 job implementations, in the case of Median today. diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index 2139b4a02e2..b23be49458e 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -305,7 +305,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { ocr2DelegateConfig := ocr2.NewDelegateConfig(config.OCR2(), config.Mercury(), config.Threshold(), config.Insecure(), config.JobPipeline(), config.Database(), processConfig) d := ocr2.NewDelegate(nil, orm, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig, - keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, capabilities.NewRegistry()) + keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, capabilities.NewRegistry(lggr)) delegateOCR2 := &delegate{jobOCR2VRF.Type, []job.ServiceCtx{}, 0, nil, d} spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{ diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 1f34b58105d..3260702e66b 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -3,6 +3,9 @@ package workflows import ( "context" "fmt" + "time" + + "github.com/shopspring/decimal" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -12,49 +15,91 @@ import ( ) const ( - mockedWorkflowID = "ef7c8168-f4d1-422f-a4b2-8ce0a1075f0a" - mockedTriggerID = "bd727a82-5cac-4071-be62-0152dd9adb0f" + mockedWorkflowID = "aaaaaaaa-f4d1-422f-a4b2-8ce0a1075f0a" + mockedExecutionID = "bbbbbbbb-f4d1-422f-a4b2-8ce0a1075f0a" + mockedTriggerID = "cccccccc-5cac-4071-be62-0152dd9adb0f" ) type Engine struct { services.StateMachine - logger logger.Logger - registry types.CapabilitiesRegistry - trigger capabilities.TriggerCapability - consensus capabilities.ConsensusCapability - target capabilities.TargetCapability - callbackCh chan capabilities.CapabilityResponse - cancel func() + logger logger.Logger + registry types.CapabilitiesRegistry + triggerType string + triggerConfig *values.Map + trigger capabilities.TriggerCapability + consensusType string + consensusConfig *values.Map + consensus capabilities.ConsensusCapability + targetType string + targetConfig *values.Map + target capabilities.TargetCapability + callbackCh chan capabilities.CapabilityResponse + cancel func() } func (e *Engine) Start(ctx context.Context) error { return e.StartOnce("Engine", func() error { - err := e.registerTrigger(ctx) - if err != nil { - return err - } - // create a new context, since the one passed in via Start is short-lived. ctx, cancel := context.WithCancel(context.Background()) e.cancel = cancel - go e.loop(ctx) + go e.init(ctx) + go e.triggerHandlerLoop(ctx) return nil }) } -func (e *Engine) registerTrigger(ctx context.Context) error { - triggerConf, err := values.NewMap( - map[string]any{ - "feedlist": []any{ - // ETHUSD, LINKUSD, USDBTC - 123, 456, 789, - }, +func (e *Engine) init(ctx context.Context) { + retrySec := 5 + ticker := time.NewTicker(time.Duration(retrySec) * time.Second) + defer ticker.Stop() + var err error +LOOP: + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + e.trigger, err = e.registry.GetTrigger(ctx, e.triggerType) + if err != nil { + e.logger.Errorf("failed to get trigger capability: %s, retrying in %d seconds", err, retrySec) + break + } + e.consensus, err = e.registry.GetConsensus(ctx, e.consensusType) + if err != nil { + e.logger.Errorf("failed to get consensus capability: %s, retrying in %d seconds", err, retrySec) + break + } + e.target, err = e.registry.GetTarget(ctx, e.targetType) + if err != nil { + e.logger.Errorf("failed to get target capability: %s, retrying in %d seconds", err, retrySec) + break + } + break LOOP + } + } + + // we have all needed capabilities, now we can register for trigger events + err = e.registerTrigger(ctx) + if err != nil { + e.logger.Errorf("failed to register trigger: %s", err) + } + + // also register for consensus + reg := capabilities.RegisterToWorkflowRequest{ + Metadata: capabilities.RegistrationMetadata{ + WorkflowID: mockedWorkflowID, }, - ) + Config: e.consensusConfig, + } + err = e.consensus.RegisterToWorkflow(ctx, reg) if err != nil { - return err + e.logger.Errorf("failed to register consensus: %s", err) } + e.logger.Info("engine initialized") +} + +func (e *Engine) registerTrigger(ctx context.Context) error { triggerInputs, err := values.NewMap( map[string]any{ "triggerId": mockedTriggerID, @@ -68,7 +113,7 @@ func (e *Engine) registerTrigger(ctx context.Context) error { Metadata: capabilities.RequestMetadata{ WorkflowID: mockedWorkflowID, }, - Config: triggerConf, + Config: e.triggerConfig, Inputs: triggerInputs, } err = e.trigger.RegisterTrigger(ctx, e.callbackCh, triggerRegRequest) @@ -78,7 +123,7 @@ func (e *Engine) registerTrigger(ctx context.Context) error { return nil } -func (e *Engine) loop(ctx context.Context) { +func (e *Engine) triggerHandlerLoop(ctx context.Context) { for { select { case <-ctx.Done(): @@ -92,8 +137,9 @@ func (e *Engine) loop(ctx context.Context) { } } -func (e *Engine) handleExecution(ctx context.Context, resp capabilities.CapabilityResponse) error { - results, err := e.handleConsensus(ctx, resp) +func (e *Engine) handleExecution(ctx context.Context, event capabilities.CapabilityResponse) error { + e.logger.Debugw("executing on a trigger event", "event", event) + results, err := e.handleConsensus(ctx, event) if err != nil { return err } @@ -103,27 +149,14 @@ func (e *Engine) handleExecution(ctx context.Context, resp capabilities.Capabili } func (e *Engine) handleTarget(ctx context.Context, resp *values.List) (*values.List, error) { - report, err := resp.Unwrap() - if err != nil { - return nil, err - } + inputs := map[string]values.Value{ "report": resp, } - config, err := values.NewMap(map[string]any{ - "address": "0xaabbcc", - "method": "updateFeedValues(report bytes, role uint8)", - "params": []any{ - report, 1, - }, - }) - if err != nil { - return nil, err - } tr := capabilities.CapabilityRequest{ Inputs: &values.Map{Underlying: inputs}, - Config: config, + Config: e.targetConfig, Metadata: capabilities.RequestMetadata{ WorkflowID: mockedWorkflowID, }, @@ -132,39 +165,17 @@ func (e *Engine) handleTarget(ctx context.Context, resp *values.List) (*values.L } func (e *Engine) handleConsensus(ctx context.Context, resp capabilities.CapabilityResponse) (*values.List, error) { + e.logger.Debugw("running consensus", "resp", resp) inputs := map[string]values.Value{ "observations": resp.Value, } - config, err := values.NewMap(map[string]any{ - "aggregation_method": "data_feeds_2_0", - "aggregation_config": map[string]any{ - // ETHUSD - "123": map[string]any{ - "deviation": "0.005", - "heartbeat": "24h", - }, - // LINKUSD - "456": map[string]any{ - "deviation": "0.001", - "heartbeat": "24h", - }, - // BTCUSD - "789": map[string]any{ - "deviation": "0.002", - "heartbeat": "6h", - }, - }, - "encoder": "EVM", - }) - if err != nil { - return nil, nil - } cr := capabilities.CapabilityRequest{ Metadata: capabilities.RequestMetadata{ - WorkflowID: mockedWorkflowID, + WorkflowID: mockedWorkflowID, + WorkflowExecutionID: mockedExecutionID, }, Inputs: &values.Map{Underlying: inputs}, - Config: config, + Config: e.consensusConfig, } return capabilities.ExecuteSync(ctx, e.consensus, cr) } @@ -191,26 +202,65 @@ func (e *Engine) Close() error { }) } -func NewEngine(lggr logger.Logger, registry types.CapabilitiesRegistry) (*Engine, error) { - ctx := context.Background() - trigger, err := registry.GetTrigger(ctx, "on_mercury_report") +func NewEngine(lggr logger.Logger, registry types.CapabilitiesRegistry) (engine *Engine, err error) { + engine = &Engine{ + logger: lggr.Named("WorkflowEngine"), + registry: registry, + callbackCh: make(chan capabilities.CapabilityResponse), + } + + // Trigger + engine.triggerType = "on_mercury_report" + engine.triggerConfig, err = values.NewMap( + map[string]any{ + "feedlist": []any{ + 123, 456, 789, // ETHUSD, LINKUSD, USDBTC + }, + }, + ) if err != nil { return nil, err } - consensus, err := registry.GetConsensus(ctx, "off-chain-reporting") + + // Consensus + engine.consensusType = "offchain_reporting" + engine.consensusConfig, err = values.NewMap(map[string]any{ + "aggregation_method": "data_feeds_2_0", + "aggregation_config": map[string]any{ + // ETHUSD + "0x1111111111111111111100000000000000000000000000000000000000000000": map[string]any{ + "deviation": decimal.NewFromFloat(0.003), + "heartbeat": 24, + }, + // LINKUSD + "0x2222222222222222222200000000000000000000000000000000000000000000": map[string]any{ + "deviation": decimal.NewFromFloat(0.001), + "heartbeat": 24, + }, + // BTCUSD + "0x3333333333333333333300000000000000000000000000000000000000000000": map[string]any{ + "deviation": decimal.NewFromFloat(0.002), + "heartbeat": 6, + }, + }, + "encoder": "EVM", + "encoder_config": map[string]any{ + "abi": "mercury_reports bytes[]", + }, + }) if err != nil { return nil, err } - target, err := registry.GetTarget(ctx, "write_polygon_mainnet") + + // Target + engine.targetType = "write_polygon-testnet-mumbai" + engine.targetConfig, err = values.NewMap(map[string]any{ + "address": "0xaabbcc", + "params": []any{"$(report)"}, + "abi": "receive(report bytes)", + }) if err != nil { return nil, err } - return &Engine{ - logger: lggr, - registry: registry, - trigger: trigger, - consensus: consensus, - target: target, - callbackCh: make(chan capabilities.CapabilityResponse), - }, nil + return } diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 603f5eee3b1..339792fd06d 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -41,15 +41,23 @@ func (m *mockCapability) Execute(ctx context.Context, ch chan<- capabilities.Cap return nil } +func (m *mockCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { + return nil +} + +func (m *mockCapability) UnregisterFromWorkflow(ctx context.Context, request capabilities.UnregisterFromWorkflowRequest) error { + return nil +} + type mockTriggerCapability struct { capabilities.CapabilityInfo - ch chan<- capabilities.CapabilityResponse + triggerEvent capabilities.CapabilityResponse } var _ capabilities.TriggerCapability = (*mockTriggerCapability)(nil) func (m *mockTriggerCapability) RegisterTrigger(ctx context.Context, ch chan<- capabilities.CapabilityResponse, req capabilities.CapabilityRequest) error { - m.ch = ch + ch <- m.triggerEvent return nil } @@ -59,7 +67,7 @@ func (m *mockTriggerCapability) UnregisterTrigger(ctx context.Context, req capab func TestEngineWithHardcodedWorkflow(t *testing.T) { ctx := context.Background() - reg := coreCap.NewRegistry() + reg := coreCap.NewRegistry(logger.TestLogger(t)) trigger := &mockTriggerCapability{ CapabilityInfo: capabilities.MustNewCapabilityInfo( @@ -73,7 +81,7 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { consensus := newMockCapability( capabilities.MustNewCapabilityInfo( - "off-chain-reporting", + "offchain_reporting", capabilities.CapabilityTypeConsensus, "an ocr3 consensus capability", "v3.0.0", @@ -88,7 +96,7 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { target := newMockCapability( capabilities.MustNewCapabilityInfo( - "write_polygon_mainnet", + "write_polygon-testnet-mumbai", capabilities.CapabilityTypeTarget, "a write capability targeting polygon mainnet", "v1.0.0", @@ -107,10 +115,6 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { eng, err := NewEngine(lggr, reg) require.NoError(t, err) - err = eng.Start(ctx) - require.NoError(t, err) - defer eng.Close() - resp, err := values.NewMap(map[string]any{ "123": decimal.NewFromFloat(1.00), "456": decimal.NewFromFloat(1.25), @@ -120,6 +124,10 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { cr := capabilities.CapabilityResponse{ Value: resp, } - trigger.ch <- cr + trigger.triggerEvent = cr + + err = eng.Start(ctx) + require.NoError(t, err) + defer eng.Close() assert.Equal(t, cr, <-target.response) } diff --git a/go.mod b/go.mod index be354048dcd..c0ef2b819de 100644 --- a/go.mod +++ b/go.mod @@ -69,7 +69,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 1f2da19fe3b..88ea058b06e 100644 --- a/go.sum +++ b/go.sum @@ -1168,8 +1168,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c h1:ielGD+tVCB+irZ+nDt5VDTYJauJI88tirkLLaHWLaTs= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 38954c5b178..ae2ac344c9b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -23,7 +23,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c github.com/smartcontractkit/chainlink-testing-framework v1.23.6 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 77c335604cd..fe81cc3ac68 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1507,8 +1507,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c h1:ielGD+tVCB+irZ+nDt5VDTYJauJI88tirkLLaHWLaTs= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= From 423529c1ac7fe2cf46c8423ebf6d76d9563c1dd6 Mon Sep 17 00:00:00 2001 From: Tate Date: Wed, 21 Feb 2024 12:22:13 -0700 Subject: [PATCH 67/98] [TT-704] Add go mod tidy to build/lint section and remove from others (#12120) * Add go mod tidy to build/lint section and remove from others * bump chainlink-github-actions versions * Remove tidy check from test matrix * fix go import issue in lint --- .../actions/build-chainlink-image/action.yml | 4 +- .github/actions/build-test-image/action.yml | 10 ++-- .github/actions/version-file-bump/action.yml | 2 +- .../workflows/automation-benchmark-tests.yml | 2 +- .github/workflows/automation-load-tests.yml | 2 +- .../workflows/automation-nightly-tests.yml | 2 +- .../workflows/automation-ondemand-tests.yml | 6 +-- .github/workflows/build-publish-pr.yml | 2 +- .github/workflows/ci-core.yml | 2 +- .../workflows/client-compatibility-tests.yml | 4 +- .github/workflows/integration-chaos-tests.yml | 6 +-- .github/workflows/integration-tests.yml | 49 ++++++++++++------- .github/workflows/live-testnet-tests.yml | 46 ++++++++--------- .github/workflows/on-demand-ocr-soak-test.yml | 2 +- .../on-demand-vrfv2-eth2-clients-test.yml | 2 +- .../on-demand-vrfv2-performance-test.yml | 2 +- .../on-demand-vrfv2plus-eth2-clients-test.yml | 2 +- .../on-demand-vrfv2plus-performance-test.yml | 2 +- integration-tests/load/go.mod | 16 +++--- integration-tests/load/go.sum | 4 +- .../load/zcluster/cluster_entrypoint_test.go | 6 ++- 21 files changed, 93 insertions(+), 80 deletions(-) diff --git a/.github/actions/build-chainlink-image/action.yml b/.github/actions/build-chainlink-image/action.yml index 644c109ab24..7a2f8a04b71 100644 --- a/.github/actions/build-chainlink-image/action.yml +++ b/.github/actions/build-chainlink-image/action.yml @@ -25,7 +25,7 @@ runs: steps: - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: repository: chainlink tag: ${{ inputs.git_commit_sha }}${{ inputs.tag_suffix }} @@ -33,7 +33,7 @@ runs: AWS_ROLE_TO_ASSUME: ${{ inputs.AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ inputs.git_commit_sha }} diff --git a/.github/actions/build-test-image/action.yml b/.github/actions/build-test-image/action.yml index d2ebeaa39b9..7fe002a82b2 100644 --- a/.github/actions/build-test-image/action.yml +++ b/.github/actions/build-test-image/action.yml @@ -34,7 +34,7 @@ runs: # Base Test Image Logic - name: Get CTF Version id: version - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: go-project-path: ./integration-tests module-name: github.com/smartcontractkit/chainlink-testing-framework @@ -71,7 +71,7 @@ runs: - name: Check if test base image exists if: steps.version.outputs.is_semantic == 'false' id: check-base-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: repository: ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/test-base-image tag: ${{ steps.long_sha.outputs.long_sha }} @@ -79,7 +79,7 @@ runs: AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - name: Build Base Image if: steps.version.outputs.is_semantic == 'false' && steps.check-base-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/docker/build-push@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/build-push@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: BASE_IMAGE_NAME: ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/test-base-image:${{ steps.long_sha.outputs.long_sha }} with: @@ -92,7 +92,7 @@ runs: # Test Runner Logic - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: repository: ${{ inputs.repository }} tag: ${{ inputs.tag }} @@ -100,7 +100,7 @@ runs: AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - name: Build and Publish Test Runner if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/docker/build-push@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/build-push@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: tags: | ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/${{ inputs.repository }}:${{ inputs.tag }} diff --git a/.github/actions/version-file-bump/action.yml b/.github/actions/version-file-bump/action.yml index 241b0f5a78c..2c9b95a6898 100644 --- a/.github/actions/version-file-bump/action.yml +++ b/.github/actions/version-file-bump/action.yml @@ -31,7 +31,7 @@ runs: current_version=$(head -n1 ./VERSION) echo "current_version=${current_version}" | tee -a "$GITHUB_OUTPUT" - name: Compare semantic versions - uses: smartcontractkit/chainlink-github-actions/semver-compare@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/semver-compare@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 id: compare with: version1: ${{ steps.get-current-version.outputs.current_version }} diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index 3b6bf6384fa..60d995c75cd 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -66,7 +66,7 @@ jobs: QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} suites: benchmark load chaos reorg - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: DETACH_RUNNER: true TEST_SUITE: benchmark diff --git a/.github/workflows/automation-load-tests.yml b/.github/workflows/automation-load-tests.yml index 7c2b737da88..0b22a6e2c82 100644 --- a/.github/workflows/automation-load-tests.yml +++ b/.github/workflows/automation-load-tests.yml @@ -82,7 +82,7 @@ jobs: QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} suites: benchmark load chaos reorg - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: RR_CPU: 4000m RR_MEM: 4Gi diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index 5fb8a8f87d1..6df574e58d0 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -82,7 +82,7 @@ jobs: upgradeImage: ${{ env.CHAINLINK_IMAGE }} upgradeVersion: ${{ github.sha }} - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: TEST_SUITE: ${{ matrix.tests.suite }} with: diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index a996399b93d..ed528d2490c 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -60,7 +60,7 @@ jobs: - name: Check if image exists if: inputs.chainlinkImage == '' id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: repository: chainlink tag: ${{ github.sha }}${{ matrix.image.tag-suffix }} @@ -68,7 +68,7 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists == 'false' && inputs.chainlinkImage == '' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ github.sha }} @@ -225,7 +225,7 @@ jobs: echo ::add-mask::$BASE64_CONFIG_OVERRIDE echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: TEST_SUITE: ${{ matrix.tests.suite }} with: diff --git a/.github/workflows/build-publish-pr.yml b/.github/workflows/build-publish-pr.yml index a093f86d3de..b7b06e149e2 100644 --- a/.github/workflows/build-publish-pr.yml +++ b/.github/workflows/build-publish-pr.yml @@ -32,7 +32,7 @@ jobs: - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: repository: ${{ env.ECR_IMAGE_NAME}} tag: sha-${{ env.GIT_SHORT_SHA }} diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 78d655d4cd8..01938679054 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -98,7 +98,7 @@ jobs: run: ./tools/bin/${{ matrix.cmd }} ./... - name: Print Filtered Test Results if: ${{ failure() && matrix.cmd == 'go_core_tests' }} - uses: smartcontractkit/chainlink-github-actions/go/go-test-results-parsing@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/go/go-test-results-parsing@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: results-file: ./output.txt output-file: ./output-short.txt diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 4d895cbfc5b..3dbcbe52cdc 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -69,7 +69,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - name: Build Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_download_vendor_packages_command: cd ./integration-tests && go mod download token: ${{ secrets.GITHUB_TOKEN }} @@ -224,7 +224,7 @@ jobs: echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV touch .root_dir - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout ${{ matrix.timeout }} -test.run ${{ matrix.test }} binary_name: tests diff --git a/.github/workflows/integration-chaos-tests.yml b/.github/workflows/integration-chaos-tests.yml index 8f9e9b030ec..364b2ac12bb 100644 --- a/.github/workflows/integration-chaos-tests.yml +++ b/.github/workflows/integration-chaos-tests.yml @@ -29,7 +29,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: repository: chainlink tag: ${{ github.sha }} @@ -37,7 +37,7 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ github.sha }} @@ -129,7 +129,7 @@ jobs: echo ::add-mask::$BASE64_CONFIG_OVERRIDE echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd integration-tests && go test -timeout 1h -count=1 -json -test.parallel 11 ./chaos 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index f8beac21a8c..45401b3cd63 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -45,7 +45,7 @@ jobs: echo "should-enforce=$SHOULD_ENFORCE" >> $GITHUB_OUTPUT - name: Enforce CTF Version if: steps.condition-check.outputs.should-enforce == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: go-project-path: ./integration-tests module-name: github.com/smartcontractkit/chainlink-testing-framework @@ -85,19 +85,28 @@ jobs: build-lint-integration-tests: name: Build and Lint integration-tests runs-on: ubuntu20.04-16cores-64GB + strategy: + matrix: + project: + - name: integration-tests + path: ./integration-tests + cache-id: e2e + - name: load + path: ./integration-tests/load + cache-id: load steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Setup Go - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: - test_download_vendor_packages_command: cd ./integration-tests && go mod download - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + test_download_vendor_packages_command: cd ${{ matrix.project.path }} && go mod download + go_mod_path: ${{ matrix.project.path }}/go.mod + cache_key_id: core-${{ matrix.project.cache-id }}-${{ env.MOD_CACHE_VERSION }} cache_restore_only: "true" - name: Build Go run: | - cd ./integration-tests + cd ${{ matrix.project.path }} go build ./... go test -run=^# ./... - name: Lint Go @@ -110,7 +119,7 @@ jobs: # only-new-issues is only applicable to PRs, otherwise it is always set to false only-new-issues: false # disabled for PRs due to unreliability args: --out-format colored-line-number,checkstyle:golangci-lint-report.xml - working-directory: ./integration-tests + working-directory: ${{ matrix.project.path }} build-chainlink: environment: integration @@ -302,7 +311,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -318,9 +327,10 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" + should_tidy: "false" - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 eth-smoke-tests-matrix-log-poller: if: ${{ !(contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') || github.event_name == 'workflow_dispatch') }} @@ -388,7 +398,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -404,6 +414,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" + should_tidy: "false" eth-smoke-tests-matrix: if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} @@ -569,7 +580,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -586,10 +597,11 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" + should_tidy: "false" # Run this step when changes that do not need the test to run are made - name: Run Setup if: needs.changes.outputs.src == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_download_vendor_packages_command: cd ./integration-tests && go mod download go_mod_path: ./integration-tests/go.mod @@ -598,6 +610,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + should_tidy: "false" - name: Show Otel-Collector Logs if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' run: | @@ -614,7 +627,7 @@ jobs: path: ./integration-tests/smoke/traces/trace-data.json - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: ./integration-tests/smoke/ @@ -685,7 +698,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - name: Run Setup - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_download_vendor_packages_command: | cd ./integration-tests @@ -741,7 +754,7 @@ jobs: upgradeImage: ${{ env.UPGRADE_IMAGE }} upgradeVersion: ${{ env.UPGRADE_VERSION }} - name: Run Migration Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -854,7 +867,7 @@ jobs: steps: - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: repository: chainlink-solana-tests tag: ${{ needs.get_solana_sha.outputs.sha }} @@ -995,7 +1008,7 @@ jobs: ref: ${{ needs.get_solana_sha.outputs.sha }} - name: Run Setup if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: go_mod_path: ./integration-tests/go.mod cache_restore_only: true @@ -1039,7 +1052,7 @@ jobs: echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: export ENV_JOB_IMAGE=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} && make test_smoke cl_repo: ${{ env.CHAINLINK_IMAGE }} diff --git a/.github/workflows/live-testnet-tests.yml b/.github/workflows/live-testnet-tests.yml index 1d273788eee..9cb980aca6c 100644 --- a/.github/workflows/live-testnet-tests.yml +++ b/.github/workflows/live-testnet-tests.yml @@ -91,7 +91,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - name: Build Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_download_vendor_packages_command: cd ./integration-tests && go mod download token: ${{ secrets.GITHUB_TOKEN }} @@ -248,7 +248,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -266,7 +266,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -320,7 +320,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -338,7 +338,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -392,7 +392,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -410,7 +410,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -464,7 +464,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -482,7 +482,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -532,7 +532,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -550,7 +550,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -604,7 +604,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -622,7 +622,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -676,7 +676,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -694,7 +694,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -748,7 +748,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -766,7 +766,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -816,7 +816,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -834,7 +834,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -885,7 +885,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -903,7 +903,7 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" @@ -953,7 +953,7 @@ jobs: with: name: tests - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} binary_name: tests @@ -971,6 +971,6 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_directory: "./" diff --git a/.github/workflows/on-demand-ocr-soak-test.yml b/.github/workflows/on-demand-ocr-soak-test.yml index 81f38ba0293..b44a3fb2d92 100644 --- a/.github/workflows/on-demand-ocr-soak-test.yml +++ b/.github/workflows/on-demand-ocr-soak-test.yml @@ -72,7 +72,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: DETACH_RUNNER: true TEST_SUITE: soak diff --git a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml index 865f59b5179..24db1e6ffcf 100644 --- a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml @@ -46,7 +46,7 @@ jobs: echo "### Execution client used" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -run TestVRFv2Basic ./smoke/vrfv2_test.go 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index 1e82d8ab02c..1e8ab9e9b71 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -67,7 +67,7 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run TestVRFV2Performance/vrfv2_performance_test ./vrfv2 test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml index 228f0cdc5ff..01777fba646 100644 --- a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml @@ -46,7 +46,7 @@ jobs: echo "### Execution client used" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -run ^TestVRFv2Plus$/^Link_Billing$ ./smoke/vrfv2plus_test.go 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index 2c2e11b6cb3..23484f963e3 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -68,7 +68,7 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@92e0f299a87522c2a37bfc4686c4d8a96dc9d28b # v2.3.5 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 with: test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run TestVRFV2PlusPerformance/vrfv2plus_performance_test ./vrfv2plus test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 15753c05866..174ea743c23 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -15,7 +15,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c github.com/smartcontractkit/chainlink-testing-framework v1.23.6 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 @@ -29,14 +29,6 @@ require ( // avoids ambigious imports of indirect dependencies exclude github.com/hashicorp/consul v1.2.1 -replace ( - github.com/testcontainers/testcontainers-go => github.com/Tofel/testcontainers-go v0.0.0-20231130110817-e6fbf9498b56 - // Pin K8s versions as their updates are highly disruptive and go mod keeps wanting to update them - k8s.io/api => k8s.io/api v0.25.11 - k8s.io/client-go => k8s.io/client-go v0.25.11 - k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d -) - require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect @@ -496,4 +488,10 @@ replace ( // type func(a Label, b Label) bool of func(a, b Label) bool {…} does not match inferred type func(a Label, b Label) int for func(a E, b E) int github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 + + github.com/testcontainers/testcontainers-go => github.com/Tofel/testcontainers-go v0.0.0-20231130110817-e6fbf9498b56 + // Pin K8s versions as their updates are highly disruptive and go mod keeps wanting to update them + k8s.io/api => k8s.io/api v0.25.11 + k8s.io/client-go => k8s.io/client-go v0.25.11 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 1aacb313ce5..1aaac86bd00 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1490,8 +1490,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1 h1:MNYkjakmoKxg7L1nmfAVeFOdONaLT7E62URBpmcTh84= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240219152510-85226a0fbdc1/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c h1:ielGD+tVCB+irZ+nDt5VDTYJauJI88tirkLLaHWLaTs= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= diff --git a/integration-tests/load/zcluster/cluster_entrypoint_test.go b/integration-tests/load/zcluster/cluster_entrypoint_test.go index 03133071b36..e5e8496af8b 100644 --- a/integration-tests/load/zcluster/cluster_entrypoint_test.go +++ b/integration-tests/load/zcluster/cluster_entrypoint_test.go @@ -1,10 +1,12 @@ package zcluster import ( - tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "testing" + "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" - "testing" + + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) func TestClusterEntrypoint(t *testing.T) { From 14c416c608e32d3bf95e636883afd62fbf795246 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Wed, 21 Feb 2024 23:55:04 +0400 Subject: [PATCH 68/98] Chore/auto fix load test build (#12125) * fix automation actions - build test image * load go mod tidy --- .github/workflows/automation-benchmark-tests.yml | 2 +- .github/workflows/automation-load-tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index 60d995c75cd..c81e46d9930 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -64,7 +64,7 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: benchmark load chaos reorg + suites: benchmark chaos reorg load - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: diff --git a/.github/workflows/automation-load-tests.yml b/.github/workflows/automation-load-tests.yml index 0b22a6e2c82..bbdd59f9f5c 100644 --- a/.github/workflows/automation-load-tests.yml +++ b/.github/workflows/automation-load-tests.yml @@ -80,7 +80,7 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: benchmark load chaos reorg + suites: benchmark chaos reorg load - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 env: From 2a53c4fe3208def2477ff49c6f6f26f407fec453 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 21 Feb 2024 15:40:53 -0500 Subject: [PATCH 69/98] provide integration test support for registry 2.2 (#12071) * provide integration test support for registry 2.2 * fixed some code smells * fix linter issues * linter * linter again * update * versions * add v2.2 * wait for module deployment * fix linter issues and add comments * fix sonarqube * update * linter * fix * tab vs spaces * fix * exclude a file in sonarqube duplication tests * update * update wrappers * update * fix * fix * update for reorg protection bool * update read only address and clean up tests * update parallel tests * small fix --------- Co-authored-by: Tate --- .../native_solc_compile_all_automation | 7 +- .../arbitrum_module/arbitrum_module.go | 313 ++++++++++++++ .../chain_module_base/chain_module_base.go | 313 ++++++++++++++ .../i_chain_module/i_chain_module.go | 294 +++++++++++++ .../optimism_module/optimism_module.go | 313 ++++++++++++++ .../generated/scroll_module/scroll_module.go | 313 ++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 5 + core/gethwrappers/go_generate.go | 5 + .../actions/automation_ocr_helpers.go | 23 +- .../actions/automation_ocr_helpers_local.go | 22 +- .../actions/automationv2/actions.go | 136 +++--- integration-tests/benchmark/keeper_test.go | 6 + .../chaos/automation_chaos_test.go | 3 +- .../contracts/contract_deployer.go | 196 ++++++++- .../ethereum/KeeperRegistryVersions.go | 1 + .../contracts/ethereum_keeper_contracts.go | 215 +++++++++- .../reorg/automation_reorg_test.go | 17 +- integration-tests/smoke/automation_test.go | 406 +++++++++--------- .../smoke/automation_test.go_test_list.json | 46 +- .../testsetups/keeper_benchmark.go | 22 +- .../universal/log_poller/helpers.go | 3 +- sonar-project.properties | 3 +- 22 files changed, 2324 insertions(+), 338 deletions(-) create mode 100644 core/gethwrappers/generated/arbitrum_module/arbitrum_module.go create mode 100644 core/gethwrappers/generated/chain_module_base/chain_module_base.go create mode 100644 core/gethwrappers/generated/i_chain_module/i_chain_module.go create mode 100644 core/gethwrappers/generated/optimism_module/optimism_module.go create mode 100644 core/gethwrappers/generated/scroll_module/scroll_module.go diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index 6194d3cb057..c508079813e 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -91,4 +91,9 @@ compileContract automation/dev/v2_2/AutomationRegistry2_2.sol compileContract automation/dev/v2_2/AutomationRegistryLogicA2_2.sol compileContract automation/dev/v2_2/AutomationRegistryLogicB2_2.sol compileContract automation/dev/v2_2/AutomationUtils2_2.sol -compileContract automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol \ No newline at end of file +compileContract automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol +compileContract automation/dev/chains/ArbitrumModule.sol +compileContract automation/dev/chains/ChainModuleBase.sol +compileContract automation/dev/chains/OptimismModule.sol +compileContract automation/dev/chains/ScrollModule.sol +compileContract automation/dev/interfaces/v2_2/IChainModule.sol \ No newline at end of file diff --git a/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go b/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go new file mode 100644 index 00000000000..abcfd3d4bc9 --- /dev/null +++ b/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go @@ -0,0 +1,313 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_module + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ArbitrumModuleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610426806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a2578063de9ee35e146100b557600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a36600461033e565b6100cb565b6040519081526020015b60405180910390f35b61007f610163565b61007f6101da565b61007f6100b036600461033e565b610228565b60408051614e2081526014602082015201610089565b600080606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801561011a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013e9190610357565b50505050915050828161015191906103d0565b61015c9060106103d0565b9392505050565b6000606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d591906103ed565b905090565b6000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b1573d6000803e3d6000fd5b600080606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029b91906103ed565b905080831015806102b657506101006102b48483610406565b115b156102c45750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa15801561031a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015c91906103ed565b60006020828403121561035057600080fd5b5035919050565b60008060008060008060c0878903121561037057600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176103e7576103e76103a1565b92915050565b6000602082840312156103ff57600080fd5b5051919050565b818103818111156103e7576103e76103a156fea164736f6c6343000813000a", +} + +var ArbitrumModuleABI = ArbitrumModuleMetaData.ABI + +var ArbitrumModuleBin = ArbitrumModuleMetaData.Bin + +func DeployArbitrumModule(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ArbitrumModule, error) { + parsed, err := ArbitrumModuleMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ArbitrumModuleBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ArbitrumModule{address: address, abi: *parsed, ArbitrumModuleCaller: ArbitrumModuleCaller{contract: contract}, ArbitrumModuleTransactor: ArbitrumModuleTransactor{contract: contract}, ArbitrumModuleFilterer: ArbitrumModuleFilterer{contract: contract}}, nil +} + +type ArbitrumModule struct { + address common.Address + abi abi.ABI + ArbitrumModuleCaller + ArbitrumModuleTransactor + ArbitrumModuleFilterer +} + +type ArbitrumModuleCaller struct { + contract *bind.BoundContract +} + +type ArbitrumModuleTransactor struct { + contract *bind.BoundContract +} + +type ArbitrumModuleFilterer struct { + contract *bind.BoundContract +} + +type ArbitrumModuleSession struct { + Contract *ArbitrumModule + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbitrumModuleCallerSession struct { + Contract *ArbitrumModuleCaller + CallOpts bind.CallOpts +} + +type ArbitrumModuleTransactorSession struct { + Contract *ArbitrumModuleTransactor + TransactOpts bind.TransactOpts +} + +type ArbitrumModuleRaw struct { + Contract *ArbitrumModule +} + +type ArbitrumModuleCallerRaw struct { + Contract *ArbitrumModuleCaller +} + +type ArbitrumModuleTransactorRaw struct { + Contract *ArbitrumModuleTransactor +} + +func NewArbitrumModule(address common.Address, backend bind.ContractBackend) (*ArbitrumModule, error) { + abi, err := abi.JSON(strings.NewReader(ArbitrumModuleABI)) + if err != nil { + return nil, err + } + contract, err := bindArbitrumModule(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbitrumModule{address: address, abi: abi, ArbitrumModuleCaller: ArbitrumModuleCaller{contract: contract}, ArbitrumModuleTransactor: ArbitrumModuleTransactor{contract: contract}, ArbitrumModuleFilterer: ArbitrumModuleFilterer{contract: contract}}, nil +} + +func NewArbitrumModuleCaller(address common.Address, caller bind.ContractCaller) (*ArbitrumModuleCaller, error) { + contract, err := bindArbitrumModule(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbitrumModuleCaller{contract: contract}, nil +} + +func NewArbitrumModuleTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbitrumModuleTransactor, error) { + contract, err := bindArbitrumModule(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbitrumModuleTransactor{contract: contract}, nil +} + +func NewArbitrumModuleFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbitrumModuleFilterer, error) { + contract, err := bindArbitrumModule(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbitrumModuleFilterer{contract: contract}, nil +} + +func bindArbitrumModule(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbitrumModuleMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbitrumModule *ArbitrumModuleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumModule.Contract.ArbitrumModuleCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumModule *ArbitrumModuleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumModule.Contract.ArbitrumModuleTransactor.contract.Transfer(opts) +} + +func (_ArbitrumModule *ArbitrumModuleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumModule.Contract.ArbitrumModuleTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbitrumModule *ArbitrumModuleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumModule.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumModule *ArbitrumModuleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumModule.Contract.contract.Transfer(opts) +} + +func (_ArbitrumModule *ArbitrumModuleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumModule.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbitrumModule *ArbitrumModuleCaller) BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) { + var out []interface{} + err := _ArbitrumModule.contract.Call(opts, &out, "blockHash", n) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_ArbitrumModule *ArbitrumModuleSession) BlockHash(n *big.Int) ([32]byte, error) { + return _ArbitrumModule.Contract.BlockHash(&_ArbitrumModule.CallOpts, n) +} + +func (_ArbitrumModule *ArbitrumModuleCallerSession) BlockHash(n *big.Int) ([32]byte, error) { + return _ArbitrumModule.Contract.BlockHash(&_ArbitrumModule.CallOpts, n) +} + +func (_ArbitrumModule *ArbitrumModuleCaller) BlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbitrumModule.contract.Call(opts, &out, "blockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbitrumModule *ArbitrumModuleSession) BlockNumber() (*big.Int, error) { + return _ArbitrumModule.Contract.BlockNumber(&_ArbitrumModule.CallOpts) +} + +func (_ArbitrumModule *ArbitrumModuleCallerSession) BlockNumber() (*big.Int, error) { + return _ArbitrumModule.Contract.BlockNumber(&_ArbitrumModule.CallOpts) +} + +func (_ArbitrumModule *ArbitrumModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbitrumModule.contract.Call(opts, &out, "getCurrentL1Fee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbitrumModule *ArbitrumModuleSession) GetCurrentL1Fee() (*big.Int, error) { + return _ArbitrumModule.Contract.GetCurrentL1Fee(&_ArbitrumModule.CallOpts) +} + +func (_ArbitrumModule *ArbitrumModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { + return _ArbitrumModule.Contract.GetCurrentL1Fee(&_ArbitrumModule.CallOpts) +} + +func (_ArbitrumModule *ArbitrumModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) { + var out []interface{} + err := _ArbitrumModule.contract.Call(opts, &out, "getGasOverhead") + + outstruct := new(GetGasOverhead) + if err != nil { + return *outstruct, err + } + + outstruct.ChainModuleFixedOverhead = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.ChainModulePerByteOverhead = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_ArbitrumModule *ArbitrumModuleSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _ArbitrumModule.Contract.GetGasOverhead(&_ArbitrumModule.CallOpts) +} + +func (_ArbitrumModule *ArbitrumModuleCallerSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _ArbitrumModule.Contract.GetGasOverhead(&_ArbitrumModule.CallOpts) +} + +func (_ArbitrumModule *ArbitrumModuleCaller) GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _ArbitrumModule.contract.Call(opts, &out, "getMaxL1Fee", dataSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbitrumModule *ArbitrumModuleSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ArbitrumModule.Contract.GetMaxL1Fee(&_ArbitrumModule.CallOpts, dataSize) +} + +func (_ArbitrumModule *ArbitrumModuleCallerSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ArbitrumModule.Contract.GetMaxL1Fee(&_ArbitrumModule.CallOpts, dataSize) +} + +type GetGasOverhead struct { + ChainModuleFixedOverhead *big.Int + ChainModulePerByteOverhead *big.Int +} + +func (_ArbitrumModule *ArbitrumModule) Address() common.Address { + return _ArbitrumModule.address +} + +type ArbitrumModuleInterface interface { + BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) + + BlockNumber(opts *bind.CallOpts) (*big.Int, error) + + GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + + GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) + + GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/chain_module_base/chain_module_base.go b/core/gethwrappers/generated/chain_module_base/chain_module_base.go new file mode 100644 index 00000000000..4c830566ef5 --- /dev/null +++ b/core/gethwrappers/generated/chain_module_base/chain_module_base.go @@ -0,0 +1,313 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package chain_module_base + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ChainModuleBaseMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061015a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a0578063de9ee35e146100b357600080fd5b8063125441401461006c57806318b8f61314610093575b600080fd5b61008061007a3660046100f4565b50600090565b6040519081526020015b60405180910390f35b6000610080565b43610080565b6100806100ae3660046100f4565b6100c7565b60408051600080825260208201520161008a565b600043821015806100e257506101006100e0834361010d565b115b156100ef57506000919050565b504090565b60006020828403121561010657600080fd5b5035919050565b81810381811115610147577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000a", +} + +var ChainModuleBaseABI = ChainModuleBaseMetaData.ABI + +var ChainModuleBaseBin = ChainModuleBaseMetaData.Bin + +func DeployChainModuleBase(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ChainModuleBase, error) { + parsed, err := ChainModuleBaseMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ChainModuleBaseBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ChainModuleBase{address: address, abi: *parsed, ChainModuleBaseCaller: ChainModuleBaseCaller{contract: contract}, ChainModuleBaseTransactor: ChainModuleBaseTransactor{contract: contract}, ChainModuleBaseFilterer: ChainModuleBaseFilterer{contract: contract}}, nil +} + +type ChainModuleBase struct { + address common.Address + abi abi.ABI + ChainModuleBaseCaller + ChainModuleBaseTransactor + ChainModuleBaseFilterer +} + +type ChainModuleBaseCaller struct { + contract *bind.BoundContract +} + +type ChainModuleBaseTransactor struct { + contract *bind.BoundContract +} + +type ChainModuleBaseFilterer struct { + contract *bind.BoundContract +} + +type ChainModuleBaseSession struct { + Contract *ChainModuleBase + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ChainModuleBaseCallerSession struct { + Contract *ChainModuleBaseCaller + CallOpts bind.CallOpts +} + +type ChainModuleBaseTransactorSession struct { + Contract *ChainModuleBaseTransactor + TransactOpts bind.TransactOpts +} + +type ChainModuleBaseRaw struct { + Contract *ChainModuleBase +} + +type ChainModuleBaseCallerRaw struct { + Contract *ChainModuleBaseCaller +} + +type ChainModuleBaseTransactorRaw struct { + Contract *ChainModuleBaseTransactor +} + +func NewChainModuleBase(address common.Address, backend bind.ContractBackend) (*ChainModuleBase, error) { + abi, err := abi.JSON(strings.NewReader(ChainModuleBaseABI)) + if err != nil { + return nil, err + } + contract, err := bindChainModuleBase(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ChainModuleBase{address: address, abi: abi, ChainModuleBaseCaller: ChainModuleBaseCaller{contract: contract}, ChainModuleBaseTransactor: ChainModuleBaseTransactor{contract: contract}, ChainModuleBaseFilterer: ChainModuleBaseFilterer{contract: contract}}, nil +} + +func NewChainModuleBaseCaller(address common.Address, caller bind.ContractCaller) (*ChainModuleBaseCaller, error) { + contract, err := bindChainModuleBase(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ChainModuleBaseCaller{contract: contract}, nil +} + +func NewChainModuleBaseTransactor(address common.Address, transactor bind.ContractTransactor) (*ChainModuleBaseTransactor, error) { + contract, err := bindChainModuleBase(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ChainModuleBaseTransactor{contract: contract}, nil +} + +func NewChainModuleBaseFilterer(address common.Address, filterer bind.ContractFilterer) (*ChainModuleBaseFilterer, error) { + contract, err := bindChainModuleBase(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ChainModuleBaseFilterer{contract: contract}, nil +} + +func bindChainModuleBase(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ChainModuleBaseMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ChainModuleBase *ChainModuleBaseRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ChainModuleBase.Contract.ChainModuleBaseCaller.contract.Call(opts, result, method, params...) +} + +func (_ChainModuleBase *ChainModuleBaseRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChainModuleBase.Contract.ChainModuleBaseTransactor.contract.Transfer(opts) +} + +func (_ChainModuleBase *ChainModuleBaseRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ChainModuleBase.Contract.ChainModuleBaseTransactor.contract.Transact(opts, method, params...) +} + +func (_ChainModuleBase *ChainModuleBaseCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ChainModuleBase.Contract.contract.Call(opts, result, method, params...) +} + +func (_ChainModuleBase *ChainModuleBaseTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ChainModuleBase.Contract.contract.Transfer(opts) +} + +func (_ChainModuleBase *ChainModuleBaseTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ChainModuleBase.Contract.contract.Transact(opts, method, params...) +} + +func (_ChainModuleBase *ChainModuleBaseCaller) BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) { + var out []interface{} + err := _ChainModuleBase.contract.Call(opts, &out, "blockHash", n) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_ChainModuleBase *ChainModuleBaseSession) BlockHash(n *big.Int) ([32]byte, error) { + return _ChainModuleBase.Contract.BlockHash(&_ChainModuleBase.CallOpts, n) +} + +func (_ChainModuleBase *ChainModuleBaseCallerSession) BlockHash(n *big.Int) ([32]byte, error) { + return _ChainModuleBase.Contract.BlockHash(&_ChainModuleBase.CallOpts, n) +} + +func (_ChainModuleBase *ChainModuleBaseCaller) BlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ChainModuleBase.contract.Call(opts, &out, "blockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ChainModuleBase *ChainModuleBaseSession) BlockNumber() (*big.Int, error) { + return _ChainModuleBase.Contract.BlockNumber(&_ChainModuleBase.CallOpts) +} + +func (_ChainModuleBase *ChainModuleBaseCallerSession) BlockNumber() (*big.Int, error) { + return _ChainModuleBase.Contract.BlockNumber(&_ChainModuleBase.CallOpts) +} + +func (_ChainModuleBase *ChainModuleBaseCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ChainModuleBase.contract.Call(opts, &out, "getCurrentL1Fee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ChainModuleBase *ChainModuleBaseSession) GetCurrentL1Fee() (*big.Int, error) { + return _ChainModuleBase.Contract.GetCurrentL1Fee(&_ChainModuleBase.CallOpts) +} + +func (_ChainModuleBase *ChainModuleBaseCallerSession) GetCurrentL1Fee() (*big.Int, error) { + return _ChainModuleBase.Contract.GetCurrentL1Fee(&_ChainModuleBase.CallOpts) +} + +func (_ChainModuleBase *ChainModuleBaseCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) { + var out []interface{} + err := _ChainModuleBase.contract.Call(opts, &out, "getGasOverhead") + + outstruct := new(GetGasOverhead) + if err != nil { + return *outstruct, err + } + + outstruct.ChainModuleFixedOverhead = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.ChainModulePerByteOverhead = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_ChainModuleBase *ChainModuleBaseSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _ChainModuleBase.Contract.GetGasOverhead(&_ChainModuleBase.CallOpts) +} + +func (_ChainModuleBase *ChainModuleBaseCallerSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _ChainModuleBase.Contract.GetGasOverhead(&_ChainModuleBase.CallOpts) +} + +func (_ChainModuleBase *ChainModuleBaseCaller) GetMaxL1Fee(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _ChainModuleBase.contract.Call(opts, &out, "getMaxL1Fee", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ChainModuleBase *ChainModuleBaseSession) GetMaxL1Fee(arg0 *big.Int) (*big.Int, error) { + return _ChainModuleBase.Contract.GetMaxL1Fee(&_ChainModuleBase.CallOpts, arg0) +} + +func (_ChainModuleBase *ChainModuleBaseCallerSession) GetMaxL1Fee(arg0 *big.Int) (*big.Int, error) { + return _ChainModuleBase.Contract.GetMaxL1Fee(&_ChainModuleBase.CallOpts, arg0) +} + +type GetGasOverhead struct { + ChainModuleFixedOverhead *big.Int + ChainModulePerByteOverhead *big.Int +} + +func (_ChainModuleBase *ChainModuleBase) Address() common.Address { + return _ChainModuleBase.address +} + +type ChainModuleBaseInterface interface { + BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) + + BlockNumber(opts *bind.CallOpts) (*big.Int, error) + + GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + + GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) + + GetMaxL1Fee(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/i_chain_module/i_chain_module.go b/core/gethwrappers/generated/i_chain_module/i_chain_module.go new file mode 100644 index 00000000000..23cec8fb9c8 --- /dev/null +++ b/core/gethwrappers/generated/i_chain_module/i_chain_module.go @@ -0,0 +1,294 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package i_chain_module + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var IChainModuleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var IChainModuleABI = IChainModuleMetaData.ABI + +type IChainModule struct { + address common.Address + abi abi.ABI + IChainModuleCaller + IChainModuleTransactor + IChainModuleFilterer +} + +type IChainModuleCaller struct { + contract *bind.BoundContract +} + +type IChainModuleTransactor struct { + contract *bind.BoundContract +} + +type IChainModuleFilterer struct { + contract *bind.BoundContract +} + +type IChainModuleSession struct { + Contract *IChainModule + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type IChainModuleCallerSession struct { + Contract *IChainModuleCaller + CallOpts bind.CallOpts +} + +type IChainModuleTransactorSession struct { + Contract *IChainModuleTransactor + TransactOpts bind.TransactOpts +} + +type IChainModuleRaw struct { + Contract *IChainModule +} + +type IChainModuleCallerRaw struct { + Contract *IChainModuleCaller +} + +type IChainModuleTransactorRaw struct { + Contract *IChainModuleTransactor +} + +func NewIChainModule(address common.Address, backend bind.ContractBackend) (*IChainModule, error) { + abi, err := abi.JSON(strings.NewReader(IChainModuleABI)) + if err != nil { + return nil, err + } + contract, err := bindIChainModule(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IChainModule{address: address, abi: abi, IChainModuleCaller: IChainModuleCaller{contract: contract}, IChainModuleTransactor: IChainModuleTransactor{contract: contract}, IChainModuleFilterer: IChainModuleFilterer{contract: contract}}, nil +} + +func NewIChainModuleCaller(address common.Address, caller bind.ContractCaller) (*IChainModuleCaller, error) { + contract, err := bindIChainModule(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IChainModuleCaller{contract: contract}, nil +} + +func NewIChainModuleTransactor(address common.Address, transactor bind.ContractTransactor) (*IChainModuleTransactor, error) { + contract, err := bindIChainModule(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IChainModuleTransactor{contract: contract}, nil +} + +func NewIChainModuleFilterer(address common.Address, filterer bind.ContractFilterer) (*IChainModuleFilterer, error) { + contract, err := bindIChainModule(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IChainModuleFilterer{contract: contract}, nil +} + +func bindIChainModule(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IChainModuleMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_IChainModule *IChainModuleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IChainModule.Contract.IChainModuleCaller.contract.Call(opts, result, method, params...) +} + +func (_IChainModule *IChainModuleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IChainModule.Contract.IChainModuleTransactor.contract.Transfer(opts) +} + +func (_IChainModule *IChainModuleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IChainModule.Contract.IChainModuleTransactor.contract.Transact(opts, method, params...) +} + +func (_IChainModule *IChainModuleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IChainModule.Contract.contract.Call(opts, result, method, params...) +} + +func (_IChainModule *IChainModuleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IChainModule.Contract.contract.Transfer(opts) +} + +func (_IChainModule *IChainModuleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IChainModule.Contract.contract.Transact(opts, method, params...) +} + +func (_IChainModule *IChainModuleCaller) BlockHash(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _IChainModule.contract.Call(opts, &out, "blockHash", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_IChainModule *IChainModuleSession) BlockHash(arg0 *big.Int) ([32]byte, error) { + return _IChainModule.Contract.BlockHash(&_IChainModule.CallOpts, arg0) +} + +func (_IChainModule *IChainModuleCallerSession) BlockHash(arg0 *big.Int) ([32]byte, error) { + return _IChainModule.Contract.BlockHash(&_IChainModule.CallOpts, arg0) +} + +func (_IChainModule *IChainModuleCaller) BlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IChainModule.contract.Call(opts, &out, "blockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IChainModule *IChainModuleSession) BlockNumber() (*big.Int, error) { + return _IChainModule.Contract.BlockNumber(&_IChainModule.CallOpts) +} + +func (_IChainModule *IChainModuleCallerSession) BlockNumber() (*big.Int, error) { + return _IChainModule.Contract.BlockNumber(&_IChainModule.CallOpts) +} + +func (_IChainModule *IChainModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IChainModule.contract.Call(opts, &out, "getCurrentL1Fee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IChainModule *IChainModuleSession) GetCurrentL1Fee() (*big.Int, error) { + return _IChainModule.Contract.GetCurrentL1Fee(&_IChainModule.CallOpts) +} + +func (_IChainModule *IChainModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { + return _IChainModule.Contract.GetCurrentL1Fee(&_IChainModule.CallOpts) +} + +func (_IChainModule *IChainModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) { + var out []interface{} + err := _IChainModule.contract.Call(opts, &out, "getGasOverhead") + + outstruct := new(GetGasOverhead) + if err != nil { + return *outstruct, err + } + + outstruct.ChainModuleFixedOverhead = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.ChainModulePerByteOverhead = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_IChainModule *IChainModuleSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _IChainModule.Contract.GetGasOverhead(&_IChainModule.CallOpts) +} + +func (_IChainModule *IChainModuleCallerSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _IChainModule.Contract.GetGasOverhead(&_IChainModule.CallOpts) +} + +func (_IChainModule *IChainModuleCaller) GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _IChainModule.contract.Call(opts, &out, "getMaxL1Fee", dataSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IChainModule *IChainModuleSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _IChainModule.Contract.GetMaxL1Fee(&_IChainModule.CallOpts, dataSize) +} + +func (_IChainModule *IChainModuleCallerSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _IChainModule.Contract.GetMaxL1Fee(&_IChainModule.CallOpts, dataSize) +} + +type GetGasOverhead struct { + ChainModuleFixedOverhead *big.Int + ChainModulePerByteOverhead *big.Int +} + +func (_IChainModule *IChainModule) Address() common.Address { + return _IChainModule.address +} + +type IChainModuleInterface interface { + BlockHash(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + BlockNumber(opts *bind.CallOpts) (*big.Int, error) + + GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + + GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) + + GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/optimism_module/optimism_module.go b/core/gethwrappers/generated/optimism_module/optimism_module.go new file mode 100644 index 00000000000..c6015b1e32b --- /dev/null +++ b/core/gethwrappers/generated/optimism_module/optimism_module.go @@ -0,0 +1,313 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_module + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismModuleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506104a3806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a0578063de9ee35e146100b357600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a3660046102e8565b6100c9565b6040519081526020015b60405180910390f35b61007f6101ea565b4361007f565b61007f6100ae3660046102e8565b6102bb565b60408051614e2081526014602082015201610089565b6000806100d7836004610330565b67ffffffffffffffff8111156100ef576100ef61034d565b6040519080825280601f01601f191660200182016040528015610119576020820181803683370190505b50905073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e82604051806060016040528060238152602001610474602391396040516020016101779291906103a0565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016101a291906103cf565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610420565b9392505050565b600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e6000366040518060600160405280602381526020016104746023913960405160200161024a93929190610439565b6040516020818303038152906040526040518263ffffffff1660e01b815260040161027591906103cf565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190610420565b905090565b600043821015806102d657506101006102d48343610460565b115b156102e357506000919050565b504090565b6000602082840312156102fa57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761034757610347610301565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b8381101561039757818101518382015260200161037f565b50506000910152565b600083516103b281846020880161037c565b8351908301906103c681836020880161037c565b01949350505050565b60208152600082518060208401526103ee81604085016020870161037c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561043257600080fd5b5051919050565b82848237600083820160008152835161045681836020880161037c565b0195945050505050565b818103818111156103475761034761030156feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", +} + +var OptimismModuleABI = OptimismModuleMetaData.ABI + +var OptimismModuleBin = OptimismModuleMetaData.Bin + +func DeployOptimismModule(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *OptimismModule, error) { + parsed, err := OptimismModuleMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OptimismModuleBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OptimismModule{address: address, abi: *parsed, OptimismModuleCaller: OptimismModuleCaller{contract: contract}, OptimismModuleTransactor: OptimismModuleTransactor{contract: contract}, OptimismModuleFilterer: OptimismModuleFilterer{contract: contract}}, nil +} + +type OptimismModule struct { + address common.Address + abi abi.ABI + OptimismModuleCaller + OptimismModuleTransactor + OptimismModuleFilterer +} + +type OptimismModuleCaller struct { + contract *bind.BoundContract +} + +type OptimismModuleTransactor struct { + contract *bind.BoundContract +} + +type OptimismModuleFilterer struct { + contract *bind.BoundContract +} + +type OptimismModuleSession struct { + Contract *OptimismModule + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismModuleCallerSession struct { + Contract *OptimismModuleCaller + CallOpts bind.CallOpts +} + +type OptimismModuleTransactorSession struct { + Contract *OptimismModuleTransactor + TransactOpts bind.TransactOpts +} + +type OptimismModuleRaw struct { + Contract *OptimismModule +} + +type OptimismModuleCallerRaw struct { + Contract *OptimismModuleCaller +} + +type OptimismModuleTransactorRaw struct { + Contract *OptimismModuleTransactor +} + +func NewOptimismModule(address common.Address, backend bind.ContractBackend) (*OptimismModule, error) { + abi, err := abi.JSON(strings.NewReader(OptimismModuleABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismModule(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismModule{address: address, abi: abi, OptimismModuleCaller: OptimismModuleCaller{contract: contract}, OptimismModuleTransactor: OptimismModuleTransactor{contract: contract}, OptimismModuleFilterer: OptimismModuleFilterer{contract: contract}}, nil +} + +func NewOptimismModuleCaller(address common.Address, caller bind.ContractCaller) (*OptimismModuleCaller, error) { + contract, err := bindOptimismModule(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismModuleCaller{contract: contract}, nil +} + +func NewOptimismModuleTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismModuleTransactor, error) { + contract, err := bindOptimismModule(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismModuleTransactor{contract: contract}, nil +} + +func NewOptimismModuleFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismModuleFilterer, error) { + contract, err := bindOptimismModule(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismModuleFilterer{contract: contract}, nil +} + +func bindOptimismModule(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismModuleMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismModule *OptimismModuleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismModule.Contract.OptimismModuleCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismModule *OptimismModuleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismModule.Contract.OptimismModuleTransactor.contract.Transfer(opts) +} + +func (_OptimismModule *OptimismModuleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismModule.Contract.OptimismModuleTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismModule *OptimismModuleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismModule.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismModule *OptimismModuleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismModule.Contract.contract.Transfer(opts) +} + +func (_OptimismModule *OptimismModuleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismModule.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismModule *OptimismModuleCaller) BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) { + var out []interface{} + err := _OptimismModule.contract.Call(opts, &out, "blockHash", n) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_OptimismModule *OptimismModuleSession) BlockHash(n *big.Int) ([32]byte, error) { + return _OptimismModule.Contract.BlockHash(&_OptimismModule.CallOpts, n) +} + +func (_OptimismModule *OptimismModuleCallerSession) BlockHash(n *big.Int) ([32]byte, error) { + return _OptimismModule.Contract.BlockHash(&_OptimismModule.CallOpts, n) +} + +func (_OptimismModule *OptimismModuleCaller) BlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismModule.contract.Call(opts, &out, "blockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismModule *OptimismModuleSession) BlockNumber() (*big.Int, error) { + return _OptimismModule.Contract.BlockNumber(&_OptimismModule.CallOpts) +} + +func (_OptimismModule *OptimismModuleCallerSession) BlockNumber() (*big.Int, error) { + return _OptimismModule.Contract.BlockNumber(&_OptimismModule.CallOpts) +} + +func (_OptimismModule *OptimismModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismModule.contract.Call(opts, &out, "getCurrentL1Fee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismModule *OptimismModuleSession) GetCurrentL1Fee() (*big.Int, error) { + return _OptimismModule.Contract.GetCurrentL1Fee(&_OptimismModule.CallOpts) +} + +func (_OptimismModule *OptimismModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { + return _OptimismModule.Contract.GetCurrentL1Fee(&_OptimismModule.CallOpts) +} + +func (_OptimismModule *OptimismModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) { + var out []interface{} + err := _OptimismModule.contract.Call(opts, &out, "getGasOverhead") + + outstruct := new(GetGasOverhead) + if err != nil { + return *outstruct, err + } + + outstruct.ChainModuleFixedOverhead = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.ChainModulePerByteOverhead = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_OptimismModule *OptimismModuleSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _OptimismModule.Contract.GetGasOverhead(&_OptimismModule.CallOpts) +} + +func (_OptimismModule *OptimismModuleCallerSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _OptimismModule.Contract.GetGasOverhead(&_OptimismModule.CallOpts) +} + +func (_OptimismModule *OptimismModuleCaller) GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _OptimismModule.contract.Call(opts, &out, "getMaxL1Fee", dataSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismModule *OptimismModuleSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModule.Contract.GetMaxL1Fee(&_OptimismModule.CallOpts, dataSize) +} + +func (_OptimismModule *OptimismModuleCallerSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModule.Contract.GetMaxL1Fee(&_OptimismModule.CallOpts, dataSize) +} + +type GetGasOverhead struct { + ChainModuleFixedOverhead *big.Int + ChainModulePerByteOverhead *big.Int +} + +func (_OptimismModule *OptimismModule) Address() common.Address { + return _OptimismModule.address +} + +type OptimismModuleInterface interface { + BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) + + BlockNumber(opts *bind.CallOpts) (*big.Int, error) + + GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + + GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) + + GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/scroll_module/scroll_module.go b/core/gethwrappers/generated/scroll_module/scroll_module.go new file mode 100644 index 00000000000..2bb37a8d480 --- /dev/null +++ b/core/gethwrappers/generated/scroll_module/scroll_module.go @@ -0,0 +1,313 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package scroll_module + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ScrollModuleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506104f8806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a0578063de9ee35e146100b357600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a3660046102e8565b6100c9565b6040519081526020015b60405180910390f35b61007f6101ea565b4361007f565b61007f6100ae3660046102e8565b6102bb565b60408051614e2081526014602082015201610089565b6000806100d7836004610330565b67ffffffffffffffff8111156100ef576100ef61034d565b6040519080825280601f01601f191660200182016040528015610119576020820181803683370190505b50905073530000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff166349948e0e826040518060a0016040528060788152602001610474607891396040516020016101779291906103a0565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016101a291906103cf565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610420565b9392505050565b600073530000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff166349948e0e6000366040518060a00160405280607881526020016104746078913960405160200161024a93929190610439565b6040516020818303038152906040526040518263ffffffff1660e01b815260040161027591906103cf565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190610420565b905090565b600043821015806102d657506101006102d48343610460565b115b156102e357506000919050565b504090565b6000602082840312156102fa57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761034757610347610301565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b8381101561039757818101518382015260200161037f565b50506000910152565b600083516103b281846020880161037c565b8351908301906103c681836020880161037c565b01949350505050565b60208152600082518060208401526103ee81604085016020870161037c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561043257600080fd5b5051919050565b82848237600083820160008152835161045681836020880161037c565b0195945050505050565b818103818111156103475761034761030156feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", +} + +var ScrollModuleABI = ScrollModuleMetaData.ABI + +var ScrollModuleBin = ScrollModuleMetaData.Bin + +func DeployScrollModule(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ScrollModule, error) { + parsed, err := ScrollModuleMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ScrollModuleBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ScrollModule{address: address, abi: *parsed, ScrollModuleCaller: ScrollModuleCaller{contract: contract}, ScrollModuleTransactor: ScrollModuleTransactor{contract: contract}, ScrollModuleFilterer: ScrollModuleFilterer{contract: contract}}, nil +} + +type ScrollModule struct { + address common.Address + abi abi.ABI + ScrollModuleCaller + ScrollModuleTransactor + ScrollModuleFilterer +} + +type ScrollModuleCaller struct { + contract *bind.BoundContract +} + +type ScrollModuleTransactor struct { + contract *bind.BoundContract +} + +type ScrollModuleFilterer struct { + contract *bind.BoundContract +} + +type ScrollModuleSession struct { + Contract *ScrollModule + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ScrollModuleCallerSession struct { + Contract *ScrollModuleCaller + CallOpts bind.CallOpts +} + +type ScrollModuleTransactorSession struct { + Contract *ScrollModuleTransactor + TransactOpts bind.TransactOpts +} + +type ScrollModuleRaw struct { + Contract *ScrollModule +} + +type ScrollModuleCallerRaw struct { + Contract *ScrollModuleCaller +} + +type ScrollModuleTransactorRaw struct { + Contract *ScrollModuleTransactor +} + +func NewScrollModule(address common.Address, backend bind.ContractBackend) (*ScrollModule, error) { + abi, err := abi.JSON(strings.NewReader(ScrollModuleABI)) + if err != nil { + return nil, err + } + contract, err := bindScrollModule(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ScrollModule{address: address, abi: abi, ScrollModuleCaller: ScrollModuleCaller{contract: contract}, ScrollModuleTransactor: ScrollModuleTransactor{contract: contract}, ScrollModuleFilterer: ScrollModuleFilterer{contract: contract}}, nil +} + +func NewScrollModuleCaller(address common.Address, caller bind.ContractCaller) (*ScrollModuleCaller, error) { + contract, err := bindScrollModule(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ScrollModuleCaller{contract: contract}, nil +} + +func NewScrollModuleTransactor(address common.Address, transactor bind.ContractTransactor) (*ScrollModuleTransactor, error) { + contract, err := bindScrollModule(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ScrollModuleTransactor{contract: contract}, nil +} + +func NewScrollModuleFilterer(address common.Address, filterer bind.ContractFilterer) (*ScrollModuleFilterer, error) { + contract, err := bindScrollModule(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ScrollModuleFilterer{contract: contract}, nil +} + +func bindScrollModule(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ScrollModuleMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ScrollModule *ScrollModuleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ScrollModule.Contract.ScrollModuleCaller.contract.Call(opts, result, method, params...) +} + +func (_ScrollModule *ScrollModuleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ScrollModule.Contract.ScrollModuleTransactor.contract.Transfer(opts) +} + +func (_ScrollModule *ScrollModuleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ScrollModule.Contract.ScrollModuleTransactor.contract.Transact(opts, method, params...) +} + +func (_ScrollModule *ScrollModuleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ScrollModule.Contract.contract.Call(opts, result, method, params...) +} + +func (_ScrollModule *ScrollModuleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ScrollModule.Contract.contract.Transfer(opts) +} + +func (_ScrollModule *ScrollModuleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ScrollModule.Contract.contract.Transact(opts, method, params...) +} + +func (_ScrollModule *ScrollModuleCaller) BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) { + var out []interface{} + err := _ScrollModule.contract.Call(opts, &out, "blockHash", n) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_ScrollModule *ScrollModuleSession) BlockHash(n *big.Int) ([32]byte, error) { + return _ScrollModule.Contract.BlockHash(&_ScrollModule.CallOpts, n) +} + +func (_ScrollModule *ScrollModuleCallerSession) BlockHash(n *big.Int) ([32]byte, error) { + return _ScrollModule.Contract.BlockHash(&_ScrollModule.CallOpts, n) +} + +func (_ScrollModule *ScrollModuleCaller) BlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ScrollModule.contract.Call(opts, &out, "blockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ScrollModule *ScrollModuleSession) BlockNumber() (*big.Int, error) { + return _ScrollModule.Contract.BlockNumber(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCallerSession) BlockNumber() (*big.Int, error) { + return _ScrollModule.Contract.BlockNumber(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ScrollModule.contract.Call(opts, &out, "getCurrentL1Fee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ScrollModule *ScrollModuleSession) GetCurrentL1Fee() (*big.Int, error) { + return _ScrollModule.Contract.GetCurrentL1Fee(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { + return _ScrollModule.Contract.GetCurrentL1Fee(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) { + var out []interface{} + err := _ScrollModule.contract.Call(opts, &out, "getGasOverhead") + + outstruct := new(GetGasOverhead) + if err != nil { + return *outstruct, err + } + + outstruct.ChainModuleFixedOverhead = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.ChainModulePerByteOverhead = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_ScrollModule *ScrollModuleSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _ScrollModule.Contract.GetGasOverhead(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCallerSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _ScrollModule.Contract.GetGasOverhead(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCaller) GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _ScrollModule.contract.Call(opts, &out, "getMaxL1Fee", dataSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ScrollModule *ScrollModuleSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ScrollModule.Contract.GetMaxL1Fee(&_ScrollModule.CallOpts, dataSize) +} + +func (_ScrollModule *ScrollModuleCallerSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ScrollModule.Contract.GetMaxL1Fee(&_ScrollModule.CallOpts, dataSize) +} + +type GetGasOverhead struct { + ChainModuleFixedOverhead *big.Int + ChainModulePerByteOverhead *big.Int +} + +func (_ScrollModule *ScrollModule) Address() common.Address { + return _ScrollModule.address +} + +type ScrollModuleInterface interface { + BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) + + BlockNumber(opts *bind.CallOpts) (*big.Int, error) + + GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + + GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) + + GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index d112efac94f..29e0ffacf85 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,6 +1,7 @@ GETH_VERSION: 1.13.8 aggregator_v2v3_interface: ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.bin 95e8814b408bb05bf21742ef580d98698b7db6a9bac6a35c3de12b23aec4ee28 aggregator_v3_interface: ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV3Interface.bin 351b55d3b0f04af67db6dfb5c92f1c64479400ca1fec77afc20bc0ce65cb49ab +arbitrum_module: ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin 9048e5ccf9a6274cbf131cb5d7ef24b783e2fc9595153e0abacddfd2b6668469 authorized_forwarder: ../../contracts/solc/v0.8.19/AuthorizedForwarder/AuthorizedForwarder.abi ../../contracts/solc/v0.8.19/AuthorizedForwarder/AuthorizedForwarder.bin 8ea76c883d460f8353a45a493f2aebeb5a2d9a7b4619d1bc4fff5fb590bb3e10 authorized_receiver: ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedReceiver.abi ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedReceiver.bin 18e8969ba3234b027e1b16c11a783aca58d0ea5c2361010ec597f134b7bf1c4f automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e @@ -16,6 +17,7 @@ batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore/BatchBloc batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.bin d0a54963260d8c1f1bbd984b758285e6027cfb5a7e42701bcb562ab123219332 batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin 73cb626b5cb2c3464655b61b8ac42fe7a1963fe25e6a5eea40b8e4d5bff3de36 blockhash_store: ../../contracts/solc/v0.8.6/BlockhashStore/BlockhashStore.abi ../../contracts/solc/v0.8.6/BlockhashStore/BlockhashStore.bin 12b0662f1636a341c8863bdec7a20f2ddd97c3a4fd1a7ae353fe316609face4e +chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin 41331cdf20464ea860ab57324642ff4797feb20e376908921726ce7e5cb2cf34 chain_reader_example: ../../contracts/solc/v0.8.19/ChainReaderTestContract/LatestValueHolder.abi ../../contracts/solc/v0.8.19/ChainReaderTestContract/LatestValueHolder.bin de88c7e68de36b96aa2bec844bdc96fcd7c9017b38e25062b3b9f9cec42c814f chain_specific_util_helper: ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.abi ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.bin 5f10664e31abc768f4a37901cae7a3bef90146180f97303e5a1bde5a08d84595 consumer_wrapper: ../../contracts/solc/v0.7/Consumer/Consumer.abi ../../contracts/solc/v0.7/Consumer/Consumer.bin 894d1cbd920dccbd36d92918c1037c6ded34f66f417ccb18ec3f33c64ef83ec5 @@ -27,6 +29,7 @@ flux_aggregator_wrapper: ../../contracts/solc/v0.6/FluxAggregator/FluxAggregator gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723 gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8 i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 0886dd1df1f4dcf5b08012f8adcf30fd96caab28999610e70ce02beb2170c92f +i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 383611981c86c70522f41b8750719faacc7d7933a22849d5004799ebef3371fa i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin 6501bb9bcf5048bab2737b00685c6984a24867e234ddf5b60a65904eee9a4ebc i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin 296beccb6af655d6fc3a6e676b244831cce2da6688d3afc4f21f8738ae59e03e keeper_consumer_performance_wrapper: ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.abi ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.bin eeda39f5d3e1c8ffa0fb6cd1803731b98a4bc262d41833458e3fe8b40933ae90 @@ -55,8 +58,10 @@ multiwordconsumer_wrapper: ../../contracts/solc/v0.7/MultiWordConsumer/MultiWord offchain_aggregator_wrapper: OffchainAggregator/OffchainAggregator.abi - 5c8d6562e94166d4790f1ee6e4321d359d9f7262e6c5452a712b1f1c896f45cf operator_factory: ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.abi ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.bin 357203fabe3df436eb015e2d5094374c6967a9fc922ac8edc265b27aac4d67cf operator_wrapper: ../../contracts/solc/v0.8.19/Operator/Operator.abi ../../contracts/solc/v0.8.19/Operator/Operator.bin c5e1db81070d940a82ef100b0bce38e055593cbeebbc73abf9d45c30d6020cd2 +optimism_module: ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.bin 7df8460e07edd0cc849f7e7b111a4135d9e4740ad8fb25003d6a21dc2b6ffe25 oracle_wrapper: ../../contracts/solc/v0.6/Oracle/Oracle.abi ../../contracts/solc/v0.6/Oracle/Oracle.bin 7af2fbac22a6e8c2847e8e685a5400cac5101d72ddf5365213beb79e4dede43a perform_data_checker_wrapper: ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.abi ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.bin 48d8309c2117c29a24e1155917ab0b780956b2cd6a8a39ef06ae66a7f6d94f73 +scroll_module: ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin c7283da6f6bd4874f8c5b2d6fb93fd1d9dfbab30d0f39adf5c9d448d88acdb88 simple_log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.abi ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.bin a2532ca73e227f846be39b52fa63cfa9d088116c3cfc311d972fe8db886fa915 solidity_vrf_consumer_interface: ../../contracts/solc/v0.6/VRFConsumer/VRFConsumer.abi ../../contracts/solc/v0.6/VRFConsumer/VRFConsumer.bin ecc99378aa798014de9db42b2eb81320778b0663dbe208008dad75ccdc1d4366 solidity_vrf_consumer_interface_v08: ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.abi ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.bin b14f9136b15e3dc9d6154d5700f3ed4cf88ddc4f70f20c3bb57fc46050904c8f diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index 00da87af56b..c582583b783 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -62,6 +62,11 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin AutomationRegistryLogicB automation_registry_logic_b_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin IAutomationRegistryMaster i_automation_registry_master_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin AutomationUtils automation_utils_2_2 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin ArbitrumModule arbitrum_module +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin ChainModuleBase chain_module_base +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.bin OptimismModule optimism_module +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin ScrollModule scroll_module +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin IChainModule i_chain_module //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin ILogAutomation i_log_automation //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin AutomationForwarderLogic automation_forwarder_logic //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.bin LogUpkeepCounter log_upkeep_counter_wrapper diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 38df2e00b5c..9b564409c2a 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -20,17 +20,15 @@ import ( ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/store/models" - "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/store/models" ) func BuildAutoOCR2ConfigVars( @@ -39,8 +37,10 @@ func BuildAutoOCR2ConfigVars( registryConfig contracts.KeeperRegistrySettings, registrar string, deltaStage time.Duration, + chainModuleAddress common.Address, + reorgProtectionEnabled bool, ) (contracts.OCRv2Config, error) { - return BuildAutoOCR2ConfigVarsWithKeyIndex(t, chainlinkNodes, registryConfig, registrar, deltaStage, 0, common.Address{}) + return BuildAutoOCR2ConfigVarsWithKeyIndex(t, chainlinkNodes, registryConfig, registrar, deltaStage, 0, common.Address{}, chainModuleAddress, reorgProtectionEnabled) } func BuildAutoOCR2ConfigVarsWithKeyIndex( @@ -51,6 +51,8 @@ func BuildAutoOCR2ConfigVarsWithKeyIndex( deltaStage time.Duration, keyIndex int, registryOwnerAddress common.Address, + chainModuleAddress common.Address, + reorgProtectionEnabled bool, ) (contracts.OCRv2Config, error) { l := logging.GetTestLogger(t) S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndex(chainlinkNodes, keyIndex) @@ -65,7 +67,7 @@ func BuildAutoOCR2ConfigVarsWithKeyIndex( var offchainConfigVersion uint64 var offchainConfig []byte - if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 { + if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 || registryConfig.RegistryVersion == ethereum.RegistryVersion_2_2 { offC, err = json.Marshal(ocr2keepers30config.OffchainConfig{ TargetProbability: "0.999", TargetInRounds: 1, @@ -151,7 +153,7 @@ func BuildAutoOCR2ConfigVarsWithKeyIndex( transmitters = append(transmitters, common.HexToAddress(string(transmitter))) } - onchainConfig, err := registryConfig.EncodeOnChainConfig(registrar, registryOwnerAddress) + onchainConfig, err := registryConfig.EncodeOnChainConfig(registrar, registryOwnerAddress, chainModuleAddress, reorgProtectionEnabled) if err != nil { return contracts.OCRv2Config{}, err } @@ -183,12 +185,13 @@ func CreateOCRKeeperJobs( bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID var contractVersion string - if registryVersion == ethereum.RegistryVersion_2_1 { + // TODO: use v2.1 for registry 2.2 for now until AUTO-9033 is done + if registryVersion == ethereum.RegistryVersion_2_1 || registryVersion == ethereum.RegistryVersion_2_2 { contractVersion = "v2.1" } else if registryVersion == ethereum.RegistryVersion_2_0 { contractVersion = "v2.0" } else { - require.FailNow(t, "v2.0 and v2.1 are the only supported versions") + require.FailNow(t, "v2.0, v2.1, and v2.2 are the only supported versions") } bootstrapSpec := &client.OCR2TaskJobSpec{ diff --git a/integration-tests/actions/automation_ocr_helpers_local.go b/integration-tests/actions/automation_ocr_helpers_local.go index e591e75a983..6c72956045a 100644 --- a/integration-tests/actions/automation_ocr_helpers_local.go +++ b/integration-tests/actions/automation_ocr_helpers_local.go @@ -18,13 +18,12 @@ import ( ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/store/models" - "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/store/models" ) func BuildAutoOCR2ConfigVarsLocal( @@ -34,8 +33,10 @@ func BuildAutoOCR2ConfigVarsLocal( registrar string, deltaStage time.Duration, registryOwnerAddress common.Address, + chainModuleAddress common.Address, + reorgProtectionEnabled bool, ) (contracts.OCRv2Config, error) { - return BuildAutoOCR2ConfigVarsWithKeyIndexLocal(l, chainlinkNodes, registryConfig, registrar, deltaStage, 0, registryOwnerAddress) + return BuildAutoOCR2ConfigVarsWithKeyIndexLocal(l, chainlinkNodes, registryConfig, registrar, deltaStage, 0, registryOwnerAddress, chainModuleAddress, reorgProtectionEnabled) } func BuildAutoOCR2ConfigVarsWithKeyIndexLocal( @@ -46,6 +47,8 @@ func BuildAutoOCR2ConfigVarsWithKeyIndexLocal( deltaStage time.Duration, keyIndex int, registryOwnerAddress common.Address, + chainModuleAddress common.Address, + reorgProtectionEnabled bool, ) (contracts.OCRv2Config, error) { S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndexLocal(chainlinkNodes, keyIndex) if err != nil { @@ -59,7 +62,7 @@ func BuildAutoOCR2ConfigVarsWithKeyIndexLocal( var offchainConfigVersion uint64 var offchainConfig []byte - if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 { + if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 || registryConfig.RegistryVersion == ethereum.RegistryVersion_2_2 { offC, err = json.Marshal(ocr2keepers30config.OffchainConfig{ TargetProbability: "0.999", TargetInRounds: 1, @@ -149,7 +152,7 @@ func BuildAutoOCR2ConfigVarsWithKeyIndexLocal( transmitters = append(transmitters, common.HexToAddress(string(transmitter))) } - onchainConfig, err := registryConfig.EncodeOnChainConfig(registrar, registryOwnerAddress) + onchainConfig, err := registryConfig.EncodeOnChainConfig(registrar, registryOwnerAddress, chainModuleAddress, reorgProtectionEnabled) if err != nil { return contracts.OCRv2Config{}, err } @@ -183,12 +186,13 @@ func CreateOCRKeeperJobsLocal( bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID var contractVersion string - if registryVersion == ethereum.RegistryVersion_2_1 { + // TODO: use v2.1 for registry 2.2 for now until AUTO-9033 is done + if registryVersion == ethereum.RegistryVersion_2_1 || registryVersion == ethereum.RegistryVersion_2_2 { contractVersion = "v2.1" } else if registryVersion == ethereum.RegistryVersion_2_0 { contractVersion = "v2.0" } else { - return fmt.Errorf("v2.0 and v2.1 are the only supported versions") + return fmt.Errorf("v2.0, v2.1, and v2.2 are the only supported versions") } bootstrapSpec := &client.OCR2TaskJobSpec{ diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index bccd3ef1675..5c181cc449b 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -11,8 +11,6 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" @@ -24,16 +22,19 @@ import ( "golang.org/x/sync/errgroup" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1" + ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper2_0" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" @@ -371,12 +372,13 @@ func (a *AutomationTest) AddBootstrapJob() error { func (a *AutomationTest) AddAutomationJobs() error { var contractVersion string - if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_1 { + // TODO: use v2.1 for registry 2.2 for now until AUTO-9033 is done + if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_1 || a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_2 { contractVersion = "v2.1" } else if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_0 { contractVersion = "v2.0" } else { - return fmt.Errorf("v2.0 and v2.1 are the only supported versions") + return fmt.Errorf("v2.0, v2.1, and v2.2 are the only supported versions") } for i := 1; i < len(a.ChainlinkNodes); i++ { autoOCR2JobSpec := client.OCR2TaskJobSpec{ @@ -411,7 +413,6 @@ func (a *AutomationTest) SetConfigOnRegistry() error { donNodes := a.NodeDetails[1:] S := make([]int, len(donNodes)) oracleIdentities := make([]confighelper.OracleIdentityExtra, len(donNodes)) - var offC []byte var signerOnchainPublicKeys []types.OnchainPublicKey var transmitterAccounts []types.Account var f uint8 @@ -470,63 +471,17 @@ func (a *AutomationTest) SetConfigOnRegistry() error { switch a.RegistrySettings.RegistryVersion { case ethereum.RegistryVersion_2_0: - offC, err = json.Marshal(ocr2keepers20config.OffchainConfig{ - TargetProbability: a.PluginConfig.TargetProbability, - TargetInRounds: a.PluginConfig.TargetInRounds, - PerformLockoutWindow: a.PluginConfig.PerformLockoutWindow, - GasLimitPerReport: a.PluginConfig.GasLimitPerReport, - GasOverheadPerUpkeep: a.PluginConfig.GasOverheadPerUpkeep, - MinConfirmations: a.PluginConfig.MinConfirmations, - MaxUpkeepBatchSize: a.PluginConfig.MaxUpkeepBatchSize, - }) - if err != nil { - return errors.Join(err, fmt.Errorf("failed to marshal plugin config")) - } - - signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr2.ContractSetConfigArgsForTests( - a.PublicConfig.DeltaProgress, a.PublicConfig.DeltaResend, - a.PublicConfig.DeltaRound, a.PublicConfig.DeltaGrace, - a.PublicConfig.DeltaStage, uint8(a.PublicConfig.RMax), - S, oracleIdentities, offC, - a.PublicConfig.MaxDurationQuery, a.PublicConfig.MaxDurationObservation, - 1200*time.Millisecond, - a.PublicConfig.MaxDurationShouldAcceptAttestedReport, - a.PublicConfig.MaxDurationShouldTransmitAcceptedReport, - a.PublicConfig.F, a.PublicConfig.OnchainConfig, - ) + signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = calculateOCR2ConfigArgs(a, S, oracleIdentities) if err != nil { return errors.Join(err, fmt.Errorf("failed to build config args")) } - - case ethereum.RegistryVersion_2_1: - offC, err = json.Marshal(ocr2keepers30config.OffchainConfig{ - TargetProbability: a.PluginConfig.TargetProbability, - TargetInRounds: a.PluginConfig.TargetInRounds, - PerformLockoutWindow: a.PluginConfig.PerformLockoutWindow, - GasLimitPerReport: a.PluginConfig.GasLimitPerReport, - GasOverheadPerUpkeep: a.PluginConfig.GasOverheadPerUpkeep, - MinConfirmations: a.PluginConfig.MinConfirmations, - MaxUpkeepBatchSize: a.PluginConfig.MaxUpkeepBatchSize, - }) - if err != nil { - return errors.Join(err, fmt.Errorf("failed to marshal plugin config")) - } - - signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr3.ContractSetConfigArgsForTests( - a.PublicConfig.DeltaProgress, a.PublicConfig.DeltaResend, a.PublicConfig.DeltaInitial, - a.PublicConfig.DeltaRound, a.PublicConfig.DeltaGrace, a.PublicConfig.DeltaCertifiedCommitRequest, - a.PublicConfig.DeltaStage, a.PublicConfig.RMax, - S, oracleIdentities, offC, - a.PublicConfig.MaxDurationQuery, a.PublicConfig.MaxDurationObservation, - a.PublicConfig.MaxDurationShouldAcceptAttestedReport, - a.PublicConfig.MaxDurationShouldTransmitAcceptedReport, - a.PublicConfig.F, a.PublicConfig.OnchainConfig, - ) + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: + signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = calculateOCR3ConfigArgs(a, S, oracleIdentities) if err != nil { return errors.Join(err, fmt.Errorf("failed to build config args")) } default: - return fmt.Errorf("v2.0 and v2.1 are the only supported versions") + return fmt.Errorf("v2.0, v2.1, and v2.2 are the only supported versions") } var signers []common.Address @@ -545,7 +500,7 @@ func (a *AutomationTest) SetConfigOnRegistry() error { transmitters = append(transmitters, common.HexToAddress(string(transmitter))) } - onchainConfig, err := a.RegistrySettings.EncodeOnChainConfig(a.Registrar.Address(), a.UpkeepPrivilegeManager) + onchainConfig, err := a.RegistrySettings.EncodeOnChainConfig(a.Registrar.Address(), a.UpkeepPrivilegeManager, a.Registry.ChainModuleAddress(), a.Registry.ReorgProtectionEnabled()) if err != nil { return errors.Join(err, fmt.Errorf("failed to encode onchain config")) } @@ -566,6 +521,69 @@ func (a *AutomationTest) SetConfigOnRegistry() error { return nil } +func calculateOCR2ConfigArgs(a *AutomationTest, S []int, oracleIdentities []confighelper.OracleIdentityExtra) ( + signers []types.OnchainPublicKey, + transmitters []types.Account, + f_ uint8, + onchainConfig_ []byte, + offchainConfigVersion uint64, + offchainConfig []byte, + err error, +) { + offC, _ := json.Marshal(ocr2keepers20config.OffchainConfig{ + TargetProbability: a.PluginConfig.TargetProbability, + TargetInRounds: a.PluginConfig.TargetInRounds, + PerformLockoutWindow: a.PluginConfig.PerformLockoutWindow, + GasLimitPerReport: a.PluginConfig.GasLimitPerReport, + GasOverheadPerUpkeep: a.PluginConfig.GasOverheadPerUpkeep, + MinConfirmations: a.PluginConfig.MinConfirmations, + MaxUpkeepBatchSize: a.PluginConfig.MaxUpkeepBatchSize, + }) + + return ocr2.ContractSetConfigArgsForTests( + a.PublicConfig.DeltaProgress, a.PublicConfig.DeltaResend, + a.PublicConfig.DeltaRound, a.PublicConfig.DeltaGrace, + a.PublicConfig.DeltaStage, uint8(a.PublicConfig.RMax), + S, oracleIdentities, offC, + a.PublicConfig.MaxDurationQuery, a.PublicConfig.MaxDurationObservation, + 1200*time.Millisecond, + a.PublicConfig.MaxDurationShouldAcceptAttestedReport, + a.PublicConfig.MaxDurationShouldTransmitAcceptedReport, + a.PublicConfig.F, a.PublicConfig.OnchainConfig, + ) +} + +func calculateOCR3ConfigArgs(a *AutomationTest, S []int, oracleIdentities []confighelper.OracleIdentityExtra) ( + signers []types.OnchainPublicKey, + transmitters []types.Account, + f_ uint8, + onchainConfig_ []byte, + offchainConfigVersion uint64, + offchainConfig []byte, + err error, +) { + offC, _ := json.Marshal(ocr2keepers30config.OffchainConfig{ + TargetProbability: a.PluginConfig.TargetProbability, + TargetInRounds: a.PluginConfig.TargetInRounds, + PerformLockoutWindow: a.PluginConfig.PerformLockoutWindow, + GasLimitPerReport: a.PluginConfig.GasLimitPerReport, + GasOverheadPerUpkeep: a.PluginConfig.GasOverheadPerUpkeep, + MinConfirmations: a.PluginConfig.MinConfirmations, + MaxUpkeepBatchSize: a.PluginConfig.MaxUpkeepBatchSize, + }) + + return ocr3.ContractSetConfigArgsForTests( + a.PublicConfig.DeltaProgress, a.PublicConfig.DeltaResend, a.PublicConfig.DeltaInitial, + a.PublicConfig.DeltaRound, a.PublicConfig.DeltaGrace, a.PublicConfig.DeltaCertifiedCommitRequest, + a.PublicConfig.DeltaStage, a.PublicConfig.RMax, + S, oracleIdentities, offC, + a.PublicConfig.MaxDurationQuery, a.PublicConfig.MaxDurationObservation, + a.PublicConfig.MaxDurationShouldAcceptAttestedReport, + a.PublicConfig.MaxDurationShouldTransmitAcceptedReport, + a.PublicConfig.F, a.PublicConfig.OnchainConfig, + ) +} + func (a *AutomationTest) RegisterUpkeeps(upkeepConfigs []UpkeepConfig) ([]common.Hash, error) { var registrarABI *abi.ABI var err error @@ -588,7 +606,7 @@ func (a *AutomationTest) RegisterUpkeeps(upkeepConfigs []UpkeepConfig) ([]common if err != nil { return nil, errors.Join(err, fmt.Errorf("failed to pack registrar request")) } - case ethereum.RegistryVersion_2_1: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: // 2.1 and 2.2 use the same registrar registrarABI, err = automation_registrar_wrapper2_1.AutomationRegistrarMetaData.GetAbi() if err != nil { return nil, errors.Join(err, fmt.Errorf("failed to get registrar abi")) @@ -603,7 +621,7 @@ func (a *AutomationTest) RegisterUpkeeps(upkeepConfigs []UpkeepConfig) ([]common return nil, errors.Join(err, fmt.Errorf("failed to pack registrar request")) } default: - return nil, fmt.Errorf("v2.0 and v2.1 are the only supported versions") + return nil, fmt.Errorf("v2.0, v2.1, and v2.2 are the only supported versions") } tx, err := a.LinkToken.TransferAndCall(a.Registrar.Address(), upkeepConfig.FundingAmount, registrationRequest) if err != nil { diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index 12a7e4c75aa..5ca52d26a9e 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -205,15 +205,21 @@ func addRegistry(config *tc.TestConfig) []eth_contracts.KeeperRegistryVersion { return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0} case "2_1": return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_1} + case "2_2": + return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_2} case "2_0-1_3": return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0, eth_contracts.RegistryVersion_1_3} case "2_1-2_0-1_3": return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_1, eth_contracts.RegistryVersion_2_0, eth_contracts.RegistryVersion_1_3} + case "2_2-2_1": + return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_2, eth_contracts.RegistryVersion_2_1} case "2_0-Multiple": return repeatRegistries(eth_contracts.RegistryVersion_2_0, *config.Keeper.Common.NumberOfRegistries) case "2_1-Multiple": return repeatRegistries(eth_contracts.RegistryVersion_2_1, *config.Keeper.Common.NumberOfRegistries) + case "2_2-Multiple": + return repeatRegistries(eth_contracts.RegistryVersion_2_2, *config.Keeper.Common.NumberOfRegistries) default: return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0} } diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index 711a3557307..1d1fda451b3 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -126,6 +126,7 @@ func TestAutomationChaos(t *testing.T) { registryVersions := map[string]eth_contracts.KeeperRegistryVersion{ "registry_2_0": eth_contracts.RegistryVersion_2_0, "registry_2_1": eth_contracts.RegistryVersion_2_1, + "registry_2_2": eth_contracts.RegistryVersion_2_2, } for name, registryVersion := range registryVersions { @@ -276,7 +277,7 @@ func TestAutomationChaos(t *testing.T) { actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion) nodesWithoutBootstrap := chainlinkNodes[1:] - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled()) require.NoError(t, err, "Error building OCR config vars") err = registry.SetConfig(defaultOCRRegistryConfig, ocrConfig) require.NoError(t, err, "Registry config should be be set successfully") diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index 47c654b5d46..f53a709779d 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -9,7 +9,6 @@ import ( "time" "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -21,19 +20,26 @@ import ( ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_mock_ethlink_aggregator" + eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_v1_events_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/arbitrum_module" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_consumer_benchmark" automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic" registrar21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1" + registrylogica22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2" + registrylogicb22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_2" + registry22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_wrapper_2_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/chain_module_base" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flags_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_billing_registry_events_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_oracle_events_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper_mock" + iregistry22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_chain_module" iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_consumer_performance_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_consumer_wrapper" @@ -58,21 +64,22 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_ethlink_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_gas_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_factory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/optimism_module" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/oracle_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/perform_data_checker_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/scroll_module" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/simple_log_upkeep_counter_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/streams_lookup_upkeep_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/test_api_consumer_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_counter_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_perform_counter_restrictive_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_transcoder" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_mock_ethlink_aggregator" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/fee_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/reward_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/werc20_mock" - - eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" ) // ContractDeployer is an interface for abstracting the contract deployment methods across network implementations @@ -840,7 +847,7 @@ func (e *EthereumContractDeployer) DeployKeeperRegistrar(registryVersion eth_con registrar20: instance.(*keeper_registrar_wrapper2_0.KeeperRegistrar), address: address, }, err - } else if registryVersion == eth_contracts.RegistryVersion_2_1 { + } else if registryVersion == eth_contracts.RegistryVersion_2_1 || registryVersion == eth_contracts.RegistryVersion_2_2 { // both 2.1 and 2.2 registry use registrar 2.1 // deploy registrar 2.1 address, _, instance, err := e.client.DeployContract("AutomationRegistrar", func( opts *bind.TransactOpts, @@ -1139,21 +1146,11 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry( }, err case eth_contracts.RegistryVersion_2_1: - automationForwarderLogicAddr, _, _, err := e.client.DeployContract("automationForwarderLogic", func( - auth *bind.TransactOpts, - backend bind.ContractBackend, - ) (common.Address, *types.Transaction, interface{}, error) { - return automationForwarderLogic.DeployAutomationForwarderLogic(auth, backend) - }) - + automationForwarderLogicAddr, err := deployAutomationForwarderLogic(e.client) if err != nil { return nil, err } - if err := e.client.WaitForEvents(); err != nil { - return nil, err - } - registryLogicBAddr, _, _, err := e.client.DeployContract("KeeperRegistryLogicB2_1", func( auth *bind.TransactOpts, backend bind.ContractBackend, @@ -1225,11 +1222,162 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry( registry2_1: registryMaster, address: address, }, err + case eth_contracts.RegistryVersion_2_2: + var chainModuleAddr *common.Address + var err error + chainId := e.client.GetChainID().Int64() + + if chainId == 534352 || chainId == 534351 { // Scroll / Scroll Sepolia + chainModuleAddr, _, _, err = e.client.DeployContract("ScrollModule", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return scroll_module.DeployScrollModule(auth, backend) + }) + } else if chainId == 42161 || chainId == 421614 || chainId == 421613 { // Arbitrum One / Sepolia / Goerli + chainModuleAddr, _, _, err = e.client.DeployContract("ArbitrumModule", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return arbitrum_module.DeployArbitrumModule(auth, backend) + }) + } else if chainId == 10 || chainId == 11155420 { // Optimism / Optimism Sepolia + chainModuleAddr, _, _, err = e.client.DeployContract("OptimismModule", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return optimism_module.DeployOptimismModule(auth, backend) + }) + } else { + chainModuleAddr, _, _, err = e.client.DeployContract("ChainModuleBase", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return chain_module_base.DeployChainModuleBase(auth, backend) + }) + } + if err != nil { + return nil, err + } + if err = e.client.WaitForEvents(); err != nil { + return nil, err + } + + automationForwarderLogicAddr, err := deployAutomationForwarderLogic(e.client) + if err != nil { + return nil, err + } + + var allowedReadOnlyAddress common.Address + if chainId == 1101 || chainId == 1442 || chainId == 2442 { + allowedReadOnlyAddress = common.HexToAddress("0x1111111111111111111111111111111111111111") + } else { + allowedReadOnlyAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") + } + registryLogicBAddr, _, _, err := e.client.DeployContract("AutomationRegistryLogicB2_2", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + + return registrylogicb22.DeployAutomationRegistryLogicB( + auth, + backend, + common.HexToAddress(opts.LinkAddr), + common.HexToAddress(opts.ETHFeedAddr), + common.HexToAddress(opts.GasFeedAddr), + *automationForwarderLogicAddr, + allowedReadOnlyAddress, + ) + }) + if err != nil { + return nil, err + } + + if err := e.client.WaitForEvents(); err != nil { + return nil, err + } + + registryLogicAAddr, _, _, err := e.client.DeployContract("AutomationRegistryLogicA2_2", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + + return registrylogica22.DeployAutomationRegistryLogicA( + auth, + backend, + *registryLogicBAddr, + ) + }) + if err != nil { + return nil, err + } + if err := e.client.WaitForEvents(); err != nil { + return nil, err + } + + address, _, _, err := e.client.DeployContract("AutomationRegistry2_2", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return registry22.DeployAutomationRegistry( + auth, + backend, + *registryLogicAAddr, + ) + }) + if err != nil { + return nil, err + } + if err := e.client.WaitForEvents(); err != nil { + return nil, err + } + + registryMaster, err := iregistry22.NewIAutomationRegistryMaster( + *address, + e.client.Backend(), + ) + if err != nil { + return nil, err + } + + chainModule, err := i_chain_module.NewIChainModule( + *chainModuleAddr, + e.client.Backend(), + ) + if err != nil { + return nil, err + } + + return &EthereumKeeperRegistry{ + client: e.client, + version: eth_contracts.RegistryVersion_2_2, + registry2_2: registryMaster, + chainModule: chainModule, + address: address, + }, err default: return nil, fmt.Errorf("keeper registry version %d is not supported", opts.RegistryVersion) } } +func deployAutomationForwarderLogic(client blockchain.EVMClient) (*common.Address, error) { + automationForwarderLogicAddr, _, _, err := client.DeployContract("automationForwarderLogic", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return automationForwarderLogic.DeployAutomationForwarderLogic(auth, backend) + }) + + if err != nil { + return nil, err + } + + if err := client.WaitForEvents(); err != nil { + return nil, err + } + return automationForwarderLogicAddr, nil +} + // LoadKeeperRegistry returns deployed on given address EthereumKeeperRegistry func (e *EthereumContractDeployer) LoadKeeperRegistry(address common.Address, registryVersion eth_contracts.KeeperRegistryVersion) (KeeperRegistry, error) { switch registryVersion { @@ -1313,6 +1461,22 @@ func (e *EthereumContractDeployer) LoadKeeperRegistry(address common.Address, re registry2_1: instance.(*iregistry21.IKeeperRegistryMaster), version: registryVersion, }, err + case eth_contracts.RegistryVersion_2_2: // why the contract name is not the same as the actual contract name? + instance, err := e.client.LoadContract("AutomationRegistry", address, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return iregistry22.NewIAutomationRegistryMaster(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumKeeperRegistry{ + address: &address, + client: e.client, + registry2_2: instance.(*iregistry22.IAutomationRegistryMaster), + version: registryVersion, + }, err default: return nil, fmt.Errorf("keeper registry version %d is not supported", registryVersion) } diff --git a/integration-tests/contracts/ethereum/KeeperRegistryVersions.go b/integration-tests/contracts/ethereum/KeeperRegistryVersions.go index f15e43524d0..4aee8d75d21 100644 --- a/integration-tests/contracts/ethereum/KeeperRegistryVersions.go +++ b/integration-tests/contracts/ethereum/KeeperRegistryVersions.go @@ -18,4 +18,5 @@ const ( RegistryVersion_1_3 RegistryVersion_2_0 RegistryVersion_2_1 + RegistryVersion_2_2 ) diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go index a15fcfc7aea..3622edcef5f 100644 --- a/integration-tests/contracts/ethereum_keeper_contracts.go +++ b/integration-tests/contracts/ethereum_keeper_contracts.go @@ -19,12 +19,20 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/integration-tests/testreporters" cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_consumer_benchmark" registrar21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_wrapper_2_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_chain_module" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_consumer_performance_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_consumer_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper1_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1" @@ -37,17 +45,13 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/perform_data_checker_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/simple_log_upkeep_counter_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/streams_lookup_upkeep_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_counter_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_perform_counter_restrictive_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_transcoder" - - "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - "github.com/smartcontractkit/chainlink/integration-tests/testreporters" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_consumer_performance_wrapper" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_consumer_wrapper" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_counter_wrapper" ) -var utilsABI = cltypes.MustGetABI(automation_utils_2_1.AutomationUtilsABI) +var utilsABI21 = cltypes.MustGetABI(automation_utils_2_1.AutomationUtilsABI) +var utilsABI22 = cltypes.MustGetABI(automation_utils_2_2.AutomationUtilsABI) var registrarABI = cltypes.MustGetABI(registrar21.AutomationRegistrarABI) type KeeperRegistrar interface { @@ -87,6 +91,8 @@ type KeeperRegistry interface { SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) error SetUpkeepPrivilegeConfig(id *big.Int, privilegeConfig []byte) error RegistryOwnerAddress() common.Address + ChainModuleAddress() common.Address + ReorgProtectionEnabled() bool } type KeeperConsumer interface { @@ -212,10 +218,25 @@ type EthereumKeeperRegistry struct { registry1_3 *keeper_registry_wrapper1_3.KeeperRegistry registry2_0 *keeper_registry_wrapper2_0.KeeperRegistry registry2_1 *i_keeper_registry_master_wrapper_2_1.IKeeperRegistryMaster + registry2_2 *i_automation_registry_master_wrapper_2_2.IAutomationRegistryMaster + chainModule *i_chain_module.IChainModule address *common.Address l zerolog.Logger } +func (v *EthereumKeeperRegistry) ReorgProtectionEnabled() bool { + chainId := v.client.GetChainID().Uint64() + // reorg protection is disabled in polygon zkEVM and Scroll bc currently there is no way to get the block hash onchain + return v.version != ethereum.RegistryVersion_2_2 || (chainId != 1101 && chainId != 1442 && chainId != 2442 && chainId != 534352 && chainId != 534351) +} + +func (v *EthereumKeeperRegistry) ChainModuleAddress() common.Address { + if v.version == ethereum.RegistryVersion_2_2 { + return v.chainModule.Address() + } + return common.Address{} +} + func (v *EthereumKeeperRegistry) Address() string { return v.address.Hex() } @@ -228,7 +249,7 @@ func (v *EthereumKeeperRegistry) Fund(ethAmount *big.Float) error { return v.client.Fund(v.address.Hex(), ethAmount, gasEstimates) } -func (rcs *KeeperRegistrySettings) EncodeOnChainConfig(registrar string, registryOwnerAddress common.Address) ([]byte, error) { +func (rcs *KeeperRegistrySettings) EncodeOnChainConfig(registrar string, registryOwnerAddress, chainModuleAddress common.Address, reorgProtectionEnabled bool) ([]byte, error) { if rcs.RegistryVersion == ethereum.RegistryVersion_2_1 { onchainConfigStruct := registry21.KeeperRegistryBase21OnchainConfig{ PaymentPremiumPPB: rcs.PaymentPremiumPPB, @@ -248,9 +269,11 @@ func (rcs *KeeperRegistrySettings) EncodeOnChainConfig(registrar string, registr UpkeepPrivilegeManager: registryOwnerAddress, } - encodedOnchainConfig, err := utilsABI.Methods["_onChainConfig"].Inputs.Pack(&onchainConfigStruct) + encodedOnchainConfig, err := utilsABI21.Methods["_onChainConfig"].Inputs.Pack(&onchainConfigStruct) return encodedOnchainConfig, err + } else if rcs.RegistryVersion == ethereum.RegistryVersion_2_2 { + return rcs.encode22OnchainConfig(registrar, registryOwnerAddress, chainModuleAddress, reorgProtectionEnabled) } configType := goabi.MustNewType("tuple(uint32 paymentPremiumPPB,uint32 flatFeeMicroLink,uint32 checkGasLimit,uint24 stalenessSeconds,uint16 gasCeilingMultiplier,uint96 minUpkeepSpend,uint32 maxPerformGas,uint32 maxCheckDataSize,uint32 maxPerformDataSize,uint256 fallbackGasPrice,uint256 fallbackLinkPrice,address transcoder,address registrar)") onchainConfig, err := goabi.Encode(map[string]interface{}{ @@ -272,6 +295,32 @@ func (rcs *KeeperRegistrySettings) EncodeOnChainConfig(registrar string, registr } +func (rcs *KeeperRegistrySettings) encode22OnchainConfig(registrar string, registryOwnerAddress, chainModuleAddr common.Address, reorgProtectionEnabled bool) ([]byte, error) { + onchainConfigStruct := automation_registry_wrapper_2_2.AutomationRegistryBase22OnchainConfig{ + PaymentPremiumPPB: rcs.PaymentPremiumPPB, + FlatFeeMicroLink: rcs.FlatFeeMicroLINK, + CheckGasLimit: rcs.CheckGasLimit, + StalenessSeconds: rcs.StalenessSeconds, + GasCeilingMultiplier: rcs.GasCeilingMultiplier, + MinUpkeepSpend: rcs.MinUpkeepSpend, + MaxPerformGas: rcs.MaxPerformGas, + MaxCheckDataSize: rcs.MaxCheckDataSize, + MaxPerformDataSize: rcs.MaxPerformDataSize, + MaxRevertDataSize: uint32(1000), + FallbackGasPrice: rcs.FallbackGasPrice, + FallbackLinkPrice: rcs.FallbackLinkPrice, + Transcoder: common.Address{}, + Registrars: []common.Address{common.HexToAddress(registrar)}, + UpkeepPrivilegeManager: registryOwnerAddress, + ChainModule: chainModuleAddr, + ReorgProtectionEnabled: reorgProtectionEnabled, + } + + encodedOnchainConfig, err := utilsABI22.Methods["_onChainConfig"].Inputs.Pack(&onchainConfigStruct) + + return encodedOnchainConfig, err +} + func (v *EthereumKeeperRegistry) RegistryOwnerAddress() common.Address { callOpts := &bind.CallOpts{ Pending: false, @@ -279,6 +328,9 @@ func (v *EthereumKeeperRegistry) RegistryOwnerAddress() common.Address { //nolint: exhaustive switch v.version { + case ethereum.RegistryVersion_2_2: + ownerAddress, _ := v.registry2_2.Owner(callOpts) + return ownerAddress case ethereum.RegistryVersion_2_1: ownerAddress, _ := v.registry2_1.Owner(callOpts) return ownerAddress @@ -394,11 +446,28 @@ func (v *EthereumKeeperRegistry) SetConfig(config KeeperRegistrySettings, ocrCon return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_2: + return v.setConfig22(txOpts, ocrConfig) } return fmt.Errorf("keeper registry version %d is not supported", v.version) } +func (v *EthereumKeeperRegistry) setConfig22(txOpts *bind.TransactOpts, ocrConfig OCRv2Config) error { + tx, err := v.registry2_2.SetConfig(txOpts, + ocrConfig.Signers, + ocrConfig.Transmitters, + ocrConfig.F, + ocrConfig.OnchainConfig, + ocrConfig.OffchainConfigVersion, + ocrConfig.OffchainConfig, + ) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) +} + // Pause pauses the registry. func (v *EthereumKeeperRegistry) Pause() error { txOpts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) @@ -439,6 +508,12 @@ func (v *EthereumKeeperRegistry) Pause() error { return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_2: + tx, err = v.registry2_2.Pause(txOpts) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) } return fmt.Errorf("keeper registry version %d is not supported", v.version) @@ -552,6 +627,8 @@ func (v *EthereumKeeperRegistry) AddUpkeepFunds(id *big.Int, amount *big.Int) er tx, err = v.registry2_0.AddFunds(opts, id, amount) case ethereum.RegistryVersion_2_1: tx, err = v.registry2_1.AddFunds(opts, id, amount) + case ethereum.RegistryVersion_2_2: + tx, err = v.registry2_2.AddFunds(opts, id, amount) } if err != nil { @@ -644,11 +721,32 @@ func (v *EthereumKeeperRegistry) GetUpkeepInfo(ctx context.Context, id *big.Int) Paused: uk.Paused, OffchainConfig: uk.OffchainConfig, }, nil + case ethereum.RegistryVersion_2_2: + return v.getUpkeepInfo22(opts, id) } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) } +func (v *EthereumKeeperRegistry) getUpkeepInfo22(opts *bind.CallOpts, id *big.Int) (*UpkeepInfo, error) { + uk, err := v.registry2_2.GetUpkeep(opts, id) + if err != nil { + return nil, err + } + return &UpkeepInfo{ + Target: uk.Target.Hex(), + ExecuteGas: uk.PerformGas, + CheckData: uk.CheckData, + Balance: uk.Balance, + Admin: uk.Admin.Hex(), + MaxValidBlocknumber: uk.MaxValidBlocknumber, + LastPerformBlockNumber: uk.LastPerformedBlockNumber, + AmountSpent: uk.AmountSpent, + Paused: uk.Paused, + OffchainConfig: uk.OffchainConfig, + }, nil +} + func (v *EthereumKeeperRegistry) GetKeeperInfo(ctx context.Context, keeperAddr string) (*KeeperInfo, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), @@ -668,7 +766,7 @@ func (v *EthereumKeeperRegistry) GetKeeperInfo(ctx context.Context, keeperAddr s info, err = v.registry1_2.GetKeeperInfo(opts, common.HexToAddress(keeperAddr)) case ethereum.RegistryVersion_1_3: info, err = v.registry1_3.GetKeeperInfo(opts, common.HexToAddress(keeperAddr)) - case ethereum.RegistryVersion_2_0, ethereum.RegistryVersion_2_1: + case ethereum.RegistryVersion_2_0, ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: // this is not used anywhere return nil, fmt.Errorf("not supported") } @@ -714,7 +812,7 @@ func (v *EthereumKeeperRegistry) SetKeepers(keepers []string, payees []string, o ocrConfig.OffchainConfigVersion, ocrConfig.OffchainConfig, ) - case ethereum.RegistryVersion_2_1: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: return fmt.Errorf("not supported") } @@ -766,7 +864,7 @@ func (v *EthereumKeeperRegistry) RegisterUpkeep(target string, gasLimit uint32, checkData, nil, //offchain config ) - case ethereum.RegistryVersion_2_1: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: return fmt.Errorf("not supported") } @@ -810,6 +908,11 @@ func (v *EthereumKeeperRegistry) CancelUpkeep(id *big.Int) error { if err != nil { return err } + case ethereum.RegistryVersion_2_2: + tx, err = v.registry2_2.CancelUpkeep(opts, id) + if err != nil { + return err + } } v.l.Info(). @@ -849,6 +952,11 @@ func (v *EthereumKeeperRegistry) SetUpkeepGasLimit(id *big.Int, gas uint32) erro if err != nil { return err } + case ethereum.RegistryVersion_2_2: + tx, err = v.registry2_2.SetUpkeepGasLimit(opts, id, gas) + if err != nil { + return err + } default: return fmt.Errorf("keeper registry version %d is not supported for SetUpkeepGasLimit", v.version) } @@ -885,7 +993,7 @@ func (v *EthereumKeeperRegistry) GetKeeperList(ctx context.Context) ([]string, e return []string{}, err } list = state.Transmitters - case ethereum.RegistryVersion_2_1: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: return nil, fmt.Errorf("not supported") } @@ -936,6 +1044,17 @@ func (v *EthereumKeeperRegistry) UpdateCheckData(id *big.Int, newCheckData []byt return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_2: + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + + tx, err := v.registry2_2.SetUpkeepCheckData(opts, id, newCheckData) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) default: return fmt.Errorf("UpdateCheckData is not supported by keeper registry version %d", v.version) } @@ -956,6 +1075,17 @@ func (v *EthereumKeeperRegistry) SetUpkeepTriggerConfig(id *big.Int, triggerConf return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_2: + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + + tx, err := v.registry2_2.SetUpkeepTriggerConfig(opts, id, triggerConfig) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) default: return fmt.Errorf("SetUpkeepTriggerConfig is not supported by keeper registry version %d", v.version) } @@ -976,6 +1106,17 @@ func (v *EthereumKeeperRegistry) SetUpkeepPrivilegeConfig(id *big.Int, privilege return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_2: + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + + tx, err := v.registry2_2.SetUpkeepPrivilegeConfig(opts, id, privilegeConfig) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) default: return fmt.Errorf("SetUpkeepPrivilegeConfig is not supported by keeper registry version %d", v.version) } @@ -1017,6 +1158,17 @@ func (v *EthereumKeeperRegistry) PauseUpkeep(id *big.Int) error { return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_2: + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + + tx, err := v.registry2_2.PauseUpkeep(opts, id) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) default: return fmt.Errorf("PauseUpkeep is not supported by keeper registry version %d", v.version) } @@ -1058,6 +1210,17 @@ func (v *EthereumKeeperRegistry) UnpauseUpkeep(id *big.Int) error { return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_2: + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + + tx, err := v.registry2_2.UnpauseUpkeep(opts, id) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) default: return fmt.Errorf("UnpauseUpkeep is not supported by keeper registry version %d", v.version) } @@ -1116,6 +1279,16 @@ func (v *EthereumKeeperRegistry) ParseUpkeepPerformedLog(log *types.Log) (*Upkee Success: parsedLog.Success, From: utils.ZeroAddress, }, nil + case ethereum.RegistryVersion_2_2: + parsedLog, err := v.registry2_2.ParseUpkeepPerformed(*log) + if err != nil { + return nil, err + } + return &UpkeepPerformedLog{ + Id: parsedLog.Id, + Success: parsedLog.Success, + From: utils.ZeroAddress, + }, nil } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) } @@ -1140,6 +1313,14 @@ func (v *EthereumKeeperRegistry) ParseStaleUpkeepReportLog(log *types.Log) (*Sta return &StaleUpkeepReportLog{ Id: parsedLog.Id, }, nil + case ethereum.RegistryVersion_2_2: + parsedLog, err := v.registry2_2.ParseStaleUpkeepReport(*log) + if err != nil { + return nil, err + } + return &StaleUpkeepReportLog{ + Id: parsedLog.Id, + }, nil } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) } @@ -1177,6 +1358,12 @@ func (v *EthereumKeeperRegistry) ParseUpkeepIdFromRegisteredLog(log *types.Log) return nil, err } return parsedLog.Id, nil + case ethereum.RegistryVersion_2_2: + parsedLog, err := v.registry2_2.ParseUpkeepRegistered(*log) + if err != nil { + return nil, err + } + return parsedLog.Id, nil } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) @@ -2057,7 +2244,7 @@ func (v *EthereumKeeperRegistrar) EncodeRegisterRequest(name string, email []byt Topic2: bytes0, Topic3: bytes0, } - encodedLogTriggerConfig, err := utilsABI.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) + encodedLogTriggerConfig, err := utilsABI21.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) if err != nil { return nil, err } diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 36b5d3eb985..e889a1c6123 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -25,7 +25,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) @@ -129,14 +128,16 @@ func TestAutomationReorg(t *testing.T) { l := logging.GetTestLogger(t) registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_2_0": ethereum.RegistryVersion_2_0, - // "registry_2_1_conditional": ethereum.RegistryVersion_2_1, - // "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1, + "registry_2_0": ethereum.RegistryVersion_2_0, + "registry_2_1_conditional": ethereum.RegistryVersion_2_1, + "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1, + "registry_2_2_conditional": ethereum.RegistryVersion_2_2, + "registry_2_2_logtrigger": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() config, err := tc.GetConfig("Reorg", tc.Automation) @@ -213,7 +214,7 @@ func TestAutomationReorg(t *testing.T) { actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion) nodesWithoutBootstrap := chainlinkNodes[1:] - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled()) require.NoError(t, err, "OCR2 config should be built successfully") err = registry.SetConfig(defaultOCRRegistryConfig, ocrConfig) require.NoError(t, err, "Registry config should be be set successfully") diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 3f69e7f829c..c51b90c1f57 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -10,37 +10,34 @@ import ( "testing" "time" - ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - - "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" - tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" - "github.com/smartcontractkit/chainlink/integration-tests/types" - "github.com/ethereum/go-ethereum/common" "github.com/onsi/gomega" "github.com/stretchr/testify/require" + ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/integration-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/types" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams" ) -var utilsABI = cltypes.MustGetABI(automation_utils_2_1.AutomationUtilsABI) +var utilsABI21 = cltypes.MustGetABI(automation_utils_2_1.AutomationUtilsABI) const ( automationDefaultUpkeepGasLimit = uint32(2500000) @@ -96,11 +93,16 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool, automationTestConfig t "registry_2_1_with_mercury_v02": ethereum.RegistryVersion_2_1, "registry_2_1_with_mercury_v03": ethereum.RegistryVersion_2_1, "registry_2_1_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_1, + "registry_2_2_conditional": ethereum.RegistryVersion_2_2, + "registry_2_2_logtrigger": ethereum.RegistryVersion_2_2, + "registry_2_2_with_mercury_v02": ethereum.RegistryVersion_2_2, + "registry_2_2_with_mercury_v03": ethereum.RegistryVersion_2_2, + "registry_2_2_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { cfg := tc.MustCopy(automationTestConfig) t.Parallel() @@ -114,9 +116,9 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool, automationTestConfig t } // Use the name to determine if this is a log trigger or mercury - isLogTrigger := name == "registry_2_1_logtrigger" || name == "registry_2_1_with_logtrigger_and_mercury_v02" - isMercuryV02 := name == "registry_2_1_with_mercury_v02" || name == "registry_2_1_with_logtrigger_and_mercury_v02" - isMercuryV03 := name == "registry_2_1_with_mercury_v03" + isLogTrigger := name == "registry_2_1_logtrigger" || name == "registry_2_1_with_logtrigger_and_mercury_v02" || name == "registry_2_2_logtrigger" || name == "registry_2_2_with_logtrigger_and_mercury_v02" + isMercuryV02 := name == "registry_2_1_with_mercury_v02" || name == "registry_2_1_with_logtrigger_and_mercury_v02" || name == "registry_2_2_with_mercury_v02" || name == "registry_2_2_with_logtrigger_and_mercury_v02" + isMercuryV03 := name == "registry_2_1_with_mercury_v03" || name == "registry_2_2_with_mercury_v03" isMercury := isMercuryV02 || isMercuryV03 a := setupAutomationTestDocker( @@ -234,172 +236,184 @@ func TestSetUpkeepTriggerConfig(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) - config, err := tc.GetConfig("Smoke", tc.Automation) - if err != nil { - t.Fatal(err) + registryVersions := map[string]ethereum.KeeperRegistryVersion{ + "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - a := setupAutomationTestDocker( - t, ethereum.RegistryVersion_2_1, automationDefaultRegistryConfig, false, false, &config, - ) - - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.Registry, - a.Registrar, - a.LinkToken, - a.Deployer, - a.ChainClient, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - true, - false, - ) - - // Start log trigger based upkeeps for all consumers - for i := 0; i < len(consumers); i++ { - err := consumers[i].Start() - if err != nil { - return - } - } + for n, rv := range registryVersions { + name := n + registryVersion := rv + t.Run(name, func(t *testing.T) { + t.Parallel() + config, err := tc.GetConfig("Smoke", tc.Automation) + if err != nil { + t.Fatal(err) + } - l.Info().Msg("Waiting for all upkeeps to perform") - gom := gomega.NewGomegaWithT(t) - gom.Eventually(func(g gomega.Gomega) { - // Check if the upkeeps are performing multiple times by analyzing their counters - for i := 0; i < len(upkeepIDs); i++ { - counter, err := consumers[i].Counter(testcontext.Get(t)) - require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) - expect := 5 - l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep Index", i).Msg("Number of upkeeps performed") - g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", int64(expect)), - "Expected consumer counter to be greater than %d, but got %d", expect, counter.Int64()) - } - }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer - - topic0InBytesMatch := [32]byte{ - 61, 83, 163, 149, 80, 224, 70, 136, - 6, 88, 39, 243, 187, 134, 88, 76, - 176, 7, 171, 158, 188, 167, 235, - 213, 40, 231, 48, 28, 156, 49, 235, 93, - } // bytes representation of 0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d - - topic0InBytesNoMatch := [32]byte{ - 62, 83, 163, 149, 80, 224, 70, 136, - 6, 88, 39, 243, 187, 134, 88, 76, - 176, 7, 171, 158, 188, 167, 235, - 213, 40, 231, 48, 28, 156, 49, 235, 93, - } // changed the first byte from 61 to 62 to make it not match - - bytes0 := [32]byte{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - } // bytes representation of 0x0000000000000000000000000000000000000000000000000000000000000000 - - // Update the trigger config so no upkeeps are triggered - for i := 0; i < len(consumers); i++ { - upkeepAddr := consumers[i].Address() - - logTriggerConfigStruct := automation_utils_2_1.LogTriggerConfig{ - ContractAddress: common.HexToAddress(upkeepAddr), - FilterSelector: 0, - Topic0: topic0InBytesNoMatch, - Topic1: bytes0, - Topic2: bytes0, - Topic3: bytes0, - } - encodedLogTriggerConfig, err := utilsABI.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) - if err != nil { - return - } + a := setupAutomationTestDocker( + t, registryVersion, automationDefaultRegistryConfig, false, false, &config, + ) - err = a.Registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig) - require.NoError(t, err, "Could not set upkeep trigger config at index %d", i) - } + consumers, upkeepIDs := actions.DeployConsumers( + t, + a.Registry, + a.Registrar, + a.LinkToken, + a.Deployer, + a.ChainClient, + defaultAmountOfUpkeeps, + big.NewInt(automationDefaultLinkFunds), + automationDefaultUpkeepGasLimit, + true, + false, + ) + + // Start log trigger based upkeeps for all consumers + for i := 0; i < len(consumers); i++ { + err := consumers[i].Start() + if err != nil { + return + } + } + + l.Info().Msg("Waiting for all upkeeps to perform") + gom := gomega.NewGomegaWithT(t) + gom.Eventually(func(g gomega.Gomega) { + // Check if the upkeeps are performing multiple times by analyzing their counters + for i := 0; i < len(upkeepIDs); i++ { + counter, err := consumers[i].Counter(testcontext.Get(t)) + require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) + expect := 5 + l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep Index", i).Msg("Number of upkeeps performed") + g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", int64(expect)), + "Expected consumer counter to be greater than %d, but got %d", expect, counter.Int64()) + } + }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer - err = a.ChainClient.WaitForEvents() - require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps") + topic0InBytesMatch := [32]byte{ + 61, 83, 163, 149, 80, 224, 70, 136, + 6, 88, 39, 243, 187, 134, 88, 76, + 176, 7, 171, 158, 188, 167, 235, + 213, 40, 231, 48, 28, 156, 49, 235, 93, + } // bytes representation of 0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d + + topic0InBytesNoMatch := [32]byte{ + 62, 83, 163, 149, 80, 224, 70, 136, + 6, 88, 39, 243, 187, 134, 88, 76, + 176, 7, 171, 158, 188, 167, 235, + 213, 40, 231, 48, 28, 156, 49, 235, 93, + } // changed the first byte from 61 to 62 to make it not match + + bytes0 := [32]byte{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } // bytes representation of 0x0000000000000000000000000000000000000000000000000000000000000000 + + // Update the trigger config so no upkeeps are triggered + for i := 0; i < len(consumers); i++ { + upkeepAddr := consumers[i].Address() + + logTriggerConfigStruct := automation_utils_2_1.LogTriggerConfig{ + ContractAddress: common.HexToAddress(upkeepAddr), + FilterSelector: 0, + Topic0: topic0InBytesNoMatch, + Topic1: bytes0, + Topic2: bytes0, + Topic3: bytes0, + } + encodedLogTriggerConfig, err := utilsABI21.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) + if err != nil { + return + } - var countersAfterSetNoMatch = make([]*big.Int, len(upkeepIDs)) + err = a.Registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig) + require.NoError(t, err, "Could not set upkeep trigger config at index %d", i) + } - // Wait for 10 seconds to let in-flight upkeeps finish - time.Sleep(10 * time.Second) - for i := 0; i < len(upkeepIDs); i++ { - // Obtain the amount of times the upkeep has been executed so far - countersAfterSetNoMatch[i], err = consumers[i].Counter(testcontext.Get(t)) - require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) - l.Info().Int64("Upkeep Count", countersAfterSetNoMatch[i].Int64()).Int("Upkeep Index", i).Msg("Upkeep") - } + err = a.ChainClient.WaitForEvents() + require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps") - l.Info().Msg("Making sure the counter stays consistent") - gom.Consistently(func(g gomega.Gomega) { - for i := 0; i < len(upkeepIDs); i++ { - // Expect the counter to remain constant (At most increase by 2 to account for stale performs) because the upkeep trigger config is not met - bufferCount := int64(2) - latestCounter, err := consumers[i].Counter(testcontext.Get(t)) - g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) - g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterSetNoMatch[i].Int64()+bufferCount), - "Expected consumer counter to remain less than or equal to %d, but got %d", - countersAfterSetNoMatch[i].Int64()+bufferCount, latestCounter.Int64()) - } - }, "1m", "1s").Should(gomega.Succeed()) - - // Update the trigger config, so upkeeps start performing again - for i := 0; i < len(consumers); i++ { - upkeepAddr := consumers[i].Address() - - logTriggerConfigStruct := automation_utils_2_1.LogTriggerConfig{ - ContractAddress: common.HexToAddress(upkeepAddr), - FilterSelector: 0, - Topic0: topic0InBytesMatch, - Topic1: bytes0, - Topic2: bytes0, - Topic3: bytes0, - } - encodedLogTriggerConfig, err := utilsABI.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) - if err != nil { - return - } + var countersAfterSetNoMatch = make([]*big.Int, len(upkeepIDs)) - err = a.Registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig) - require.NoError(t, err, "Could not set upkeep trigger config at index %d", i) - } + // Wait for 10 seconds to let in-flight upkeeps finish + time.Sleep(10 * time.Second) + for i := 0; i < len(upkeepIDs); i++ { + // Obtain the amount of times the upkeep has been executed so far + countersAfterSetNoMatch[i], err = consumers[i].Counter(testcontext.Get(t)) + require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) + l.Info().Int64("Upkeep Count", countersAfterSetNoMatch[i].Int64()).Int("Upkeep Index", i).Msg("Upkeep") + } + + l.Info().Msg("Making sure the counter stays consistent") + gom.Consistently(func(g gomega.Gomega) { + for i := 0; i < len(upkeepIDs); i++ { + // Expect the counter to remain constant (At most increase by 2 to account for stale performs) because the upkeep trigger config is not met + bufferCount := int64(2) + latestCounter, err := consumers[i].Counter(testcontext.Get(t)) + g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) + g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterSetNoMatch[i].Int64()+bufferCount), + "Expected consumer counter to remain less than or equal to %d, but got %d", + countersAfterSetNoMatch[i].Int64()+bufferCount, latestCounter.Int64()) + } + }, "1m", "1s").Should(gomega.Succeed()) - err = a.ChainClient.WaitForEvents() - require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps") + // Update the trigger config, so upkeeps start performing again + for i := 0; i < len(consumers); i++ { + upkeepAddr := consumers[i].Address() + + logTriggerConfigStruct := automation_utils_2_1.LogTriggerConfig{ + ContractAddress: common.HexToAddress(upkeepAddr), + FilterSelector: 0, + Topic0: topic0InBytesMatch, + Topic1: bytes0, + Topic2: bytes0, + Topic3: bytes0, + } + encodedLogTriggerConfig, err := utilsABI21.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) + if err != nil { + return + } - var countersAfterSetMatch = make([]*big.Int, len(upkeepIDs)) + err = a.Registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig) + require.NoError(t, err, "Could not set upkeep trigger config at index %d", i) + } - for i := 0; i < len(upkeepIDs); i++ { - // Obtain the amount of times the upkeep has been executed so far - countersAfterSetMatch[i], err = consumers[i].Counter(testcontext.Get(t)) - require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) - l.Info().Int64("Upkeep Count", countersAfterSetMatch[i].Int64()).Int("Upkeep Index", i).Msg("Upkeep") - } + err = a.ChainClient.WaitForEvents() + require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps") - // Wait for 30 seconds to make sure backend is ready - time.Sleep(30 * time.Second) - // Start the consumers again - for i := 0; i < len(consumers); i++ { - err := consumers[i].Start() - if err != nil { - return - } - } + var countersAfterSetMatch = make([]*big.Int, len(upkeepIDs)) - l.Info().Msg("Making sure the counter starts increasing again") - gom.Eventually(func(g gomega.Gomega) { - // Check if the upkeeps are performing multiple times by analyzing their counters - for i := 0; i < len(upkeepIDs); i++ { - counter, err := consumers[i].Counter(testcontext.Get(t)) - require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) - expect := int64(5) - l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep Index", i).Msg("Number of upkeeps performed") - g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", countersAfterSetMatch[i].Int64()+expect), - "Expected consumer counter to be greater than %d, but got %d", countersAfterSetMatch[i].Int64()+expect, counter.Int64()) - } - }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer + for i := 0; i < len(upkeepIDs); i++ { + // Obtain the amount of times the upkeep has been executed so far + countersAfterSetMatch[i], err = consumers[i].Counter(testcontext.Get(t)) + require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) + l.Info().Int64("Upkeep Count", countersAfterSetMatch[i].Int64()).Int("Upkeep Index", i).Msg("Upkeep") + } + + // Wait for 30 seconds to make sure backend is ready + time.Sleep(30 * time.Second) + // Start the consumers again + for i := 0; i < len(consumers); i++ { + err := consumers[i].Start() + if err != nil { + return + } + } + + l.Info().Msg("Making sure the counter starts increasing again") + gom.Eventually(func(g gomega.Gomega) { + // Check if the upkeeps are performing multiple times by analyzing their counters + for i := 0; i < len(upkeepIDs); i++ { + counter, err := consumers[i].Counter(testcontext.Get(t)) + require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) + expect := int64(5) + l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep Index", i).Msg("Number of upkeeps performed") + g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", countersAfterSetMatch[i].Int64()+expect), + "Expected consumer counter to be greater than %d, but got %d", countersAfterSetMatch[i].Int64()+expect, counter.Int64()) + } + }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer + }) + } } func TestAutomationAddFunds(t *testing.T) { @@ -407,11 +421,12 @@ func TestAutomationAddFunds(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() config, err := tc.GetConfig("Smoke", tc.Automation) @@ -473,6 +488,7 @@ func TestAutomationPauseUnPause(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } for n, rv := range registryVersions { @@ -572,11 +588,12 @@ func TestAutomationRegisterUpkeep(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) @@ -660,11 +677,12 @@ func TestAutomationPauseRegistry(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() config, err := tc.GetConfig("Smoke", tc.Automation) @@ -733,11 +751,12 @@ func TestAutomationKeeperNodesDown(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) @@ -837,11 +856,12 @@ func TestAutomationPerformSimulation(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() config, err := tc.GetConfig("Smoke", tc.Automation) @@ -904,11 +924,12 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) @@ -997,7 +1018,7 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { highCheckGasLimit.CheckGasLimit = uint32(5000000) highCheckGasLimit.RegistryVersion = registryVersion - ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(l, nodesWithoutBootstrap, highCheckGasLimit, a.Registrar.Address(), 30*time.Second, a.Registry.RegistryOwnerAddress()) + ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(l, nodesWithoutBootstrap, highCheckGasLimit, a.Registrar.Address(), 30*time.Second, a.Registry.RegistryOwnerAddress(), a.Registry.ChainModuleAddress(), a.Registry.ReorgProtectionEnabled()) require.NoError(t, err, "Error building OCR config") err = a.Registry.SetConfig(highCheckGasLimit, ocrConfig) @@ -1022,11 +1043,12 @@ func TestUpdateCheckData(t *testing.T) { registryVersions := map[string]ethereum.KeeperRegistryVersion{ "registry_2_0": ethereum.RegistryVersion_2_0, "registry_2_1": ethereum.RegistryVersion_2_1, + "registry_2_2": ethereum.RegistryVersion_2_2, } - for name, registryVersion := range registryVersions { - name := name - registryVersion := registryVersion + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) diff --git a/integration-tests/smoke/automation_test.go_test_list.json b/integration-tests/smoke/automation_test.go_test_list.json index b88684599c7..3e7a82effd3 100644 --- a/integration-tests/smoke/automation_test.go_test_list.json +++ b/integration-tests/smoke/automation_test.go_test_list.json @@ -3,19 +3,31 @@ { "name": "TestAutomationBasic", "label": "ubuntu-latest", - "nodes": 2, + "nodes": 3, "run":[ {"name":"registry_2_0"}, - {"name":"registry_2_1_conditional"} + {"name":"registry_2_1_conditional"}, + {"name":"registry_2_1_logtrigger"} ] }, { "name": "TestAutomationBasic", "label": "ubuntu-latest", - "nodes": 2, + "nodes": 3, "run":[ - {"name":"registry_2_1_logtrigger"}, - {"name":"registry_2_1_with_mercury_v02"} + {"name":"registry_2_1_with_mercury_v02"}, + {"name":"registry_2_1_with_mercury_v03"}, + {"name":"registry_2_1_with_logtrigger_and_mercury_v02"} + ] + }, + { + "name": "TestAutomationBasic", + "label": "ubuntu-latest", + "nodes": 3, + "run":[ + {"name":"registry_2_2_conditional"}, + {"name":"registry_2_2_logtrigger"}, + {"name":"registry_2_2_with_mercury_v02"} ] }, { @@ -23,52 +35,54 @@ "label": "ubuntu-latest", "nodes": 2, "run":[ - {"name":"registry_2_1_with_mercury_v03"}, - {"name":"registry_2_1_with_logtrigger_and_mercury_v02"} + {"name":"registry_2_2_with_mercury_v03"}, + {"name":"registry_2_2_with_logtrigger_and_mercury_v02"} ] }, { - "name": "TestSetUpkeepTriggerConfig" + "name": "TestSetUpkeepTriggerConfig", + "label": "ubuntu-latest", + "nodes": 2 }, { "name": "TestAutomationAddFunds", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 }, { "name": "TestAutomationPauseUnPause", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 }, { "name": "TestAutomationRegisterUpkeep", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 }, { "name": "TestAutomationPauseRegistry", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 }, { "name": "TestAutomationKeeperNodesDown", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 }, { "name": "TestAutomationPerformSimulation", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 }, { "name": "TestAutomationCheckPerformGasLimit", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 }, { "name": "TestUpdateCheckData", "label": "ubuntu-latest", - "nodes": 2 + "nodes": 3 } ] } \ No newline at end of file diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index 1330ea291b8..4be6eb9c59c 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -27,18 +27,18 @@ import ( reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" - iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" - "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" tt "github.com/smartcontractkit/chainlink/integration-tests/types" + iregistry22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" ) // KeeperBenchmarkTest builds a test to check that chainlink nodes are able to upkeep a specified amount of Upkeep @@ -197,7 +197,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Keep for index := range keysToFund { // Fund chainlink nodes nodesToFund := k.chainlinkNodes - if inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_0 || inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_1 { + if inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_0 || inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_1 || inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_2 { nodesToFund = k.chainlinkNodes[1:] } err = actions.FundChainlinkNodesAddress(nodesToFund, k.chainClient, k.Inputs.ChainlinkNodeFunding, index) @@ -247,12 +247,12 @@ func (k *KeeperBenchmarkTest) Run() { txKeyId = 0 } ocrConfig, err := actions.BuildAutoOCR2ConfigVarsWithKeyIndex( - k.t, nodesWithoutBootstrap, *inputs.KeeperRegistrySettings, k.keeperRegistrars[rIndex].Address(), k.Inputs.DeltaStage, txKeyId, common.Address{}, + k.t, nodesWithoutBootstrap, *inputs.KeeperRegistrySettings, k.keeperRegistrars[rIndex].Address(), k.Inputs.DeltaStage, txKeyId, common.Address{}, k.keeperRegistries[rIndex].ChainModuleAddress(), k.keeperRegistries[rIndex].ReorgProtectionEnabled(), ) require.NoError(k.t, err, "Building OCR config shouldn't fail") // Send keeper jobs to registry and chainlink nodes - if inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_0 || inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_1 { + if inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_0 || inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_1 || inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_2 { actions.CreateOCRKeeperJobs(k.t, k.chainlinkNodes, k.keeperRegistries[rIndex].Address(), k.chainClient.GetChainID().Int64(), txKeyId, inputs.RegistryVersions[rIndex]) err = k.keeperRegistries[rIndex].SetConfig(*inputs.KeeperRegistrySettings, ocrConfig) require.NoError(k.t, err, "Registry config should be be set successfully") @@ -538,6 +538,8 @@ func (k *KeeperBenchmarkTest) contractABI(rIndex int) *abi.ABI { contractABI, err = keeper_registry_wrapper2_0.KeeperRegistryMetaData.GetAbi() case ethereum.RegistryVersion_2_1: contractABI, err = iregistry21.IKeeperRegistryMasterMetaData.GetAbi() + case ethereum.RegistryVersion_2_2: + contractABI, err = iregistry22.IAutomationRegistryMasterMetaData.GetAbi() default: contractABI, err = keeper_registry_wrapper2_0.KeeperRegistryMetaData.GetAbi() } @@ -652,7 +654,7 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int) { // Fund the registry with LINK err := k.linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(k.Inputs.Upkeeps.NumberOfUpkeeps)))) require.NoError(k.t, err, "Funding keeper registry contract shouldn't fail") - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(k.t, k.chainlinkNodes[1:], *k.Inputs.KeeperRegistrySettings, registrar.Address(), k.Inputs.DeltaStage) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(k.t, k.chainlinkNodes[1:], *k.Inputs.KeeperRegistrySettings, registrar.Address(), k.Inputs.DeltaStage, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled()) k.log.Debug().Interface("KeeperRegistrySettings", *k.Inputs.KeeperRegistrySettings).Interface("OCRConfig", ocrConfig).Msg("Config") require.NoError(k.t, err, "Error building OCR config vars") err = registry.SetConfig(*k.Inputs.KeeperRegistrySettings, ocrConfig) diff --git a/integration-tests/universal/log_poller/helpers.go b/integration-tests/universal/log_poller/helpers.go index db7eaee625b..b91156a3784 100644 --- a/integration-tests/universal/log_poller/helpers.go +++ b/integration-tests/universal/log_poller/helpers.go @@ -31,6 +31,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" @@ -1200,7 +1201,7 @@ func SetupLogPollerTestDocker( err = actions.CreateOCRKeeperJobsLocal(l, nodeClients, registry.Address(), network.ChainID, 0, registryVersion) require.NoError(t, err, "Error creating OCR Keeper Jobs") - ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(l, workerNodes, registryConfig, registrar.Address(), 30*time.Second, registry.RegistryOwnerAddress()) + ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(l, workerNodes, registryConfig, registrar.Address(), 30*time.Second, registry.RegistryOwnerAddress(), registry.ChainModuleAddress(), registry.ReorgProtectionEnabled()) require.NoError(t, err, "Error building OCR config vars") err = registry.SetConfig(automationDefaultRegistryConfig, ocrConfig) require.NoError(t, err, "Registry config should be set successfully") diff --git a/sonar-project.properties b/sonar-project.properties index 7d0c1be5fc5..67da119cd2a 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -53,7 +53,8 @@ sonar.cpd.exclusions=\ **/config.go,\ **/core/services/ocr2/plugins/ocr2keeper/evm/**/*,\ **/core/services/ocr2/plugins/mercury/plugin.go,\ -**/integration-tests/load/**/* +**/integration-tests/load/**/*,\ +**/integration-tests/contracts/ethereum_keeper_contracts.go # Tests' root folder, inclusions (tests to check and count) and exclusions sonar.tests=. From b60acb4c33586543c04b2658b7b27fae29008cf2 Mon Sep 17 00:00:00 2001 From: Radek Scheibinger Date: Thu, 22 Feb 2024 00:12:08 +0100 Subject: [PATCH 70/98] chore: export ABIs in the compile step (#12083) By default ABIs where not exported in the compile step. Updated the dir path to fetch ABIs from the target location used by prepublish script. Co-authored-by: chainchad <96362174+chainchad@users.noreply.github.com> --- contracts/hardhat.config.ts | 1 + contracts/package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 5306827b8e3..6a0b36ad0c7 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -35,6 +35,7 @@ subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction( let config = { abiExporter: { path: './abi', + runOnCompile: true, }, paths: { artifacts: './artifacts', diff --git a/contracts/package.json b/contracts/package.json index 654ec1d8958..20717c036bc 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -22,7 +22,7 @@ }, "files": [ "src/v0.8", - "abi/src/v0.8" + "abi/v0.8" ], "pnpm": { "_comment": "See https://github.com/ethers-io/ethers.js/discussions/2849#discussioncomment-2696454", From c14789651ecff7c1db31393d33baa81a48127c8a Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Wed, 21 Feb 2024 22:55:55 -0800 Subject: [PATCH 71/98] [KS-55] Minor fixes to Engine and Write target (#12135) 1. Fix default gas limit in the Write target 2. Use mocked IDs with exactly 32 bytes 3. Pass observations as a list (of size 1) 4. More logging --- core/capabilities/targets/write_target.go | 16 +++++--- .../capabilities/targets/write_target_test.go | 3 +- core/services/workflows/delegate.go | 2 +- core/services/workflows/engine.go | 39 ++++++++++++------- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index c6d34271662..531730cc089 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -22,14 +22,15 @@ import ( 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" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" ) var forwardABI = evmtypes.MustGetABI(forwarder.KeystoneForwarderMetaData.ABI) -func InitializeWrite(registry commontypes.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer) error { +func InitializeWrite(registry commontypes.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer, lggr logger.Logger) error { for _, chain := range legacyEVMChains.Slice() { - capability := NewEvmWrite(chain) + capability := NewEvmWrite(chain, lggr) if err := registry.Add(context.TODO(), capability); err != nil { return err } @@ -41,12 +42,15 @@ var ( _ capabilities.ActionCapability = &EvmWrite{} ) +const defaultGasLimit = 200000 + type EvmWrite struct { chain legacyevm.Chain capabilities.CapabilityInfo + lggr logger.Logger } -func NewEvmWrite(chain legacyevm.Chain) *EvmWrite { +func NewEvmWrite(chain legacyevm.Chain, lggr logger.Logger) *EvmWrite { // generate ID based on chain selector name := fmt.Sprintf("write_%v", chain.ID()) chainName, err := chainselectors.NameFromChainId(chain.ID().Uint64()) @@ -64,6 +68,7 @@ func NewEvmWrite(chain legacyevm.Chain) *EvmWrite { return &EvmWrite{ chain, info, + lggr.Named("EvmWrite"), } } @@ -153,6 +158,7 @@ func encodePayload(args []any, rawSelector string) ([]byte, error) { } func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.CapabilityResponse, request capabilities.CapabilityRequest) error { + cap.lggr.Debugw("Execute", "request", request) // TODO: idempotency // TODO: extract into ChainWriter? @@ -184,8 +190,6 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C // TODO: validate encoded report is prefixed with workflowID and executionID that match the request meta - // unlimited gas in the MVP demo - gasLimit := 0 // No signature validation in the MVP demo signatures := [][]byte{} @@ -208,7 +212,7 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C FromAddress: config.FromAddress().Address(), ToAddress: config.ForwarderAddress().Address(), EncodedPayload: calldata, - FeeLimit: uint32(gasLimit), + FeeLimit: uint32(defaultGasLimit), Meta: txMeta, Strategy: strategy, Checker: checker, diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index 68ca890cc0c..c99e84beb75 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" @@ -45,7 +46,7 @@ func TestEvmWrite(t *testing.T) { evmcfg := evmtest.NewChainScopedConfig(t, cfg) chain.On("Config").Return(evmcfg) - capability := targets.NewEvmWrite(chain) + capability := targets.NewEvmWrite(chain, logger.TestLogger(t)) ctx := testutils.Context(t) config, err := values.NewMap(map[string]any{ diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index 13a8bda4043..6faa0bacdb8 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -44,7 +44,7 @@ func (d *Delegate) ServicesForSpec(spec job.Job) ([]job.ServiceCtx, error) { func NewDelegate(logger logger.Logger, registry types.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer) *Delegate { // NOTE: we temporarily do registration inside NewDelegate, this will be moved out of job specs in the future - _ = targets.InitializeWrite(registry, legacyEVMChains) + _ = targets.InitializeWrite(registry, legacyEVMChains, logger) return &Delegate{logger: logger, registry: registry} } diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 3260702e66b..01d1326e072 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -15,9 +15,10 @@ import ( ) const ( - mockedWorkflowID = "aaaaaaaa-f4d1-422f-a4b2-8ce0a1075f0a" - mockedExecutionID = "bbbbbbbb-f4d1-422f-a4b2-8ce0a1075f0a" - mockedTriggerID = "cccccccc-5cac-4071-be62-0152dd9adb0f" + // NOTE: max 32 bytes per ID - consider enforcing exactly 32 bytes? + mockedWorkflowID = "aaaaaaaaaa0000000000000000000000" + mockedExecutionID = "bbbbbbbbbb0000000000000000000000" + mockedTriggerID = "cccccccccc0000000000000000000000" ) type Engine struct { @@ -143,13 +144,20 @@ func (e *Engine) handleExecution(ctx context.Context, event capabilities.Capabil if err != nil { return err } + if len(results.Underlying) == 0 { + return fmt.Errorf("consensus returned no reports") + } + if len(results.Underlying) > 1 { + e.logger.Debugw("consensus returned more than one report") + } - _, err = e.handleTarget(ctx, results) + // we're expecting exactly one report + _, err = e.handleTarget(ctx, results.Underlying[0]) return err } -func (e *Engine) handleTarget(ctx context.Context, resp *values.List) (*values.List, error) { - +func (e *Engine) handleTarget(ctx context.Context, resp values.Value) (*values.List, error) { + e.logger.Debugw("handle target") inputs := map[string]values.Value{ "report": resp, } @@ -158,23 +166,28 @@ func (e *Engine) handleTarget(ctx context.Context, resp *values.List) (*values.L Inputs: &values.Map{Underlying: inputs}, Config: e.targetConfig, Metadata: capabilities.RequestMetadata{ - WorkflowID: mockedWorkflowID, + WorkflowID: mockedWorkflowID, + WorkflowExecutionID: mockedExecutionID, }, } return capabilities.ExecuteSync(ctx, e.target, tr) } -func (e *Engine) handleConsensus(ctx context.Context, resp capabilities.CapabilityResponse) (*values.List, error) { - e.logger.Debugw("running consensus", "resp", resp) - inputs := map[string]values.Value{ - "observations": resp.Value, - } +func (e *Engine) handleConsensus(ctx context.Context, event capabilities.CapabilityResponse) (*values.List, error) { + e.logger.Debugw("running consensus", "event", event) cr := capabilities.CapabilityRequest{ Metadata: capabilities.RequestMetadata{ WorkflowID: mockedWorkflowID, WorkflowExecutionID: mockedExecutionID, }, - Inputs: &values.Map{Underlying: inputs}, + Inputs: &values.Map{ + Underlying: map[string]values.Value{ + // each node provides a single observation - outputs of mercury trigger + "observations": &values.List{ + Underlying: []values.Value{event.Value}, + }, + }, + }, Config: e.consensusConfig, } return capabilities.ExecuteSync(ctx, e.consensus, cr) From 2b99f070e71e40cc4dd3fcde5380400ca4cd1386 Mon Sep 17 00:00:00 2001 From: "app-token-issuer-infra-releng[bot]" <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:33:42 +0200 Subject: [PATCH 72/98] Update Operator UI from v0.8.0-8da47c3 to v0.8.0-a2b54a2 (#12059) * Update Operator UI from v0.8.0-8da47c3 to v0.8.0-a2b54a2 * Sig scanner check * Add web assets --------- Co-authored-by: github-merge-queue Co-authored-by: george-dorin --- core/web/assets/index.html | 2 +- core/web/assets/index.html.gz | Bin 420 -> 419 bytes ...614139.js => main.f42e73c0c7811e9907db.js} | 2 +- ....js.gz => main.f42e73c0c7811e9907db.js.gz} | Bin 1196933 -> 1196936 bytes operator_ui/TAG | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) rename core/web/assets/{main.74b124ef5d2ef3614139.js => main.f42e73c0c7811e9907db.js} (93%) rename core/web/assets/{main.74b124ef5d2ef3614139.js.gz => main.f42e73c0c7811e9907db.js.gz} (92%) diff --git a/core/web/assets/index.html b/core/web/assets/index.html index 77331861516..21811e104e8 100644 --- a/core/web/assets/index.html +++ b/core/web/assets/index.html @@ -1 +1 @@ -Operator UIChainlink
\ No newline at end of file +Operator UIChainlink
\ No newline at end of file diff --git a/core/web/assets/index.html.gz b/core/web/assets/index.html.gz index afbd1b1a38b50f16f3c36b98a2bcef67890ed40b..2067ae210af32b1dbe31cb9cd36fbe814930f729 100644 GIT binary patch literal 419 zcmV;U0bKqciwFP!000021C^3NYa1~Th5w2w$f@>fouoJk(&i8-q)-ZNa>#Kk&3dPm zG>bIe#Q(mm?HCG$(u;&1%=c!V#(oIwWj~@CB*o62PK40egaXPBP%4Vk&rhG1H`<)! z3<;f{2wz7oqLt??n8oQ=3NpBW6M0-79t+AO1aVnCM0Bf}AtVvIZzC2EF6#NwnxkYR z^!Hj zV67LI4?ULzGBnq>-_04L9x3}#&Y?_}{ch(#Uoi)eB*>Ko* zHuFh-;hoBeK?y6&u!*R?zyv>zw!*6HvXX(Sf^lrDITzYMlcL~sVV2n^(9~IT#GAva N{st{JBxt|_006$~&U^p> literal 420 zcmV;V0bBkbiwFP!000021C^3nYa1~Th5w2w=u_?0`jTFPw0Q^=QYeMCdFbO9L?pLJ*hLLqxZl8A1}V`!Zqy;i4WNtT{_I zQvRh1MyKn*Mf^b&dCpo51$(Clk+I$yQxg=KO$&HwDDCOF$tcDTKzU{~%Xw3hiR^!N7R4KYW`5CDZw7i^YWx!L%)AX=o)$T zg+@^Udn`_$F0E?uP8+BdrJ4kkn|IsYYQ4q&CakgFyj^Wqn-9&;syl1WgwC4t;_Nsa zJDd3;|KNklh(QS}%&?27KEVXv&bGp;9I}#us)BKBthpB2K$D{2bYYg+C(zVcbH=_},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125M(o,n))void 0!==u&&0>M(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[a]=n,r=a);else if(void 0!==u&&0>M(u,n))e[r]=u,e[s]=n,r=s;else break a}}return t}return null}function M(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var O=[],A=[],L=1,C=null,I=3,D=!1,N=!1,P=!1;function R(e){for(var t=x(A);null!==t;){if(null===t.callback)T(A);else if(t.startTime<=e)T(A),t.sortIndex=t.expirationTime,k(O,t);else break;t=x(A)}}function j(e){if(P=!1,R(e),!N){if(null!==x(O))N=!0,n(F);else{var t=x(A);null!==t&&r(j,t.startTime-e)}}}function F(e,n){N=!1,P&&(P=!1,i()),D=!0;var o=I;try{for(R(n),C=x(O);null!==C&&(!(C.expirationTime>n)||e&&!a());){var s=C.callback;if(null!==s){C.callback=null,I=C.priorityLevel;var u=s(C.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?C.callback=u:C===x(O)&&T(O),R(n)}else T(O);C=x(O)}if(null!==C)var c=!0;else{var l=x(A);null!==l&&r(j,l.startTime-n),c=!1}return c}finally{C=null,I=o,D=!1}}function Y(e){switch(e){case 1:return -1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=o;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,a,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0s?(e.sortIndex=u,k(A,e),null===x(O)&&e===x(A)&&(P?i():P=!0,r(j,u-s))):(e.sortIndex=o,k(O,e),N||D||(N=!0,n(F))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();R(e);var n=x(O);return n!==C&&null!==C&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function c(e,t,n){var r=t.length-1;if(r=0?(i>0&&(e.lastNeed=i-1),i):--r=0?(i>0&&(e.lastNeed=i-2),i):--r=0?(i>0&&(2===i?i=0:e.lastNeed=i-3),i):0}function l(e,t,n){if((192&t[0])!=128)return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if((192&t[1])!=128)return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&(192&t[2])!=128)return e.lastNeed=2,"�"}}function f(e){var t=this.lastTotal-this.lastNeed,n=l(this,e,t);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):void(e.copy(this.lastChar,t,0,e.length),this.lastNeed-=e.length)}function d(e,t){var n=c(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t}function p(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function b(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function m(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function v(e){return e.toString(this.encoding)}function y(e){return e&&e.length?this.write(e):""}t.s=s,s.prototype.write=function(e){var t,n;if(0===e.length)return"";if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return nOF});var r,i,a,o,s,u,c,l=n(67294),f=n.t(l,2),d=n(97779),h=n(47886),p=n(57209),b=n(32316),m=n(95880),g=n(17051),v=n(71381),y=n(81701),w=n(3022),_=n(60323),E=n(87591),S=n(25649),k=n(28902),x=n(71426),T=n(48884),M=n(94184),O=n.n(M),A=n(55977),L=n(73935),C=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some(function(e,r){return e[0]===t&&(n=r,!0)}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n0},e.prototype.connect_=function(){I&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Y?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){I&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;F.some(function(e){return!!~n.indexOf(e)})&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),U=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),er="undefined"!=typeof WeakMap?new WeakMap:new C,ei=function(){function e(t){if(!(this instanceof e))throw TypeError("Cannot call a class as a function.");if(!arguments.length)throw TypeError("1 argument required, but only 0 present.");var n=B.getInstance(),r=new en(t,n,this);er.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){ei.prototype[e]=function(){var t;return(t=er.get(this))[e].apply(t,arguments)}});var ea=void 0!==D.ResizeObserver?D.ResizeObserver:ei;let eo=ea;var es=function(e){var t=[],n=null,r=function(){for(var r=arguments.length,i=Array(r),a=0;a=t||n<0||f&&r>=a}function g(){var e=eb();if(m(e))return v(e);s=setTimeout(g,b(e))}function v(e){return(s=void 0,d&&r)?h(e):(r=i=void 0,o)}function y(){void 0!==s&&clearTimeout(s),c=0,r=u=i=s=void 0}function w(){return void 0===s?o:v(eb())}function _(){var e=eb(),n=m(e);if(r=arguments,i=this,u=e,n){if(void 0===s)return p(u);if(f)return clearTimeout(s),s=setTimeout(g,t),h(u)}return void 0===s&&(s=setTimeout(g,t)),o}return t=ez(t)||0,ed(n)&&(l=!!n.leading,a=(f="maxWait"in n)?eW(ez(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),_.cancel=y,_.flush=w,_}let eq=eV;var eZ="Expected a function";function eX(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw TypeError(eZ);return ed(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),eq(e,t,{leading:r,maxWait:t,trailing:i})}let eJ=eX;var eQ={debounce:eq,throttle:eJ},e1=function(e){return eQ[e]},e0=function(e){return"function"==typeof e},e2=function(){return"undefined"==typeof window},e3=function(e){return e instanceof Element||e instanceof HTMLDocument};function e4(e){return(e4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function e5(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function e6(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&l.createElement(tG.Z,{variant:"indeterminate",classes:r}))};tK.propTypes={fetchCount:el().number.isRequired};let tV=(0,b.withStyles)(tW)(tK);var tq=n(5536);let tZ=n.p+"ba8bbf16ebf8e1d05bef.svg";function tX(){return(tX=Object.assign||function(e){for(var t=1;t120){for(var d=Math.floor(u/80),h=u%80,p=[],b=0;b0},name:{enumerable:!1},nodes:{enumerable:!1},source:{enumerable:!1},positions:{enumerable:!1},originalError:{enumerable:!1}}),null!=s&&s.stack)?(Object.defineProperty(nf(b),"stack",{value:s.stack,writable:!0,configurable:!0}),nl(b)):(Error.captureStackTrace?Error.captureStackTrace(nf(b),n):Object.defineProperty(nf(b),"stack",{value:Error().stack,writable:!0,configurable:!0}),b)}return ns(n,[{key:"toString",value:function(){return nw(this)}},{key:t4.YF,get:function(){return"Object"}}]),n}(nd(Error));function ny(e){return void 0===e||0===e.length?void 0:e}function nw(e){var t=e.message;if(e.nodes)for(var n=0,r=e.nodes;n",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"}),nx=n(10143),nT=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"}),nM=n(87392),nO=function(){function e(e){var t=new nS.WU(nk.SOF,0,0,0,0,null);this.source=e,this.lastToken=t,this.token=t,this.line=1,this.lineStart=0}var t=e.prototype;return t.advance=function(){return this.lastToken=this.token,this.token=this.lookahead()},t.lookahead=function(){var e,t=this.token;if(t.kind!==nk.EOF)do t=null!==(e=t.next)&&void 0!==e?e:t.next=nC(this,t);while(t.kind===nk.COMMENT)return t},e}();function nA(e){return e===nk.BANG||e===nk.DOLLAR||e===nk.AMP||e===nk.PAREN_L||e===nk.PAREN_R||e===nk.SPREAD||e===nk.COLON||e===nk.EQUALS||e===nk.AT||e===nk.BRACKET_L||e===nk.BRACKET_R||e===nk.BRACE_L||e===nk.PIPE||e===nk.BRACE_R}function nL(e){return isNaN(e)?nk.EOF:e<127?JSON.stringify(String.fromCharCode(e)):'"\\u'.concat(("00"+e.toString(16).toUpperCase()).slice(-4),'"')}function nC(e,t){for(var n=e.source,r=n.body,i=r.length,a=t.end;a31||9===a))return new nS.WU(nk.COMMENT,t,s,n,r,i,o.slice(t+1,s))}function nN(e,t,n,r,i,a){var o=e.body,s=n,u=t,c=!1;if(45===s&&(s=o.charCodeAt(++u)),48===s){if((s=o.charCodeAt(++u))>=48&&s<=57)throw n_(e,u,"Invalid number, unexpected digit after 0: ".concat(nL(s),"."))}else u=nP(e,u,s),s=o.charCodeAt(u);if(46===s&&(c=!0,s=o.charCodeAt(++u),u=nP(e,u,s),s=o.charCodeAt(u)),(69===s||101===s)&&(c=!0,(43===(s=o.charCodeAt(++u))||45===s)&&(s=o.charCodeAt(++u)),u=nP(e,u,s),s=o.charCodeAt(u)),46===s||nU(s))throw n_(e,u,"Invalid number, expected digit but got: ".concat(nL(s),"."));return new nS.WU(c?nk.FLOAT:nk.INT,t,u,r,i,a,o.slice(t,u))}function nP(e,t,n){var r=e.body,i=t,a=n;if(a>=48&&a<=57){do a=r.charCodeAt(++i);while(a>=48&&a<=57)return i}throw n_(e,i,"Invalid number, expected digit but got: ".concat(nL(a),"."))}function nR(e,t,n,r,i){for(var a=e.body,o=t+1,s=o,u=0,c="";o=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function nB(e,t,n,r,i){for(var a=e.body,o=a.length,s=t+1,u=0;s!==o&&!isNaN(u=a.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new nS.WU(nk.NAME,t,s,n,r,i,a.slice(t,s))}function nU(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}function nH(e,t){return new n$(e,t).parseDocument()}var n$=function(){function e(e,t){var n=(0,nx.T)(e)?e:new nx.H(e);this._lexer=new nO(n),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(nk.NAME);return{kind:nE.h.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:nE.h.DOCUMENT,definitions:this.many(nk.SOF,this.parseDefinition,nk.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(nk.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else if(this.peek(nk.BRACE_L))return this.parseOperationDefinition();else if(this.peekDescription())return this.parseTypeSystemDefinition();throw this.unexpected()},t.parseOperationDefinition=function(){var e,t=this._lexer.token;if(this.peek(nk.BRACE_L))return{kind:nE.h.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(t)};var n=this.parseOperationType();return this.peek(nk.NAME)&&(e=this.parseName()),{kind:nE.h.OPERATION_DEFINITION,operation:n,name:e,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseOperationType=function(){var e=this.expectToken(nk.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(nk.PAREN_L,this.parseVariableDefinition,nk.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:nE.h.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(nk.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(nk.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(nk.DOLLAR),{kind:nE.h.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:nE.h.SELECTION_SET,selections:this.many(nk.BRACE_L,this.parseSelection,nk.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(nk.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,n=this._lexer.token,r=this.parseName();return this.expectOptionalToken(nk.COLON)?(e=r,t=this.parseName()):t=r,{kind:nE.h.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(nk.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(n)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(nk.PAREN_L,t,nk.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:nE.h.ARGUMENT,name:this.parseName(),value:(this.expectToken(nk.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(nk.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(nk.NAME)?{kind:nE.h.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:nE.h.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return(this.expectKeyword("fragment"),(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)===!0)?{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case nk.BRACKET_L:return this.parseList(e);case nk.BRACE_L:return this.parseObject(e);case nk.INT:return this._lexer.advance(),{kind:nE.h.INT,value:t.value,loc:this.loc(t)};case nk.FLOAT:return this._lexer.advance(),{kind:nE.h.FLOAT,value:t.value,loc:this.loc(t)};case nk.STRING:case nk.BLOCK_STRING:return this.parseStringLiteral();case nk.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:nE.h.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:nE.h.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:nE.h.NULL,loc:this.loc(t)};default:return{kind:nE.h.ENUM,value:t.value,loc:this.loc(t)}}case nk.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:nE.h.STRING,value:e.value,block:e.kind===nk.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseValueLiteral(e)};return{kind:nE.h.LIST,values:this.any(nk.BRACKET_L,r,nk.BRACKET_R),loc:this.loc(n)}},t.parseObject=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseObjectField(e)};return{kind:nE.h.OBJECT,fields:this.any(nk.BRACE_L,r,nk.BRACE_R),loc:this.loc(n)}},t.parseObjectField=function(e){var t=this._lexer.token,n=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.OBJECT_FIELD,name:n,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(nk.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(nk.AT),{kind:nE.h.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return(this.expectOptionalToken(nk.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(nk.BRACKET_R),e={kind:nE.h.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(nk.BANG))?{kind:nE.h.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:nE.h.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(nk.STRING)||this.peek(nk.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var n=this.parseDirectives(!0),r=this.many(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);return{kind:nE.h.SCHEMA_DEFINITION,description:t,directives:n,operationTypes:r,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(nk.COLON);var n=this.parseNamedType();return{kind:nE.h.OPERATION_TYPE_DEFINITION,operation:t,type:n,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.SCALAR_TYPE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.OBJECT_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if((null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)===!0){var t=[];this.expectOptionalToken(nk.AMP);do t.push(this.parseNamedType());while(this.expectOptionalToken(nk.AMP)||this.peek(nk.NAME))return t}return this.delimitedMany(nk.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)===!0&&this.peek(nk.BRACE_L)&&this._lexer.lookahead().kind===nk.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(nk.BRACE_L,this.parseFieldDefinition,nk.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseArgumentDefs();this.expectToken(nk.COLON);var i=this.parseTypeReference(),a=this.parseDirectives(!0);return{kind:nE.h.FIELD_DEFINITION,description:t,name:n,arguments:r,type:i,directives:a,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(nk.PAREN_L,this.parseInputValueDef,nk.PAREN_R)},t.parseInputValueDef=function(){var e,t=this._lexer.token,n=this.parseDescription(),r=this.parseName();this.expectToken(nk.COLON);var i=this.parseTypeReference();this.expectOptionalToken(nk.EQUALS)&&(e=this.parseValueLiteral(!0));var a=this.parseDirectives(!0);return{kind:nE.h.INPUT_VALUE_DEFINITION,description:n,name:r,type:i,defaultValue:e,directives:a,loc:this.loc(t)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.INTERFACE_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:nE.h.UNION_TYPE_DEFINITION,description:t,name:n,directives:r,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(nk.EQUALS)?this.delimitedMany(nk.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:nE.h.ENUM_TYPE_DEFINITION,description:t,name:n,directives:r,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseEnumValueDefinition,nk.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.ENUM_VALUE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:nE.h.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseInputValueDef,nk.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),n=this.optionalMany(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);if(0===t.length&&0===n.length)throw this.unexpected();return{kind:nE.h.SCHEMA_EXTENSION,directives:t,operationTypes:n,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),n=this.parseDirectives(!0);if(0===n.length)throw this.unexpected();return{kind:nE.h.SCALAR_TYPE_EXTENSION,name:t,directives:n,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.OBJECT_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.INTERFACE_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseUnionMemberTypes();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.UNION_TYPE_EXTENSION,name:t,directives:n,types:r,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseEnumValuesDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.ENUM_TYPE_EXTENSION,name:t,directives:n,values:r,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseInputFieldsDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:n,fields:r,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(nk.AT);var n=this.parseName(),r=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var a=this.parseDirectiveLocations();return{kind:nE.h.DIRECTIVE_DEFINITION,description:t,name:n,arguments:r,repeatable:i,locations:a,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(nk.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==nT[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if((null===(t=this._options)||void 0===t?void 0:t.noLocation)!==!0)return new nS.Ye(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw n_(this._lexer.source,t.start,"Expected ".concat(nG(e),", found ").concat(nz(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind===nk.NAME&&t.value===e)this._lexer.advance();else throw n_(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(nz(t),"."))},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===nk.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return n_(this._lexer.source,t.start,"Unexpected ".concat(nz(t),"."))},t.any=function(e,t,n){this.expectToken(e);for(var r=[];!this.expectOptionalToken(n);)r.push(t.call(this));return r},t.optionalMany=function(e,t,n){if(this.expectOptionalToken(e)){var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r}return[]},t.many=function(e,t,n){this.expectToken(e);var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var n=[];do n.push(t.call(this));while(this.expectOptionalToken(e))return n},e}();function nz(e){var t=e.value;return nG(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function nG(e){return nA(e)?'"'.concat(e,'"'):e}var nW=new Map,nK=new Map,nV=!0,nq=!1;function nZ(e){return e.replace(/[\s,]+/g," ").trim()}function nX(e){return nZ(e.source.body.substring(e.start,e.end))}function nJ(e){var t=new Set,n=[];return e.definitions.forEach(function(e){if("FragmentDefinition"===e.kind){var r=e.name.value,i=nX(e.loc),a=nK.get(r);a&&!a.has(i)?nV&&console.warn("Warning: fragment with name "+r+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):a||nK.set(r,a=new Set),a.add(i),t.has(i)||(t.add(i),n.push(e))}else n.push(e)}),(0,t0.pi)((0,t0.pi)({},e),{definitions:n})}function nQ(e){var t=new Set(e.definitions);t.forEach(function(e){e.loc&&delete e.loc,Object.keys(e).forEach(function(n){var r=e[n];r&&"object"==typeof r&&t.add(r)})});var n=e.loc;return n&&(delete n.startToken,delete n.endToken),e}function n1(e){var t=nZ(e);if(!nW.has(t)){var n=nH(e,{experimentalFragmentVariables:nq,allowLegacyFragmentVariables:nq});if(!n||"Document"!==n.kind)throw Error("Not a valid GraphQL document.");nW.set(t,nQ(nJ(n)))}return nW.get(t)}function n0(e){for(var t=[],n=1;n, or pass an ApolloClient instance in via options.'):(0,n7.kG)(!!n,32),n}var rb=n(10542),rm=n(53712),rg=n(21436),rv=Object.prototype.hasOwnProperty;function ry(e,t){return void 0===t&&(t=Object.create(null)),rw(rp(t.client),e).useQuery(t)}function rw(e,t){var n=(0,l.useRef)();n.current&&e===n.current.client&&t===n.current.query||(n.current=new r_(e,t,n.current));var r=n.current,i=(0,l.useState)(0),a=(i[0],i[1]);return r.forceUpdate=function(){a(function(e){return e+1})},r}var r_=function(){function e(e,t,n){this.client=e,this.query=t,this.ssrDisabledResult=(0,rb.J)({loading:!0,data:void 0,error:void 0,networkStatus:rc.I.loading}),this.skipStandbyResult=(0,rb.J)({loading:!1,data:void 0,error:void 0,networkStatus:rc.I.ready}),this.toQueryResultCache=new(re.mr?WeakMap:Map),rh(t,r.Query);var i=n&&n.result,a=i&&i.data;a&&(this.previousData=a)}return e.prototype.forceUpdate=function(){__DEV__&&n7.kG.warn("Calling default no-op implementation of InternalState#forceUpdate")},e.prototype.executeQuery=function(e){var t,n=this;e.query&&Object.assign(this,{query:e.query}),this.watchQueryOptions=this.createWatchQueryOptions(this.queryHookOptions=e);var r=this.observable.reobserveAsConcast(this.getObsQueryOptions());return this.previousData=(null===(t=this.result)||void 0===t?void 0:t.data)||this.previousData,this.result=void 0,this.forceUpdate(),new Promise(function(e){var t;r.subscribe({next:function(e){t=e},error:function(){e(n.toQueryResult(n.observable.getCurrentResult()))},complete:function(){e(n.toQueryResult(t))}})})},e.prototype.useQuery=function(e){var t=this;this.renderPromises=(0,l.useContext)((0,rs.K)()).renderPromises,this.useOptions(e);var n=this.useObservableQuery(),r=rn((0,l.useCallback)(function(){if(t.renderPromises)return function(){};var e=function(){var e=t.result,r=n.getCurrentResult();!(e&&e.loading===r.loading&&e.networkStatus===r.networkStatus&&(0,ra.D)(e.data,r.data))&&t.setResult(r)},r=function(a){var o=n.last;i.unsubscribe();try{n.resetLastResults(),i=n.subscribe(e,r)}finally{n.last=o}if(!rv.call(a,"graphQLErrors"))throw a;var s=t.result;(!s||s&&s.loading||!(0,ra.D)(a,s.error))&&t.setResult({data:s&&s.data,error:a,loading:!1,networkStatus:rc.I.error})},i=n.subscribe(e,r);return function(){return setTimeout(function(){return i.unsubscribe()})}},[n,this.renderPromises,this.client.disableNetworkFetches,]),function(){return t.getCurrentResult()},function(){return t.getCurrentResult()});return this.unsafeHandlePartialRefetch(r),this.toQueryResult(r)},e.prototype.useOptions=function(t){var n,r=this.createWatchQueryOptions(this.queryHookOptions=t),i=this.watchQueryOptions;!(0,ra.D)(r,i)&&(this.watchQueryOptions=r,i&&this.observable&&(this.observable.reobserve(this.getObsQueryOptions()),this.previousData=(null===(n=this.result)||void 0===n?void 0:n.data)||this.previousData,this.result=void 0)),this.onCompleted=t.onCompleted||e.prototype.onCompleted,this.onError=t.onError||e.prototype.onError,(this.renderPromises||this.client.disableNetworkFetches)&&!1===this.queryHookOptions.ssr&&!this.queryHookOptions.skip?this.result=this.ssrDisabledResult:this.queryHookOptions.skip||"standby"===this.watchQueryOptions.fetchPolicy?this.result=this.skipStandbyResult:(this.result===this.ssrDisabledResult||this.result===this.skipStandbyResult)&&(this.result=void 0)},e.prototype.getObsQueryOptions=function(){var e=[],t=this.client.defaultOptions.watchQuery;return t&&e.push(t),this.queryHookOptions.defaultOptions&&e.push(this.queryHookOptions.defaultOptions),e.push((0,rm.o)(this.observable&&this.observable.options,this.watchQueryOptions)),e.reduce(ro.J)},e.prototype.createWatchQueryOptions=function(e){void 0===e&&(e={});var t,n=e.skip,r=Object.assign((e.ssr,e.onCompleted,e.onError,e.defaultOptions,(0,n8._T)(e,["skip","ssr","onCompleted","onError","defaultOptions"])),{query:this.query});if(this.renderPromises&&("network-only"===r.fetchPolicy||"cache-and-network"===r.fetchPolicy)&&(r.fetchPolicy="cache-first"),r.variables||(r.variables={}),n){var i=r.fetchPolicy,a=void 0===i?this.getDefaultFetchPolicy():i,o=r.initialFetchPolicy;Object.assign(r,{initialFetchPolicy:void 0===o?a:o,fetchPolicy:"standby"})}else r.fetchPolicy||(r.fetchPolicy=(null===(t=this.observable)||void 0===t?void 0:t.options.initialFetchPolicy)||this.getDefaultFetchPolicy());return r},e.prototype.getDefaultFetchPolicy=function(){var e,t;return(null===(e=this.queryHookOptions.defaultOptions)||void 0===e?void 0:e.fetchPolicy)||(null===(t=this.client.defaultOptions.watchQuery)||void 0===t?void 0:t.fetchPolicy)||"cache-first"},e.prototype.onCompleted=function(e){},e.prototype.onError=function(e){},e.prototype.useObservableQuery=function(){var e=this.observable=this.renderPromises&&this.renderPromises.getSSRObservable(this.watchQueryOptions)||this.observable||this.client.watchQuery(this.getObsQueryOptions());this.obsQueryFields=(0,l.useMemo)(function(){return{refetch:e.refetch.bind(e),reobserve:e.reobserve.bind(e),fetchMore:e.fetchMore.bind(e),updateQuery:e.updateQuery.bind(e),startPolling:e.startPolling.bind(e),stopPolling:e.stopPolling.bind(e),subscribeToMore:e.subscribeToMore.bind(e)}},[e]);var t=!(!1===this.queryHookOptions.ssr||this.queryHookOptions.skip);return this.renderPromises&&t&&(this.renderPromises.registerSSRObservable(e),e.getCurrentResult().loading&&this.renderPromises.addObservableQueryPromise(e)),e},e.prototype.setResult=function(e){var t=this.result;t&&t.data&&(this.previousData=t.data),this.result=e,this.forceUpdate(),this.handleErrorOrCompleted(e)},e.prototype.handleErrorOrCompleted=function(e){var t=this;if(!e.loading){var n=this.toApolloError(e);Promise.resolve().then(function(){n?t.onError(n):e.data&&t.onCompleted(e.data)}).catch(function(e){__DEV__&&n7.kG.warn(e)})}},e.prototype.toApolloError=function(e){return(0,rg.O)(e.errors)?new ru.cA({graphQLErrors:e.errors}):e.error},e.prototype.getCurrentResult=function(){return this.result||this.handleErrorOrCompleted(this.result=this.observable.getCurrentResult()),this.result},e.prototype.toQueryResult=function(e){var t=this.toQueryResultCache.get(e);if(t)return t;var n=e.data,r=(e.partial,(0,n8._T)(e,["data","partial"]));return this.toQueryResultCache.set(e,t=(0,n8.pi)((0,n8.pi)((0,n8.pi)({data:n},r),this.obsQueryFields),{client:this.client,observable:this.observable,variables:this.observable.variables,called:!this.queryHookOptions.skip,previousData:this.previousData})),!t.error&&(0,rg.O)(e.errors)&&(t.error=new ru.cA({graphQLErrors:e.errors})),t},e.prototype.unsafeHandlePartialRefetch=function(e){e.partial&&this.queryHookOptions.partialRefetch&&!e.loading&&(!e.data||0===Object.keys(e.data).length)&&"cache-only"!==this.observable.options.fetchPolicy&&(Object.assign(e,{loading:!0,networkStatus:rc.I.refetch}),this.observable.refetch())},e}();function rE(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return ry(i$,e)},iG=function(){var e=iF(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"50",10),r=iz({variables:{offset:(t-1)*n,limit:n},fetchPolicy:"network-only"}),i=r.data,a=r.loading,o=r.error;return a?l.createElement(ij,null):o?l.createElement(iN,{error:o}):i?l.createElement(iD,{chains:i.chains.results,page:t,pageSize:n,total:i.chains.metadata.total}):null},iW=n(67932),iK=n(8126),iV="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function iq(e){if(iZ())return Intl.DateTimeFormat.supportedLocalesOf(e)[0]}function iZ(){return("undefined"==typeof Intl?"undefined":iV(Intl))==="object"&&"function"==typeof Intl.DateTimeFormat}var iX="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},iJ=function(){function e(e,t){for(var n=0;n=i.length)break;s=i[o++]}else{if((o=i.next()).done)break;s=o.value}var s,u=s;if((void 0===e?"undefined":iX(e))!=="object")return;e=e[u]}return e}},{key:"put",value:function(){for(var e=arguments.length,t=Array(e),n=0;n=o.length)break;c=o[u++]}else{if((u=o.next()).done)break;c=u.value}var c,l=c;"object"!==iX(a[l])&&(a[l]={}),a=a[l]}return a[i]=r}}]),e}();let i0=i1;var i2=new i0;function i3(e,t){if(!iZ())return function(e){return e.toString()};var n=i5(e),r=JSON.stringify(t),i=i2.get(String(n),r)||i2.put(String(n),r,new Intl.DateTimeFormat(n,t));return function(e){return i.format(e)}}var i4={};function i5(e){var t=e.toString();return i4[t]?i4[t]:i4[t]=iq(e)}var i6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i9(e){return i8(e)?e:new Date(e)}function i8(e){return e instanceof Date||i7(e)}function i7(e){return(void 0===e?"undefined":i6(e))==="object"&&"function"==typeof e.getTime}var ae=n(54087),at=n.n(ae);function an(e,t){if(0===e.length)return 0;for(var n=0,r=e.length-1,i=void 0;n<=r;){var a=t(e[i=Math.floor((r+n)/2)]);if(0===a)return i;if(a<0){if((n=i+1)>r)return n}else if((r=i-1)=t.nextUpdateTime)ao(t,this.instances);else break}},scheduleNextTick:function(){var e=this;this.scheduledTick=at()(function(){e.tick(),e.scheduleNextTick()})},start:function(){this.scheduleNextTick()},stop:function(){at().cancel(this.scheduledTick)}};function aa(e){var t=ar(e.getNextValue(),2),n=t[0],r=t[1];e.setValue(n),e.nextUpdateTime=r}function ao(e,t){aa(e),au(t,e),as(t,e)}function as(e,t){var n=ac(e,t);e.splice(n,0,t)}function au(e,t){var n=e.indexOf(t);e.splice(n,1)}function ac(e,t){var n=t.nextUpdateTime;return an(e,function(e){return e.nextUpdateTime===n?0:e.nextUpdateTime>n?1:-1})}var al=(0,ec.oneOfType)([(0,ec.shape)({minTime:ec.number,formatAs:ec.string.isRequired}),(0,ec.shape)({test:ec.func,formatAs:ec.string.isRequired}),(0,ec.shape)({minTime:ec.number,format:ec.func.isRequired}),(0,ec.shape)({test:ec.func,format:ec.func.isRequired})]),af=(0,ec.oneOfType)([ec.string,(0,ec.shape)({steps:(0,ec.arrayOf)(al).isRequired,labels:(0,ec.oneOfType)([ec.string,(0,ec.arrayOf)(ec.string)]).isRequired,round:ec.string})]),ad=Object.assign||function(e){for(var t=1;t=0)&&Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function ab(e){var t=e.date,n=e.future,r=e.timeStyle,i=e.round,a=e.minTimeLeft,o=e.tooltip,s=e.component,u=e.container,c=e.wrapperComponent,f=e.wrapperProps,d=e.locale,h=e.locales,p=e.formatVerboseDate,b=e.verboseDateFormat,m=e.updateInterval,g=e.tick,v=ap(e,["date","future","timeStyle","round","minTimeLeft","tooltip","component","container","wrapperComponent","wrapperProps","locale","locales","formatVerboseDate","verboseDateFormat","updateInterval","tick"]),y=(0,l.useMemo)(function(){return d&&(h=[d]),h.concat(iK.Z.getDefaultLocale())},[d,h]),w=(0,l.useMemo)(function(){return new iK.Z(y)},[y]);t=(0,l.useMemo)(function(){return i9(t)},[t]);var _=(0,l.useCallback)(function(){var e=Date.now(),o=void 0;if(n&&e>=t.getTime()&&(e=t.getTime(),o=!0),void 0!==a){var s=t.getTime()-1e3*a;e>s&&(e=s,o=!0)}var u=w.format(t,r,{getTimeToNextUpdate:!0,now:e,future:n,round:i}),c=ah(u,2),l=c[0],f=c[1];return f=o?av:m||f||6e4,[l,e+f]},[t,n,r,m,i,a,w]),E=(0,l.useRef)();E.current=_;var S=(0,l.useMemo)(_,[]),k=ah(S,2),x=k[0],T=k[1],M=(0,l.useState)(x),O=ah(M,2),A=O[0],L=O[1],C=ah((0,l.useState)(),2),I=C[0],D=C[1],N=(0,l.useRef)();(0,l.useEffect)(function(){if(g)return N.current=ai.add({getNextValue:function(){return E.current()},setValue:L,nextUpdateTime:T}),function(){return N.current.stop()}},[g]),(0,l.useEffect)(function(){if(N.current)N.current.forceUpdate();else{var e=_(),t=ah(e,1)[0];L(t)}},[_]),(0,l.useEffect)(function(){D(!0)},[]);var P=(0,l.useMemo)(function(){if("undefined"!=typeof window)return i3(y,b)},[y,b]),R=(0,l.useMemo)(function(){if("undefined"!=typeof window)return p?p(t):P(t)},[t,p,P]),j=l.createElement(s,ad({date:t,verboseDate:I?R:void 0,tooltip:o},v),A),F=c||u;return F?l.createElement(F,ad({},f,{verboseDate:I?R:void 0}),j):j}ab.propTypes={date:el().oneOfType([el().instanceOf(Date),el().number]).isRequired,locale:el().string,locales:el().arrayOf(el().string),future:el().bool,timeStyle:af,round:el().string,minTimeLeft:el().number,component:el().elementType.isRequired,tooltip:el().bool.isRequired,formatVerboseDate:el().func,verboseDateFormat:el().object,updateInterval:el().oneOfType([el().number,el().arrayOf(el().shape({threshold:el().number,interval:el().number.isRequired}))]),tick:el().bool,wrapperComponent:el().func,wrapperProps:el().object},ab.defaultProps={locales:[],component:ay,tooltip:!0,verboseDateFormat:{weekday:"long",day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"},tick:!0},ab=l.memo(ab);let am=ab;var ag,av=31536e9;function ay(e){var t=e.date,n=e.verboseDate,r=e.tooltip,i=e.children,a=ap(e,["date","verboseDate","tooltip","children"]),o=(0,l.useMemo)(function(){return t.toISOString()},[t]);return l.createElement("time",ad({},a,{dateTime:o,title:r?n:void 0}),i)}ay.propTypes={date:el().instanceOf(Date).isRequired,verboseDate:el().string,tooltip:el().bool.isRequired,children:el().string.isRequired};var aw=n(30381),a_=n.n(aw),aE=n(31657);function aS(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ak(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?new ru.cA({graphQLErrors:i}):void 0;if(u===s.current.mutationId&&!c.ignoreResults){var f={called:!0,loading:!1,data:r,error:l,client:a};s.current.isMounted&&!(0,ra.D)(s.current.result,f)&&o(s.current.result=f)}var d=e.onCompleted||(null===(n=s.current.options)||void 0===n?void 0:n.onCompleted);return null==d||d(t.data,c),t}).catch(function(t){if(u===s.current.mutationId&&s.current.isMounted){var n,r={loading:!1,error:t,data:void 0,called:!0,client:a};(0,ra.D)(s.current.result,r)||o(s.current.result=r)}var i=e.onError||(null===(n=s.current.options)||void 0===n?void 0:n.onError);if(i)return i(t,c),{data:void 0,errors:t};throw t})},[]),c=(0,l.useCallback)(function(){s.current.isMounted&&o({called:!1,loading:!1,client:n})},[]);return(0,l.useEffect)(function(){return s.current.isMounted=!0,function(){s.current.isMounted=!1}},[]),[u,(0,n8.pi)({reset:c},a)]}var ou=n(59067),oc=n(28428),ol=n(11186),of=n(78513);function od(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var oh=function(e){return(0,b.createStyles)({paper:{display:"flex",margin:"".concat(2.5*e.spacing.unit,"px 0"),padding:"".concat(3*e.spacing.unit,"px ").concat(3.5*e.spacing.unit,"px")},content:{flex:1,width:"100%"},actions:od({marginTop:-(1.5*e.spacing.unit),marginLeft:-(4*e.spacing.unit)},e.breakpoints.up("sm"),{marginLeft:0,marginRight:-(1.5*e.spacing.unit)}),itemBlock:{border:"1px solid rgba(224, 224, 224, 1)",borderRadius:e.shape.borderRadius,padding:2*e.spacing.unit,marginTop:e.spacing.unit},itemBlockText:{overflowWrap:"anywhere"}})},op=(0,b.withStyles)(oh)(function(e){var t=e.actions,n=e.children,r=e.classes;return l.createElement(ia.default,{className:r.paper},l.createElement("div",{className:r.content},n),t&&l.createElement("div",{className:r.actions},t))}),ob=function(e){var t=e.title;return l.createElement(x.default,{variant:"subtitle2",gutterBottom:!0},t)},om=function(e){var t=e.children,n=e.value;return l.createElement(x.default,{variant:"body1",noWrap:!0},t||n)},og=(0,b.withStyles)(oh)(function(e){var t=e.children,n=e.classes,r=e.value;return l.createElement("div",{className:n.itemBlock},l.createElement(x.default,{variant:"body1",className:n.itemBlockText},t||r))});function ov(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]-1}let sZ=sq;function sX(e,t){var n=this.__data__,r=s$(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}let sJ=sX;function sQ(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=cI}let cN=cD;var cP="[object Arguments]",cR="[object Array]",cj="[object Boolean]",cF="[object Date]",cY="[object Error]",cB="[object Function]",cU="[object Map]",cH="[object Number]",c$="[object Object]",cz="[object RegExp]",cG="[object Set]",cW="[object String]",cK="[object WeakMap]",cV="[object ArrayBuffer]",cq="[object DataView]",cZ="[object Float64Array]",cX="[object Int8Array]",cJ="[object Int16Array]",cQ="[object Int32Array]",c1="[object Uint8Array]",c0="[object Uint8ClampedArray]",c2="[object Uint16Array]",c3="[object Uint32Array]",c4={};function c5(e){return eD(e)&&cN(e.length)&&!!c4[eC(e)]}c4["[object Float32Array]"]=c4[cZ]=c4[cX]=c4[cJ]=c4[cQ]=c4[c1]=c4[c0]=c4[c2]=c4[c3]=!0,c4[cP]=c4[cR]=c4[cV]=c4[cj]=c4[cq]=c4[cF]=c4[cY]=c4[cB]=c4[cU]=c4[cH]=c4[c$]=c4[cz]=c4[cG]=c4[cW]=c4[cK]=!1;let c6=c5;function c9(e){return function(t){return e(t)}}let c8=c9;var c7=n(79730),le=c7.Z&&c7.Z.isTypedArray,lt=le?c8(le):c6;let ln=lt;var lr=Object.prototype.hasOwnProperty;function li(e,t){var n=cT(e),r=!n&&ck(e),i=!n&&!r&&(0,cM.Z)(e),a=!n&&!r&&!i&&ln(e),o=n||r||i||a,s=o?cm(e.length,String):[],u=s.length;for(var c in e)(t||lr.call(e,c))&&!(o&&("length"==c||i&&("offset"==c||"parent"==c)||a&&("buffer"==c||"byteLength"==c||"byteOffset"==c)||cC(c,u)))&&s.push(c);return s}let la=li;var lo=Object.prototype;function ls(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||lo)}let lu=ls;var lc=sM(Object.keys,Object);let ll=lc;var lf=Object.prototype.hasOwnProperty;function ld(e){if(!lu(e))return ll(e);var t=[];for(var n in Object(e))lf.call(e,n)&&"constructor"!=n&&t.push(n);return t}let lh=ld;function lp(e){return null!=e&&cN(e.length)&&!ui(e)}let lb=lp;function lm(e){return lb(e)?la(e):lh(e)}let lg=lm;function lv(e,t){return e&&cp(t,lg(t),e)}let ly=lv;function lw(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}let l_=lw;var lE=Object.prototype.hasOwnProperty;function lS(e){if(!ed(e))return l_(e);var t=lu(e),n=[];for(var r in e)"constructor"==r&&(t||!lE.call(e,r))||n.push(r);return n}let lk=lS;function lx(e){return lb(e)?la(e,!0):lk(e)}let lT=lx;function lM(e,t){return e&&cp(t,lT(t),e)}let lO=lM;var lA=n(42896);function lL(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n=0||(i[n]=e[n]);return i}function hc(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var hl=function(e){return Array.isArray(e)&&0===e.length},hf=function(e){return"function"==typeof e},hd=function(e){return null!==e&&"object"==typeof e},hh=function(e){return String(Math.floor(Number(e)))===e},hp=function(e){return"[object String]"===Object.prototype.toString.call(e)},hb=function(e){return 0===l.Children.count(e)},hm=function(e){return hd(e)&&hf(e.then)};function hg(e,t,n,r){void 0===r&&(r=0);for(var i=d8(t);e&&r=0?[]:{}}}return(0===a?e:i)[o[a]]===n?e:(void 0===n?delete i[o[a]]:i[o[a]]=n,0===a&&void 0===n&&delete r[o[a]],r)}function hy(e,t,n,r){void 0===n&&(n=new WeakMap),void 0===r&&(r={});for(var i=0,a=Object.keys(e);i0?t.map(function(t){return x(t,hg(e,t))}):[Promise.resolve("DO_NOT_DELETE_YOU_WILL_BE_FIRED")]).then(function(e){return e.reduce(function(e,n,r){return"DO_NOT_DELETE_YOU_WILL_BE_FIRED"===n||n&&(e=hv(e,t[r],n)),e},{})})},[x]),M=(0,l.useCallback)(function(e){return Promise.all([T(e),h.validationSchema?k(e):{},h.validate?S(e):{}]).then(function(e){var t=e[0],n=e[1],r=e[2];return sx.all([t,n,r],{arrayMerge:hC})})},[h.validate,h.validationSchema,T,S,k]),O=hP(function(e){return void 0===e&&(e=_.values),E({type:"SET_ISVALIDATING",payload:!0}),M(e).then(function(e){return v.current&&(E({type:"SET_ISVALIDATING",payload:!1}),sh()(_.errors,e)||E({type:"SET_ERRORS",payload:e})),e})});(0,l.useEffect)(function(){o&&!0===v.current&&sh()(p.current,h.initialValues)&&O(p.current)},[o,O]);var A=(0,l.useCallback)(function(e){var t=e&&e.values?e.values:p.current,n=e&&e.errors?e.errors:b.current?b.current:h.initialErrors||{},r=e&&e.touched?e.touched:m.current?m.current:h.initialTouched||{},i=e&&e.status?e.status:g.current?g.current:h.initialStatus;p.current=t,b.current=n,m.current=r,g.current=i;var a=function(){E({type:"RESET_FORM",payload:{isSubmitting:!!e&&!!e.isSubmitting,errors:n,touched:r,status:i,values:t,isValidating:!!e&&!!e.isValidating,submitCount:e&&e.submitCount&&"number"==typeof e.submitCount?e.submitCount:0}})};if(h.onReset){var o=h.onReset(_.values,V);hm(o)?o.then(a):a()}else a()},[h.initialErrors,h.initialStatus,h.initialTouched]);(0,l.useEffect)(function(){!0===v.current&&!sh()(p.current,h.initialValues)&&(c&&(p.current=h.initialValues,A()),o&&O(p.current))},[c,h.initialValues,A,o,O]),(0,l.useEffect)(function(){c&&!0===v.current&&!sh()(b.current,h.initialErrors)&&(b.current=h.initialErrors||hk,E({type:"SET_ERRORS",payload:h.initialErrors||hk}))},[c,h.initialErrors]),(0,l.useEffect)(function(){c&&!0===v.current&&!sh()(m.current,h.initialTouched)&&(m.current=h.initialTouched||hx,E({type:"SET_TOUCHED",payload:h.initialTouched||hx}))},[c,h.initialTouched]),(0,l.useEffect)(function(){c&&!0===v.current&&!sh()(g.current,h.initialStatus)&&(g.current=h.initialStatus,E({type:"SET_STATUS",payload:h.initialStatus}))},[c,h.initialStatus,h.initialTouched]);var L=hP(function(e){if(y.current[e]&&hf(y.current[e].validate)){var t=hg(_.values,e),n=y.current[e].validate(t);return hm(n)?(E({type:"SET_ISVALIDATING",payload:!0}),n.then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}}),E({type:"SET_ISVALIDATING",payload:!1})})):(E({type:"SET_FIELD_ERROR",payload:{field:e,value:n}}),Promise.resolve(n))}return h.validationSchema?(E({type:"SET_ISVALIDATING",payload:!0}),k(_.values,e).then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t[e]}}),E({type:"SET_ISVALIDATING",payload:!1})})):Promise.resolve()}),C=(0,l.useCallback)(function(e,t){var n=t.validate;y.current[e]={validate:n}},[]),I=(0,l.useCallback)(function(e){delete y.current[e]},[]),D=hP(function(e,t){return E({type:"SET_TOUCHED",payload:e}),(void 0===t?i:t)?O(_.values):Promise.resolve()}),N=(0,l.useCallback)(function(e){E({type:"SET_ERRORS",payload:e})},[]),P=hP(function(e,t){var r=hf(e)?e(_.values):e;return E({type:"SET_VALUES",payload:r}),(void 0===t?n:t)?O(r):Promise.resolve()}),R=(0,l.useCallback)(function(e,t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}})},[]),j=hP(function(e,t,r){return E({type:"SET_FIELD_VALUE",payload:{field:e,value:t}}),(void 0===r?n:r)?O(hv(_.values,e,t)):Promise.resolve()}),F=(0,l.useCallback)(function(e,t){var n,r=t,i=e;if(!hp(e)){e.persist&&e.persist();var a=e.target?e.target:e.currentTarget,o=a.type,s=a.name,u=a.id,c=a.value,l=a.checked,f=(a.outerHTML,a.options),d=a.multiple;r=t||s||u,i=/number|range/.test(o)?(n=parseFloat(c),isNaN(n)?"":n):/checkbox/.test(o)?hD(hg(_.values,r),l,c):d?hI(f):c}r&&j(r,i)},[j,_.values]),Y=hP(function(e){if(hp(e))return function(t){return F(t,e)};F(e)}),B=hP(function(e,t,n){return void 0===t&&(t=!0),E({type:"SET_FIELD_TOUCHED",payload:{field:e,value:t}}),(void 0===n?i:n)?O(_.values):Promise.resolve()}),U=(0,l.useCallback)(function(e,t){e.persist&&e.persist();var n,r=e.target,i=r.name,a=r.id;r.outerHTML,B(t||i||a,!0)},[B]),H=hP(function(e){if(hp(e))return function(t){return U(t,e)};U(e)}),$=(0,l.useCallback)(function(e){hf(e)?E({type:"SET_FORMIK_STATE",payload:e}):E({type:"SET_FORMIK_STATE",payload:function(){return e}})},[]),z=(0,l.useCallback)(function(e){E({type:"SET_STATUS",payload:e})},[]),G=(0,l.useCallback)(function(e){E({type:"SET_ISSUBMITTING",payload:e})},[]),W=hP(function(){return E({type:"SUBMIT_ATTEMPT"}),O().then(function(e){var t,n=e instanceof Error;if(!n&&0===Object.keys(e).length){try{if(void 0===(t=q()))return}catch(r){throw r}return Promise.resolve(t).then(function(e){return v.current&&E({type:"SUBMIT_SUCCESS"}),e}).catch(function(e){if(v.current)throw E({type:"SUBMIT_FAILURE"}),e})}if(v.current&&(E({type:"SUBMIT_FAILURE"}),n))throw e})}),K=hP(function(e){e&&e.preventDefault&&hf(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hf(e.stopPropagation)&&e.stopPropagation(),W().catch(function(e){console.warn("Warning: An unhandled error was caught from submitForm()",e)})}),V={resetForm:A,validateForm:O,validateField:L,setErrors:N,setFieldError:R,setFieldTouched:B,setFieldValue:j,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,setFormikState:$,submitForm:W},q=hP(function(){return f(_.values,V)}),Z=hP(function(e){e&&e.preventDefault&&hf(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hf(e.stopPropagation)&&e.stopPropagation(),A()}),X=(0,l.useCallback)(function(e){return{value:hg(_.values,e),error:hg(_.errors,e),touched:!!hg(_.touched,e),initialValue:hg(p.current,e),initialTouched:!!hg(m.current,e),initialError:hg(b.current,e)}},[_.errors,_.touched,_.values]),J=(0,l.useCallback)(function(e){return{setValue:function(t,n){return j(e,t,n)},setTouched:function(t,n){return B(e,t,n)},setError:function(t){return R(e,t)}}},[j,B,R]),Q=(0,l.useCallback)(function(e){var t=hd(e),n=t?e.name:e,r=hg(_.values,n),i={name:n,value:r,onChange:Y,onBlur:H};if(t){var a=e.type,o=e.value,s=e.as,u=e.multiple;"checkbox"===a?void 0===o?i.checked=!!r:(i.checked=!!(Array.isArray(r)&&~r.indexOf(o)),i.value=o):"radio"===a?(i.checked=r===o,i.value=o):"select"===s&&u&&(i.value=i.value||[],i.multiple=!0)}return i},[H,Y,_.values]),ee=(0,l.useMemo)(function(){return!sh()(p.current,_.values)},[p.current,_.values]),et=(0,l.useMemo)(function(){return void 0!==s?ee?_.errors&&0===Object.keys(_.errors).length:!1!==s&&hf(s)?s(h):s:_.errors&&0===Object.keys(_.errors).length},[s,ee,_.errors,h]);return ho({},_,{initialValues:p.current,initialErrors:b.current,initialTouched:m.current,initialStatus:g.current,handleBlur:H,handleChange:Y,handleReset:Z,handleSubmit:K,resetForm:A,setErrors:N,setFormikState:$,setFieldTouched:B,setFieldValue:j,setFieldError:R,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,submitForm:W,validateForm:O,validateField:L,isValid:et,dirty:ee,unregisterField:I,registerField:C,getFieldProps:Q,getFieldMeta:X,getFieldHelpers:J,validateOnBlur:i,validateOnChange:n,validateOnMount:o})}function hM(e){var t=hT(e),n=e.component,r=e.children,i=e.render,a=e.innerRef;return(0,l.useImperativeHandle)(a,function(){return t}),(0,l.createElement)(h_,{value:t},n?(0,l.createElement)(n,t):i?i(t):r?hf(r)?r(t):hb(r)?null:l.Children.only(r):null)}function hO(e){var t={};if(e.inner){if(0===e.inner.length)return hv(t,e.path,e.message);for(var n=e.inner,r=Array.isArray(n),i=0,n=r?n:n[Symbol.iterator]();;){if(r){if(i>=n.length)break;a=n[i++]}else{if((i=n.next()).done)break;a=i.value}var a,o=a;hg(t,o.path)||(t=hv(t,o.path,o.message))}}return t}function hA(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r={});var i=hL(e);return t[n?"validateSync":"validate"](i,{abortEarly:!1,context:r})}function hL(e){var t=Array.isArray(e)?[]:{};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=String(n);!0===Array.isArray(e[r])?t[r]=e[r].map(function(e){return!0===Array.isArray(e)||sj(e)?hL(e):""!==e?e:void 0}):sj(e[r])?t[r]=hL(e[r]):t[r]=""!==e[r]?e[r]:void 0}return t}function hC(e,t,n){var r=e.slice();return t.forEach(function(t,i){if(void 0===r[i]){var a=!1!==n.clone&&n.isMergeableObject(t);r[i]=a?sx(Array.isArray(t)?[]:{},t,n):t}else n.isMergeableObject(t)?r[i]=sx(e[i],t,n):-1===e.indexOf(t)&&r.push(t)}),r}function hI(e){return Array.from(e).filter(function(e){return e.selected}).map(function(e){return e.value})}function hD(e,t,n){if("boolean"==typeof e)return Boolean(t);var r=[],i=!1,a=-1;if(Array.isArray(e))r=e,i=(a=e.indexOf(n))>=0;else if(!n||"true"==n||"false"==n)return Boolean(t);return t&&n&&!i?r.concat(n):i?r.slice(0,a).concat(r.slice(a+1)):r}var hN="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?l.useLayoutEffect:l.useEffect;function hP(e){var t=(0,l.useRef)(e);return hN(function(){t.current=e}),(0,l.useCallback)(function(){for(var e=arguments.length,n=Array(e),r=0;re?t:e},0);return Array.from(ho({},e,{length:t+1}))};(function(e){function t(t){var n;return(n=e.call(this,t)||this).updateArrayField=function(e,t,r){var i=n.props,a=i.name;(0,i.formik.setFormikState)(function(n){var i="function"==typeof r?r:e,o="function"==typeof t?t:e,s=hv(n.values,a,e(hg(n.values,a))),u=r?i(hg(n.errors,a)):void 0,c=t?o(hg(n.touched,a)):void 0;return hl(u)&&(u=void 0),hl(c)&&(c=void 0),ho({},n,{values:s,errors:r?hv(n.errors,a,u):n.errors,touched:t?hv(n.touched,a,c):n.touched})})},n.push=function(e){return n.updateArrayField(function(t){return[].concat(hH(t),[ha(e)])},!1,!1)},n.handlePush=function(e){return function(){return n.push(e)}},n.swap=function(e,t){return n.updateArrayField(function(n){return hY(n,e,t)},!0,!0)},n.handleSwap=function(e,t){return function(){return n.swap(e,t)}},n.move=function(e,t){return n.updateArrayField(function(n){return hF(n,e,t)},!0,!0)},n.handleMove=function(e,t){return function(){return n.move(e,t)}},n.insert=function(e,t){return n.updateArrayField(function(n){return hB(n,e,t)},function(t){return hB(t,e,null)},function(t){return hB(t,e,null)})},n.handleInsert=function(e,t){return function(){return n.insert(e,t)}},n.replace=function(e,t){return n.updateArrayField(function(n){return hU(n,e,t)},!1,!1)},n.handleReplace=function(e,t){return function(){return n.replace(e,t)}},n.unshift=function(e){var t=-1;return n.updateArrayField(function(n){var r=n?[e].concat(n):[e];return t<0&&(t=r.length),r},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n}),t},n.handleUnshift=function(e){return function(){return n.unshift(e)}},n.handleRemove=function(e){return function(){return n.remove(e)}},n.handlePop=function(){return function(){return n.pop()}},n.remove=n.remove.bind(hc(n)),n.pop=n.pop.bind(hc(n)),n}hs(t,e);var n=t.prototype;return n.componentDidUpdate=function(e){this.props.validateOnChange&&this.props.formik.validateOnChange&&!sh()(hg(e.formik.values,e.name),hg(this.props.formik.values,this.props.name))&&this.props.formik.validateForm(this.props.formik.values)},n.remove=function(e){var t;return this.updateArrayField(function(n){var r=n?hH(n):[];return t||(t=r[e]),hf(r.splice)&&r.splice(e,1),r},!0,!0),t},n.pop=function(){var e;return this.updateArrayField(function(t){var n=t;return e||(e=n&&n.pop&&n.pop()),n},!0,!0),e},n.render=function(){var e={push:this.push,pop:this.pop,swap:this.swap,move:this.move,insert:this.insert,replace:this.replace,unshift:this.unshift,remove:this.remove,handlePush:this.handlePush,handlePop:this.handlePop,handleSwap:this.handleSwap,handleMove:this.handleMove,handleInsert:this.handleInsert,handleReplace:this.handleReplace,handleUnshift:this.handleUnshift,handleRemove:this.handleRemove},t=this.props,n=t.component,r=t.render,i=t.children,a=t.name,o=hu(t.formik,["validate","validationSchema"]),s=ho({},e,{form:o,name:a});return n?(0,l.createElement)(n,s):r?r(s):i?"function"==typeof i?i(s):hb(i)?null:l.Children.only(i):null},t})(l.Component).defaultProps={validateOnChange:!0},l.Component,l.Component;var h$=n(24802),hz=n(71209),hG=n(91750),hW=n(11970),hK=n(4689),hV=n(67598),hq=function(){return(hq=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&(n[r[i]]=e[r[i]]);return n}function hX(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form,o=a.isSubmitting,s=a.touched,u=a.errors,c=e.onBlur,l=e.helperText,f=hZ(e,["disabled","field","form","onBlur","helperText"]),d=hg(u,i.name),h=hg(s,i.name)&&!!d;return hq(hq({variant:f.variant,error:h,helperText:h?d:l,disabled:null!=t?t:o,onBlur:null!=c?c:function(e){r(null!=e?e:i.name)}},i),f)}function hJ(e){var t=e.children,n=hZ(e,["children"]);return(0,l.createElement)(i_.Z,hq({},hX(n)),t)}function hQ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form.isSubmitting,o=(e.type,e.onBlur),s=hZ(e,["disabled","field","form","type","onBlur"]);return hq(hq({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h1(e){return(0,l.createElement)(h$.Z,hq({},hQ(e)))}function h0(e){var t,n=e.disabled,r=e.field,i=r.onBlur,a=hZ(r,["onBlur"]),o=e.form.isSubmitting,s=(e.type,e.onBlur),u=hZ(e,["disabled","field","form","type","onBlur"]);return hq(hq({disabled:null!=n?n:o,indeterminate:!Array.isArray(a.value)&&null==a.value,onBlur:null!=s?s:function(e){i(null!=e?e:a.name)}},a),u)}function h2(e){return(0,l.createElement)(hz.Z,hq({},h0(e)))}function h3(e){var t=e.Label,n=hZ(e,["Label"]);return(0,l.createElement)(hG.Z,hq({control:(0,l.createElement)(hz.Z,hq({},h0(n)))},t))}function h4(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hZ(e,["disabled","field","form","onBlur"]);return hq(hq({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h5(e){return(0,l.createElement)(hW.default,hq({},h4(e)))}function h6(e){var t=e.field,n=t.onBlur,r=hZ(t,["onBlur"]),i=(e.form,e.onBlur),a=hZ(e,["field","form","onBlur"]);return hq(hq({onBlur:null!=i?i:function(e){n(null!=e?e:r.name)}},r),a)}function h9(e){return(0,l.createElement)(hK.Z,hq({},h6(e)))}function h8(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hZ(e,["disabled","field","form","onBlur"]);return hq(hq({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h7(e){return(0,l.createElement)(hV.default,hq({},h8(e)))}hJ.displayName="FormikMaterialUITextField",h1.displayName="FormikMaterialUISwitch",h2.displayName="FormikMaterialUICheckbox",h3.displayName="FormikMaterialUICheckboxWithLabel",h5.displayName="FormikMaterialUISelect",h9.displayName="FormikMaterialUIRadioGroup",h7.displayName="FormikMaterialUIInputBase";try{a=Map}catch(pe){}try{o=Set}catch(pt){}function pn(e,t,n){if(!e||"object"!=typeof e||"function"==typeof e)return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return RegExp(e);if(Array.isArray(e))return e.map(pr);if(a&&e instanceof a)return new Map(Array.from(e.entries()));if(o&&e instanceof o)return new Set(Array.from(e.values()));if(e instanceof Object){t.push(e);var r=Object.create(e);for(var i in n.push(r),e){var s=t.findIndex(function(t){return t===e[i]});r[i]=s>-1?n[s]:pn(e[i],t,n)}return r}return e}function pr(e){return pn(e,[],[])}let pi=Object.prototype.toString,pa=Error.prototype.toString,po=RegExp.prototype.toString,ps="undefined"!=typeof Symbol?Symbol.prototype.toString:()=>"",pu=/^Symbol\((.*)\)(.*)$/;function pc(e){if(e!=+e)return"NaN";let t=0===e&&1/e<0;return t?"-0":""+e}function pl(e,t=!1){if(null==e||!0===e||!1===e)return""+e;let n=typeof e;if("number"===n)return pc(e);if("string"===n)return t?`"${e}"`:e;if("function"===n)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===n)return ps.call(e).replace(pu,"Symbol($1)");let r=pi.call(e).slice(8,-1);return"Date"===r?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===r||e instanceof Error?"["+pa.call(e)+"]":"RegExp"===r?po.call(e):null}function pf(e,t){let n=pl(e,t);return null!==n?n:JSON.stringify(e,function(e,n){let r=pl(this[e],t);return null!==r?r:n},2)}let pd={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType({path:e,type:t,value:n,originalValue:r}){let i=null!=r&&r!==n,a=`${e} must be a \`${t}\` type, but the final value was: \`${pf(n,!0)}\``+(i?` (cast from the value \`${pf(r,!0)}\`).`:".");return null===n&&(a+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),a},defined:"${path} must be defined"},ph={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"},pp={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"},pb={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"},pm={isValue:"${path} field must be ${value}"},pg={noUnknown:"${path} field has unspecified keys: ${unknown}"},pv={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};Object.assign(Object.create(null),{mixed:pd,string:ph,number:pp,date:pb,object:pg,array:pv,boolean:pm});var py=n(18721),pw=n.n(py);let p_=e=>e&&e.__isYupSchema__;class pE{constructor(e,t){if(this.refs=e,this.refs=e,"function"==typeof t){this.fn=t;return}if(!pw()(t,"is"))throw TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:n,then:r,otherwise:i}=t,a="function"==typeof n?n:(...e)=>e.every(e=>e===n);this.fn=function(...e){let t=e.pop(),n=e.pop(),o=a(...e)?r:i;if(o)return"function"==typeof o?o(n):n.concat(o.resolve(t))}}resolve(e,t){let n=this.refs.map(e=>e.getValue(null==t?void 0:t.value,null==t?void 0:t.parent,null==t?void 0:t.context)),r=this.fn.apply(e,n.concat(e,t));if(void 0===r||r===e)return e;if(!p_(r))throw TypeError("conditions must return a schema object");return r.resolve(t)}}let pS=pE;function pk(e){return null==e?[]:[].concat(e)}function px(){return(px=Object.assign||function(e){for(var t=1;tpf(t[n])):"function"==typeof e?e(t):e}static isError(e){return e&&"ValidationError"===e.name}constructor(e,t,n,r){super(),this.name="ValidationError",this.value=t,this.path=n,this.type=r,this.errors=[],this.inner=[],pk(e).forEach(e=>{pM.isError(e)?(this.errors.push(...e.errors),this.inner=this.inner.concat(e.inner.length?e.inner:e)):this.errors.push(e)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,pM)}}let pO=e=>{let t=!1;return(...n)=>{t||(t=!0,e(...n))}};function pA(e,t){let{endEarly:n,tests:r,args:i,value:a,errors:o,sort:s,path:u}=e,c=pO(t),l=r.length,f=[];if(o=o||[],!l)return o.length?c(new pM(o,a,u)):c(null,a);for(let d=0;d=0||(i[n]=e[n]);return i}function pj(e){function t(t,n){let{value:r,path:i="",label:a,options:o,originalValue:s,sync:u}=t,c=pR(t,["value","path","label","options","originalValue","sync"]),{name:l,test:f,params:d,message:h}=e,{parent:p,context:b}=o;function m(e){return pN.isRef(e)?e.getValue(r,p,b):e}function g(e={}){let t=pC()(pP({value:r,originalValue:s,label:a,path:e.path||i},d,e.params),m),n=new pM(pM.formatError(e.message||h,t),r,t.path,e.type||l);return n.params=t,n}let v=pP({path:i,parent:p,type:l,createError:g,resolve:m,options:o,originalValue:s},c);if(!u){try{Promise.resolve(f.call(v,r,v)).then(e=>{pM.isError(e)?n(e):e?n(null,e):n(g())})}catch(y){n(y)}return}let w;try{var _;if(w=f.call(v,r,v),"function"==typeof(null==(_=w)?void 0:_.then))throw Error(`Validation test of type: "${v.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(E){n(E);return}pM.isError(w)?n(w):w?n(null,w):n(g())}return t.OPTIONS=e,t}pN.prototype.__isYupRef=!0;let pF=e=>e.substr(0,e.length-1).substr(1);function pY(e,t,n,r=n){let i,a,o;return t?((0,pI.forEach)(t,(s,u,c)=>{let l=u?pF(s):s;if((e=e.resolve({context:r,parent:i,value:n})).innerType){let f=c?parseInt(l,10):0;if(n&&f>=n.length)throw Error(`Yup.reach cannot resolve an array item at index: ${s}, in the path: ${t}. because there is no value at that index. `);i=n,n=n&&n[f],e=e.innerType}if(!c){if(!e.fields||!e.fields[l])throw Error(`The schema does not contain the path: ${t}. (failed at: ${o} which is a type: "${e._type}")`);i=n,n=n&&n[l],e=e.fields[l]}a=l,o=u?"["+s+"]":"."+s}),{schema:e,parent:i,parentPath:a}):{parent:i,parentPath:t,schema:e}}class pB{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,n]of this.refs)e.push(n.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){pN.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){pN.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let n,r=this.refs.values();for(;!(n=r.next()).done;)if(t(n.value)===e)return!0;return!1}clone(){let e=new pB;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let n=this.clone();return e.list.forEach(e=>n.add(e)),e.refs.forEach(e=>n.add(e)),t.list.forEach(e=>n.delete(e)),t.refs.forEach(e=>n.delete(e)),n}}function pU(){return(pU=Object.assign||function(e){for(var t=1;t{this.typeError(pd.notType)}),this.type=(null==e?void 0:e.type)||"mixed",this.spec=pU({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},null==e?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=pU({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=pr(pU({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(0===e.length)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let n=e(this);return this._mutate=t,n}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&"mixed"!==this.type)throw TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,n=e.clone(),r=pU({},t.spec,n.spec);return n.spec=r,n._typeError||(n._typeError=t._typeError),n._whitelistError||(n._whitelistError=t._whitelistError),n._blacklistError||(n._blacklistError=t._blacklistError),n._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),n._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),n.tests=t.tests,n.exclusiveTests=t.exclusiveTests,n.withMutation(t=>{e.tests.forEach(e=>{t.test(e.OPTIONS)})}),n}isType(e){return!!this.spec.nullable&&null===e||this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let n=t.conditions;(t=t.clone()).conditions=[],t=(t=n.reduce((t,n)=>n.resolve(t,e),t)).resolve(e)}return t}cast(e,t={}){let n=this.resolve(pU({value:e},t)),r=n._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==n.isType(r)){let i=pf(e),a=pf(r);throw TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${n._type}". attempted value: ${i} -`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pU({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pA({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pA({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pU({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pU({},t,{value:e}))._validate(e,pU({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pM.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pM.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pr(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pd.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pd.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pd.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pj(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pk(e).map(e=>new pN(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pS(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pj({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pd.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pj({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pd.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pj({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let p$ of(pH.prototype.__isYupSchema__=!0,["validate","validateSync"]))pH.prototype[`${p$}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pY(this,e,t,n.context);return a[p$](r&&r[i],pU({},n,{parent:r,path:e}))};for(let pz of["equals","is"])pH.prototype[pz]=pH.prototype.oneOf;for(let pG of["not","nope"])pH.prototype[pG]=pH.prototype.notOneOf;pH.prototype.optional=pH.prototype.notRequired;let pW=pH;function pK(){return new pW}pK.prototype=pW.prototype;let pV=e=>null==e;function pq(){return new pZ}class pZ extends pH{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pV(e)||!0===e})}isFalse(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pV(e)||!1===e})}}pq.prototype=pZ.prototype;let pX=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pJ=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pQ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,p1=e=>pV(e)||e===e.trim(),p0=({}).toString();function p2(){return new p3}class p3 extends pH{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p0?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=ph.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t=ph.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||ph.matches,params:{regex:e},test:t=>pV(t)||""===t&&n||-1!==t.search(e)})}email(e=ph.email){return this.matches(pX,{name:"email",message:e,excludeEmptyString:!0})}url(e=ph.url){return this.matches(pJ,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=ph.uuid){return this.matches(pQ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=ph.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:p1})}lowercase(e=ph.lowercase){return this.transform(e=>pV(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toLowerCase()})}uppercase(e=ph.uppercase){return this.transform(e=>pV(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toUpperCase()})}}p2.prototype=p3.prototype;let p4=e=>e!=+e;function p5(){return new p6}class p6 extends pH{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p4(e)}min(e,t=pp.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t>=this.resolve(e)}})}max(e,t=pp.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t<=this.resolve(e)}})}lessThan(e,t=pp.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pV(t)||tthis.resolve(e)}})}positive(e=pp.positive){return this.moreThan(0,e)}negative(e=pp.negative){return this.lessThan(0,e)}integer(e=pp.integer){return this.test({name:"integer",message:e,test:e=>pV(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pV(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pV(t)?t:Math[e](t))}}p5.prototype=p6.prototype;var p9=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p9.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p7=new Date(""),be=e=>"[object Date]"===Object.prototype.toString.call(e);function bt(){return new bn}class bn extends pH{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p7:new Date(e))})})}_typeCheck(e){return be(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pN.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pb.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pV(e)||e>=this.resolve(n)}})}max(e,t=pb.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pV(e)||e<=this.resolve(n)}})}}bn.INVALID_DATE=p7,bt.prototype=bn.prototype,bt.INVALID_DATE=p7;var br=n(11865),bi=n.n(br),ba=n(68929),bo=n.n(ba),bs=n(67523),bu=n.n(bs),bc=n(94633),bl=n.n(bc);function bf(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pI.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(pw()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pN.isRef(o)&&o.isSibling?i(o.path,a):p_(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bl().array(r,n).reverse()}function bd(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bh(e){return(t,n)=>bd(e,t)-bd(e,n)}function bp(){return(bp=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bm(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bg=bh([]);class bv extends pH{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bg,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bb(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bp({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=pw()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pM.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bb(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bp({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pA({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bp({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pH&&i instanceof pH&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bh(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bf(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pI.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return pw()(i,e)&&(a=bp({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pg.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bm(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pg.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bu()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(bo())}snakeCase(){return this.transformKeys(bi())}constantCase(){return this.transformKeys(e=>bi()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pC()(this.fields,e=>e.describe()),e}}function by(e){return new bv(e)}function bw(){return(bw=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,bw({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pM.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pA({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!p_(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pf(e));return t.innerType=e,t}length(e,t=pv.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pv.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pv.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}b_.prototype=bE.prototype;var bS=by().shape({name:p2().required("Required"),url:p2().required("Required")}),bk=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hM,{initialValues:t,validationSchema:bS,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hj,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bx=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Bridge",action:l.createElement(aL.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aK.Z,null,l.createElement(bk,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bT(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},ml=n(76023);function mf(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0||(i[n]=e[n]);return i}function mB(e,t){if(null==e)return{};var n,r,i=mY(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mU(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mX={};function mJ(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mX[t]||(mX[t]=mZ(e)),mX[t]}function mQ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mJ(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mV({},e,n[t])},t)}function m1(e){return e.join(" ")}function m0(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m2({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m2(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m0(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mV({},s,{className:m1(m)||void 0,style:mQ(s.className,Object.assign({},s.style,i),n)})}else d=mV({},s,{className:m1(s.className)});var g=h(t.children);return l.createElement(c,mq({key:o},d),g)}}let m3=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m4=/\n/g;function m5(e){return e.match(m4)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m9(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m7(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function ge(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mV({},i,"function"==typeof e?e(t):e)}function gt(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=ge(r,n,i);t.unshift(m7(n,h))}return f&l&&(d.style=mV({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gn(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return gt({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=ge(s,t,o);e.unshift(m7(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m5(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(gt({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=gt({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gc=n(98695),gl=n.n(gc);let gf=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gd=gs(gl(),gu);gd.supportedLanguages=gf;let gh=gd;var gp=n(64566);function gb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gm(){var e=gb(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gm=function(){return e},e}var gg=n0(gm()),gv=function(e){var t=e.children;return l.createElement(ii.Z,null,l.createElement(ie.default,{component:"th",scope:"row",colSpan:3},t))},gy=function(){return l.createElement(gv,null,"...")},gw=function(e){var t=e.children;return l.createElement(gv,null,t)},g_=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gw,null,i);if(t)return l.createElement(gy,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mR.Z,{defaultExpanded:o},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},a),l.createElement(mF.Z,{style:s},l.createElement(gh,{language:"toml",style:gu},n))))},gE=function(){var e=ry(gg,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(g_,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gS=n(34823),gk=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gx=(0,b.withStyles)(gk)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gS.N,A.wU);return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r7.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gT=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(gE,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gx,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mP,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mS,null))))))},gM=function(){return l.createElement(gT,null)},gO=function(){return l.createElement(gM,null)},gA=n(44431),gL=1e18,gC=function(e){return new gA.BigNumber(e).dividedBy(gL).toFixed(8)},gI=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sf.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aK.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ob,{title:"Address"}),l.createElement(om,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"Native Token Balance"}),l.createElement(om,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"LINK Balance"}),l.createElement(om,{value:e.linkBalance?gC(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gU.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:r.footer},l.createElement(aL.Z,{href:"/runs",component:tz},"View More"))))))});function vn(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vr(){var e=vn(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vr=function(){return e},e}var vi=5,va=n0(vr(),g7),vo=function(){var e=ry(va,{variables:{offset:0,limit:vi},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vt,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vi})},vs=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vu=(0,b.withStyles)(vs)(function(e){var t=e.classes,n=(0,A.v9)(gS.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ia.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vc=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vl=(0,b.withStyles)(vc)(function(e){var t=e.classes,n=e.job;return l.createElement(ii.Z,null,l.createElement(ie.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ip,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aA,{tooltip:!0},n.createdAt))))))});function vf(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vd(){var e=vf(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vd=function(){return e},e}var vh=n0(vd()),vp=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vb=(0,b.withStyles)(vp)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gH,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vl,{job:e,key:t})}))))});function vm(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vg(){var e=vm(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vg=function(){return e},e}var vv=5,vy=n0(vg(),vh),vw=function(){var e=ry(vy,{variables:{offset:0,limit:vv},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vb,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},v_=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(vo,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gB,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vw,null))))),l.createElement(vu,null))},vE=function(){return l.createElement(v_,null)},vS=function(){return l.createElement(vE,null)},vk=n(87239),vx=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vT=n(5022),vM=n(78718),vO=n.n(vM);function vA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ii.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(ie.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(ie.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aA,{tooltip:!0},e.createdAt))),l.createElement(ie.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yp(t,e.status))},e.status.toLowerCase())))})))}),ym=n(16839),yg=n.n(ym);function yv(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=yg().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yy=n(94164),yw=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},y_=n(73343),yE=n(3379),yS=n.n(yE);function yk(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yy.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:y_.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yw,{data:e}))}))};function yC(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyB&&l.createElement("div",{className:t.runDetails},l.createElement(aL.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yY,{observationSource:n.observationSource})))});function y$(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vT.parse(e),!0}catch(t){return!1}})}),wK=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hM,{initialValues:t,validationSchema:wW,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hj,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hR,{component:hJ,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wV=n(50109),wq="persistSpec";function wZ(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wV.t8(wq,n),{toml:n}):{toml:wV.U2(wq)||""}}var wX=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wZ({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wV.t8("".concat(wq),t),n&&n(t)};return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"New Job"}),l.createElement(aK.Z,null,l.createElement(wK,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _O(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(_K,e)},_q=function(){var e=_V({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_H,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_Z=function(e){var t=e.csaKey;return l.createElement(ii.Z,{hover:!0},l.createElement(ie.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_T,{data:t.publicKey}))))};function _X(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _J(){var e=_X(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _J=function(){return e},e}var _Q=n0(_J()),_1=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r9.Z,null,l.createElement(sf.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ox.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(it.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,null,"Public Key"))),l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gH,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_Z,{csaKey:e,key:t})}))))};function _0(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EO,e)};function EL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EQ,e)},E4=function(){return os(E1)},E5=function(){return os(E0)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return ry(E2,e)};function E9(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(SV,e)};function SZ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kq(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kZ=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kV(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kK(kG({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r9.Z,null,l.createElement(aK.Z,null,l.createElement(k$,{object:n})))};function kX(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kJ(e){for(var t=1;t0&&l.createElement(ki,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kZ,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kP,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k9(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k9(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k7=n0(k8(),k5),xe=function(){var e=ry(k7,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(ij,null);if(r)return l.createElement(iN,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oo,null);default:return null}};function xt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xn(){var e=xt(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xn=function(){return e},e}var xr=n0(xn()),xi=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iw,null,"Job Runs")),t&&l.createElement(ij,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(yb,{runs:o}),l.createElement(ir.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xa(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xo(){var e=xa(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xo=function(){return e},e}var xs=n0(xo(),xr),xu=function(){var e=iF(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=ry(xs,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iN,{error:o}):l.createElement(xi,{loading:a,data:i,page:t,pageSize:n})},xc=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xu,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(xe,null)))},xl=by().shape({name:p2().required("Required"),uri:p2().required("Required"),publicKey:p2().required("Required")}),xf=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hM,{initialValues:t,validationSchema:xl,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hj,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ox.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xd=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:r,onSubmit:n})))))};function xh(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xp(){var e=xh(["\n query FetchFeedsManagers {\n feedsManagers {\n results {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n }\n }\n"]);return xp=function(){return e},e}var xb=n0(xp()),xm=function(){return ry(xb)};function xg(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(xZ,e)};function xJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0?n.feedsManagers.results[0]:void 0;return n&&a?l.createElement(TH,{manager:a}):l.createElement(h.l_,{to:{pathname:"/feeds_manager/new",state:{from:e}}})},Tz={name:"Chainlink Feeds Manager",uri:"",publicKey:""},TG=function(e){var t=e.onSubmit;return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Register Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:Tz,onSubmit:t})))))};function TW(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return Mp(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mR.Z,{defaultExpanded:0===n,key:n},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Eu.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aA,{tooltip:!0},e.createdAt)))),l.createElement(mF.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ox.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gh,{language:"toml",style:gu,"data-testid":"codeblock"},e.definition)))}),l.createElement(oI,{open:null!=c,title:c?My[c.action].title:"",body:c?My[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mi,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M_(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function ME(){var e=M_(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return ME=function(){return e},e}var MS=n0(ME(),Mg),Mk=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iw,null,"Job Proposal #",a.id))),l.createElement(T8,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(TU,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(Mw,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Mx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(55977),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(55977),a=n(47886),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(97779),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(55977),a=n(15857),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ri,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nr})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;nr,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(23564);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(23564),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},87462(e,t,n){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;tr})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(55977),p=__webpack_require__(15857),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t5(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t9("(",t5(e.variableDefinitions,", "),")"),i=t5(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t5([t,t5([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t9(" = ",r)+t9(" ",t5(i," "))},SelectionSet:function(e){return t6(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t9("",t,": ")+n,s=o+t9("(",t5(r,", "),")");return s.length>t2&&(s=o+t9("(\n",t8(t5(r,"\n")),"\n)")),t5([s,t5(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t9(" ",t5(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t5(["...",t9("on ",t),t5(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t9("(",t5(r,", "),")")," ")+"on ".concat(n," ").concat(t9("",t5(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t5(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t5(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t9("(",t5(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t5(["schema",t5(t," "),t6(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t5(["scalar",e.name,t5(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["type",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t9("(\n",t8(t5(n,"\n")),"\n)"):t9("(",t5(n,", "),")"))+": "+r+t9(" ",t5(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t5([t+": "+n,t9("= ",r),t5(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["interface",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t5(["union",t,t5(n," "),r&&0!==r.length?"= "+t5(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t5(["enum",t,t5(n," "),t6(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t5([e.name,t5(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t5(["input",t,t5(n," "),t6(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t9("(\n",t8(t5(n,"\n")),"\n)"):t9("(",t5(n,", "),")"))+(r?" repeatable":"")+" on "+t5(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t5(["extend schema",t5(t," "),t6(n)]," ")},ScalarTypeExtension:function(e){var t;return t5(["extend scalar",e.name,t5(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["extend type",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["extend interface",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t5(["extend union",t,t5(n," "),r&&0!==r.length?"= "+t5(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t5(["extend enum",t,t5(n," "),t6(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t5(["extend input",t,t5(n," "),t6(r)]," ")}};function t4(e){return function(t){return t5([t.description,e(t)],"\n")}}function t5(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t6(e){return t9("{\n",t8(t5(e,"\n")),"\n}")}function t9(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t8(e){return t9(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n5(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n6(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n9(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n8(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e9(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n8(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n8(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r5=new(t_.mr?WeakMap:Map);function r6(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r5.set(e,(r5.get(e)+1)%1e15),n.apply(this,arguments)})}function r9(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r8=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r5.has(n)||(r5.set(n,0),r6(n,"evict"),r6(n,"modify"),r6(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r9(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r9(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r5.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r5.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e8(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r8(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r8&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n6(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r8(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e8(e5(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e9(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e8(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i6(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i9(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i8(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i6(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i5=[];function i6(e,t){var n=e.map;return n.has(t)||n.set(t,i5.pop()||{map:new Map}),n.get(t)}function i9(e,t){if(e===t||!t||i8(t))return e;if(!e||i8(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i9(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i9(t.map.get(n),e.map.get(n)))})}return a}function i8(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i8(r)&&(i5.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","VRFSpec","WebhookSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file +`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pU({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pA({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pA({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pU({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pU({},t,{value:e}))._validate(e,pU({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pM.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pM.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pr(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pd.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pd.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pd.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pj(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pk(e).map(e=>new pN(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pS(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pj({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pd.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pj({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pd.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pj({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let p$ of(pH.prototype.__isYupSchema__=!0,["validate","validateSync"]))pH.prototype[`${p$}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pY(this,e,t,n.context);return a[p$](r&&r[i],pU({},n,{parent:r,path:e}))};for(let pz of["equals","is"])pH.prototype[pz]=pH.prototype.oneOf;for(let pG of["not","nope"])pH.prototype[pG]=pH.prototype.notOneOf;pH.prototype.optional=pH.prototype.notRequired;let pW=pH;function pK(){return new pW}pK.prototype=pW.prototype;let pV=e=>null==e;function pq(){return new pZ}class pZ extends pH{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pV(e)||!0===e})}isFalse(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pV(e)||!1===e})}}pq.prototype=pZ.prototype;let pX=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pJ=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pQ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,p1=e=>pV(e)||e===e.trim(),p0=({}).toString();function p2(){return new p3}class p3 extends pH{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p0?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=ph.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t=ph.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||ph.matches,params:{regex:e},test:t=>pV(t)||""===t&&n||-1!==t.search(e)})}email(e=ph.email){return this.matches(pX,{name:"email",message:e,excludeEmptyString:!0})}url(e=ph.url){return this.matches(pJ,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=ph.uuid){return this.matches(pQ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=ph.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:p1})}lowercase(e=ph.lowercase){return this.transform(e=>pV(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toLowerCase()})}uppercase(e=ph.uppercase){return this.transform(e=>pV(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toUpperCase()})}}p2.prototype=p3.prototype;let p4=e=>e!=+e;function p5(){return new p6}class p6 extends pH{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p4(e)}min(e,t=pp.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t>=this.resolve(e)}})}max(e,t=pp.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t<=this.resolve(e)}})}lessThan(e,t=pp.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pV(t)||tthis.resolve(e)}})}positive(e=pp.positive){return this.moreThan(0,e)}negative(e=pp.negative){return this.lessThan(0,e)}integer(e=pp.integer){return this.test({name:"integer",message:e,test:e=>pV(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pV(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pV(t)?t:Math[e](t))}}p5.prototype=p6.prototype;var p9=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p9.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p7=new Date(""),be=e=>"[object Date]"===Object.prototype.toString.call(e);function bt(){return new bn}class bn extends pH{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p7:new Date(e))})})}_typeCheck(e){return be(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pN.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pb.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pV(e)||e>=this.resolve(n)}})}max(e,t=pb.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pV(e)||e<=this.resolve(n)}})}}bn.INVALID_DATE=p7,bt.prototype=bn.prototype,bt.INVALID_DATE=p7;var br=n(11865),bi=n.n(br),ba=n(68929),bo=n.n(ba),bs=n(67523),bu=n.n(bs),bc=n(94633),bl=n.n(bc);function bf(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pI.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(pw()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pN.isRef(o)&&o.isSibling?i(o.path,a):p_(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bl().array(r,n).reverse()}function bd(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bh(e){return(t,n)=>bd(e,t)-bd(e,n)}function bp(){return(bp=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bm(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bg=bh([]);class bv extends pH{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bg,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bb(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bp({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=pw()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pM.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bb(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bp({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pA({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bp({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pH&&i instanceof pH&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bh(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bf(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pI.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return pw()(i,e)&&(a=bp({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pg.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bm(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pg.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bu()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(bo())}snakeCase(){return this.transformKeys(bi())}constantCase(){return this.transformKeys(e=>bi()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pC()(this.fields,e=>e.describe()),e}}function by(e){return new bv(e)}function bw(){return(bw=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,bw({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pM.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pA({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!p_(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pf(e));return t.innerType=e,t}length(e,t=pv.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pv.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pv.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}b_.prototype=bE.prototype;var bS=by().shape({name:p2().required("Required"),url:p2().required("Required")}),bk=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hM,{initialValues:t,validationSchema:bS,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hj,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bx=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Bridge",action:l.createElement(aL.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aK.Z,null,l.createElement(bk,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bT(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},ml=n(76023);function mf(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0||(i[n]=e[n]);return i}function mB(e,t){if(null==e)return{};var n,r,i=mY(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mU(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mX={};function mJ(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mX[t]||(mX[t]=mZ(e)),mX[t]}function mQ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mJ(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mV({},e,n[t])},t)}function m1(e){return e.join(" ")}function m0(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m2({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m2(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m0(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mV({},s,{className:m1(m)||void 0,style:mQ(s.className,Object.assign({},s.style,i),n)})}else d=mV({},s,{className:m1(s.className)});var g=h(t.children);return l.createElement(c,mq({key:o},d),g)}}let m3=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m4=/\n/g;function m5(e){return e.match(m4)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m9(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m7(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function ge(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mV({},i,"function"==typeof e?e(t):e)}function gt(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=ge(r,n,i);t.unshift(m7(n,h))}return f&l&&(d.style=mV({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gn(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return gt({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=ge(s,t,o);e.unshift(m7(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m5(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(gt({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=gt({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gc=n(98695),gl=n.n(gc);let gf=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gd=gs(gl(),gu);gd.supportedLanguages=gf;let gh=gd;var gp=n(64566);function gb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gm(){var e=gb(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gm=function(){return e},e}var gg=n0(gm()),gv=function(e){var t=e.children;return l.createElement(ii.Z,null,l.createElement(ie.default,{component:"th",scope:"row",colSpan:3},t))},gy=function(){return l.createElement(gv,null,"...")},gw=function(e){var t=e.children;return l.createElement(gv,null,t)},g_=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gw,null,i);if(t)return l.createElement(gy,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mR.Z,{defaultExpanded:o},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},a),l.createElement(mF.Z,{style:s},l.createElement(gh,{language:"toml",style:gu},n))))},gE=function(){var e=ry(gg,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(g_,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gS=n(34823),gk=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gx=(0,b.withStyles)(gk)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gS.N,A.wU);return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r7.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gT=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(gE,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gx,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mP,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mS,null))))))},gM=function(){return l.createElement(gT,null)},gO=function(){return l.createElement(gM,null)},gA=n(44431),gL=1e18,gC=function(e){return new gA.BigNumber(e).dividedBy(gL).toFixed(8)},gI=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sf.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aK.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ob,{title:"Address"}),l.createElement(om,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"Native Token Balance"}),l.createElement(om,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"LINK Balance"}),l.createElement(om,{value:e.linkBalance?gC(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gU.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:r.footer},l.createElement(aL.Z,{href:"/runs",component:tz},"View More"))))))});function vn(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vr(){var e=vn(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vr=function(){return e},e}var vi=5,va=n0(vr(),g7),vo=function(){var e=ry(va,{variables:{offset:0,limit:vi},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vt,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vi})},vs=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vu=(0,b.withStyles)(vs)(function(e){var t=e.classes,n=(0,A.v9)(gS.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ia.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vc=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vl=(0,b.withStyles)(vc)(function(e){var t=e.classes,n=e.job;return l.createElement(ii.Z,null,l.createElement(ie.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ip,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aA,{tooltip:!0},n.createdAt))))))});function vf(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vd(){var e=vf(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vd=function(){return e},e}var vh=n0(vd()),vp=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vb=(0,b.withStyles)(vp)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gH,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vl,{job:e,key:t})}))))});function vm(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vg(){var e=vm(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vg=function(){return e},e}var vv=5,vy=n0(vg(),vh),vw=function(){var e=ry(vy,{variables:{offset:0,limit:vv},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vb,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},v_=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(vo,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gB,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vw,null))))),l.createElement(vu,null))},vE=function(){return l.createElement(v_,null)},vS=function(){return l.createElement(vE,null)},vk=n(87239),vx=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vT=n(5022),vM=n(78718),vO=n.n(vM);function vA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ii.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(ie.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(ie.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aA,{tooltip:!0},e.createdAt))),l.createElement(ie.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yp(t,e.status))},e.status.toLowerCase())))})))}),ym=n(16839),yg=n.n(ym);function yv(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=yg().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yy=n(94164),yw=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},y_=n(73343),yE=n(3379),yS=n.n(yE);function yk(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yy.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:y_.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yw,{data:e}))}))};function yC(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyB&&l.createElement("div",{className:t.runDetails},l.createElement(aL.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yY,{observationSource:n.observationSource})))});function y$(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vT.parse(e),!0}catch(t){return!1}})}),wK=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hM,{initialValues:t,validationSchema:wW,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hj,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hR,{component:hJ,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wV=n(50109),wq="persistSpec";function wZ(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wV.t8(wq,n),{toml:n}):{toml:wV.U2(wq)||""}}var wX=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wZ({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wV.t8("".concat(wq),t),n&&n(t)};return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"New Job"}),l.createElement(aK.Z,null,l.createElement(wK,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _O(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(_K,e)},_q=function(){var e=_V({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_H,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_Z=function(e){var t=e.csaKey;return l.createElement(ii.Z,{hover:!0},l.createElement(ie.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_T,{data:t.publicKey}))))};function _X(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _J(){var e=_X(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _J=function(){return e},e}var _Q=n0(_J()),_1=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r9.Z,null,l.createElement(sf.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ox.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(it.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,null,"Public Key"))),l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gH,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_Z,{csaKey:e,key:t})}))))};function _0(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EO,e)};function EL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EQ,e)},E4=function(){return os(E1)},E5=function(){return os(E0)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return ry(E2,e)};function E9(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(SV,e)};function SZ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kq(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kZ=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kV(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kK(kG({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r9.Z,null,l.createElement(aK.Z,null,l.createElement(k$,{object:n})))};function kX(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kJ(e){for(var t=1;t0&&l.createElement(ki,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kZ,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kP,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k9(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k9(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k7=n0(k8(),k5),xe=function(){var e=ry(k7,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(ij,null);if(r)return l.createElement(iN,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oo,null);default:return null}};function xt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xn(){var e=xt(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xn=function(){return e},e}var xr=n0(xn()),xi=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iw,null,"Job Runs")),t&&l.createElement(ij,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(yb,{runs:o}),l.createElement(ir.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xa(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xo(){var e=xa(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xo=function(){return e},e}var xs=n0(xo(),xr),xu=function(){var e=iF(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=ry(xs,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iN,{error:o}):l.createElement(xi,{loading:a,data:i,page:t,pageSize:n})},xc=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xu,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(xe,null)))},xl=by().shape({name:p2().required("Required"),uri:p2().required("Required"),publicKey:p2().required("Required")}),xf=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hM,{initialValues:t,validationSchema:xl,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hj,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ox.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xd=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:r,onSubmit:n})))))};function xh(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xp(){var e=xh(["\n query FetchFeedsManagers {\n feedsManagers {\n results {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n }\n }\n"]);return xp=function(){return e},e}var xb=n0(xp()),xm=function(){return ry(xb)};function xg(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(xZ,e)};function xJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0?n.feedsManagers.results[0]:void 0;return n&&a?l.createElement(TH,{manager:a}):l.createElement(h.l_,{to:{pathname:"/feeds_manager/new",state:{from:e}}})},Tz={name:"Chainlink Feeds Manager",uri:"",publicKey:""},TG=function(e){var t=e.onSubmit;return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Register Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:Tz,onSubmit:t})))))};function TW(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return Mp(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mR.Z,{defaultExpanded:0===n,key:n},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Eu.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aA,{tooltip:!0},e.createdAt)))),l.createElement(mF.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ox.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gh,{language:"toml",style:gu,"data-testid":"codeblock"},e.definition)))}),l.createElement(oI,{open:null!=c,title:c?My[c.action].title:"",body:c?My[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mi,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M_(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function ME(){var e=M_(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return ME=function(){return e},e}var MS=n0(ME(),Mg),Mk=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iw,null,"Job Proposal #",a.id))),l.createElement(T8,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(TU,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(Mw,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Mx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(55977),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(55977),a=n(47886),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(97779),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(55977),a=n(15857),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ri,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nr})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;nr,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(23564);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(23564),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},87462(e,t,n){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;tr})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(55977),p=__webpack_require__(15857),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t5(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t9("(",t5(e.variableDefinitions,", "),")"),i=t5(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t5([t,t5([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t9(" = ",r)+t9(" ",t5(i," "))},SelectionSet:function(e){return t6(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t9("",t,": ")+n,s=o+t9("(",t5(r,", "),")");return s.length>t2&&(s=o+t9("(\n",t8(t5(r,"\n")),"\n)")),t5([s,t5(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t9(" ",t5(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t5(["...",t9("on ",t),t5(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t9("(",t5(r,", "),")")," ")+"on ".concat(n," ").concat(t9("",t5(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t5(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t5(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t9("(",t5(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t5(["schema",t5(t," "),t6(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t5(["scalar",e.name,t5(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["type",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t9("(\n",t8(t5(n,"\n")),"\n)"):t9("(",t5(n,", "),")"))+": "+r+t9(" ",t5(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t5([t+": "+n,t9("= ",r),t5(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["interface",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t5(["union",t,t5(n," "),r&&0!==r.length?"= "+t5(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t5(["enum",t,t5(n," "),t6(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t5([e.name,t5(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t5(["input",t,t5(n," "),t6(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t9("(\n",t8(t5(n,"\n")),"\n)"):t9("(",t5(n,", "),")"))+(r?" repeatable":"")+" on "+t5(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t5(["extend schema",t5(t," "),t6(n)]," ")},ScalarTypeExtension:function(e){var t;return t5(["extend scalar",e.name,t5(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["extend type",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["extend interface",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t5(["extend union",t,t5(n," "),r&&0!==r.length?"= "+t5(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t5(["extend enum",t,t5(n," "),t6(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t5(["extend input",t,t5(n," "),t6(r)]," ")}};function t4(e){return function(t){return t5([t.description,e(t)],"\n")}}function t5(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t6(e){return t9("{\n",t8(t5(e,"\n")),"\n}")}function t9(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t8(e){return t9(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n5(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n6(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n9(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n8(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e9(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n8(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n8(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r5=new(t_.mr?WeakMap:Map);function r6(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r5.set(e,(r5.get(e)+1)%1e15),n.apply(this,arguments)})}function r9(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r8=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r5.has(n)||(r5.set(n,0),r6(n,"evict"),r6(n,"modify"),r6(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r9(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r9(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r5.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r5.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e8(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r8(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r8&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n6(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r8(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e8(e5(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e9(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e8(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i6(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i9(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i8(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i6(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i5=[];function i6(e,t){var n=e.map;return n.has(t)||n.set(t,i5.pop()||{map:new Map}),n.get(t)}function i9(e,t){if(e===t||!t||i8(t))return e;if(!e||i8(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i9(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i9(t.map.get(n),e.map.get(n)))})}return a}function i8(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i8(r)&&(i5.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","VRFSpec","WebhookSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file diff --git a/core/web/assets/main.74b124ef5d2ef3614139.js.gz b/core/web/assets/main.f42e73c0c7811e9907db.js.gz similarity index 92% rename from core/web/assets/main.74b124ef5d2ef3614139.js.gz rename to core/web/assets/main.f42e73c0c7811e9907db.js.gz index 667a96c1ef3afc61afc8e61da17f2e8de3003008..408214985c13d62f443c26eb2c3f701a08d78228 100644 GIT binary patch delta 92868 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 z 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 >rKT@(Z30ei{L$E+7t!ZC=0fy$5n*FWohSvS$ou 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 z zB9=ctNg7D~$fGsC34mZyo3(l|?`dA&j z%+Q_5u+FBK3mK%Rb+N&}%#7U^YOP@{$0gEc>igdDOX+y)V(#ZNu(n*$(T;GESVc^> z?s${czM+f(=D4P4qGvT;N2pQ?!o&aFaI*bxNS!Q^T%k5SMceK|@4hCcQh#2uFCrUQ zEDAFJ#K}8}N5``|;bzBmK1Kc^v)Dsnex=x3mWlfrS449-WLP6WhDL>YQ7idF>Xj4ZApuAF!^yX1n1JCt3>ACK7i$}T#Y6A# z*Ws2u?;X1uBCaeQUi|756h9*TFQ$95}_K|<< zP2>zaFxDCTaY+1W?qZrI>sFQnHsbjJFv#ZYQKmNv;ifad9tg$h zTW*ptiCMV9dY6)s63)ff4!{cYGZW=$Gy4~fRi;zy2@ zm3Fu-7>;p6ysy==42rxoZGvCs-R(|1@4_(f17`T(W_4D4SbJ&EM3>i~Rg=cm>c%@1 zlS8tw@y$Z6!X}avNRD>IN{MtN{4Ub8c_dlvW?&^he36l~(12lC!bB`@#iP$rWHbHC zae2QRFP`U(V(qG(!DEAXl8g?nf&$ScGn`@DXS6x0zwag_`gP;WX&?UxDxoq8iC#(A z>QJL9ZNgm*NvNxb_RG`9I?55-c-{T6&vEw zM=lTPw4Z7|OsW;)&q{`aK02kg4q98yshZV1X+=kQ<4c3bNM&_OBab?~Dw{^d0?0*b zU5Bp_ywE?Qe7jf)h9hpsA;>Y}AQEhc6LhD_w+V1=fQYsP)D`VgvyuE{jn46XzDi!}G5EdKu%hJ>dd&Ml#Woo?OLo<=^;o$`Y_srlc2qsQZ}bDaqJzAd zI$wwF;@i<#f;4N(iBqxLu!<-C+9V;=vq7o=;2j~Hcyt=e2<)^ZOfljggsZCBy)%=4 zP^UrYNmag2@9x2OsATMZSYK-DSuR~e+>lYZ-I^>QjU}`I)q`*91#L;je=(9^1LZZcZCI57Qn<|SK|E7YZA`{7*(@p>s$XeG3t-$(H=Bwxs;9WrZf;k z`m|K|PN)o9UqV?<6CuoYsGT(sQ@8T$;wTeh)+PFon5jrUODe|v$zkivN#&=>p5#7= zR>e{7b>)Rfi%88*=sUL10v>#ljFZUt`I`3Qhl)ej*)ibUh*up$EQKTwiHlO7;lzn| zBGDL2NwtK!XKF8$q}SBZ(bnXgvP26o*Zq&n%JIf4{)tt+Zw2in&+>ak_rDCZH2+Iz9uHzk(eUF|=3UAx!Y6CoM30HQC!=H&9Sz4>ih zyy4ZXx*U7E?)SR}(?2u4Lh+XM@{SE5^B5tnjL1BJfYiz@h2PY(|9HQ*lTL`~R?MHK zpmJ4=pv$wug5n2f=%WM%s#zmA5G%3h4Xb(7#$Yv>(R9L!9@7~bJ22rL$XY%o7k*A6 z0iWCJ1e3*tHE(%I&1xGaMh63RLZ{_xb2SE@#7vR{EQLWVAP}itZ6rMlJzE$@VTI3c ziRPMyO_=X8{uuwE1*{P%eNU^wPIZ|C|~AqSob!i zDX|0z^Uu4hoB=+Ue6K9rTC?)pqS&i((qeFQz~+DlRZnyMl-JhvWt22tww2T*SJbTD z@|wqJ8>{#VfS=d`B|MkGe%Ga`^Q9@^G0bX$sOZ$59_(vudic#fsXmGt#C`%Iop(hy zOss?T0YyYSBG{(eaj1?N97`e}MDpFU>T*3V&P_#7K4_tk$?eshR~(is3oRN0l@-XhYH3U+ zKdGON1$uf^t&RV}nn1V5=T>1kDpfX-IKSa%tf*!Eh1d^G5+i)A3@LHND@c^YX;vVE zY8auKy3i>(OJAF$!sev3tOUAO<~)%2F_eaZ4PwH7=c9!Y8h?PlQWU?6J-w z9l!X;;auNB#$F(fL{hX5%oa@cMzIjgghqlCus=c__ zB9jsN70w!GWVvS&+Dq@L)|$$zoze?>aPaCUFs}H39F07b;v)G_czbMU5T@8{O|?Ds z6^<6wP};+MLEi}aq(ME=dO)FM4o>o{jQ_clrYcM5Ik-Xp@K^ytnHyNhl>Z-g#={^h z9yEjyluP#rFT!mO3EUV#SNA1h8HwO`SSHx@UJOjub_?qglEDt*L2}|R`HHLWO=buv z`%Wt*IOpW1`uHf?Ydml&G`l70N&Gq?1bP%^mr?k zpNfEP7P>GnMJk_)Ov%tQ*3#TFwnPE7VAXx6^vADSNS$VJf?BnoUl!1Mae`~ipL0qb z`cd4*{;rkgRd)LJ^2)(6dZAk{f6juGIYD}f?ba8*?k6Q zT(CnB!M;QEg_bX=>3jU#kOy+uDrgNZP60V>zy+;aKjm{~^3miwbb1p!{vW z@{e;ETYd**Lw85(W+^OI3Tm4}Y(#(z;xaW_&o|`K%*t>4MB<>(>*sl59o-1{R==E{ zr?AX_%G8sW)3l?^%FuNBg`cF#oJuYLN?oTm{L#ClEi+=jwFk_C6DNKw`atAt;Q4#R zFpJFA&JU8>+n8)BPSox{O85cfS`j+mXY)~1l&t7EyL-li7j_F6INnr6qJQ%EY}q}q z4EQ*f&zz3u4N6xP0p!LxYt5VFJ9?h#PB9<+o2#Yb@nlr!@WHlI&3mNq%{fB|xm~SN zHqQ+9XzcDt@f1oYsNUJ;*M;pJdJDf!yf~NSahparyt9+9quM*n_&)$?j3%kkiKUFo z*}BwVI(zMGVwafyrt@o!&0@#M9C~|P7b`T}fw$& z-f0Z0h^t+iU!=RtTq@AsX9Di&HaQ*O(gQ<;7u?Q6@sJ0KO!@Ds8r88MdKBSxnjA3C zgp@Kt(0n_Z_@K!;%VjWTXSIx5^r$gxj28ENBn5#DI(Rd{45%hvM6hc3wu#{4C+@mN z;xwj6c_i)N{LuJ4Zcn4kH&9gGC=b1XSPVyAv=BUb*k0#iBpfI&&iS)ziHYyxP)rPJ zh(Bw*<25)Ep46=Wnp%M)W1P-0GpNzWVFmhEiS0pmKzg{p84k=9D>la4-gqnY;$C13 za$N8YOb}OFrrMe9_AB^0AWlo>tM(`&6v}R0uIu3@uC{y4KILv{BZj;+qHz@q*V7Ch~LS@u}L8^hN3vk3}SIB6Rm4=&V)*9AA>2Yf52E*M5R zPRPB-YOL0W-Mtlo&#=7}2$QT?zbPA=kk29E1N#vB4WP!%aE4kY=SBpTQvhPkd(Zj! zp1liR(37r5+?+a?>ujyf`+DXZG%anJ{flmacCxZdBidJ=b;ytO(#49%XW)Xm@RhGd ziI6m)@!r+B0^3S%eY6a3VV_y?S5W1-Vywd065Op}3DUi{7{s!mFD;0D+ON)!eG*fZ zY|y{z2Mn(I|6AqT5pEj0rzXu^_y)T4!RWAZW;BLeV#&ea3=RFWFqY z-@xJIp@(-!hWB#o;DiN}K!~z=E*$=xj5G@of4YHCS0{r}SEK&jQv*xw&?jDN(J%go zC^WMj{uJiR?3-sYLCGfgBS!F|4=m>IFQDWv`1qJzpddt*6fu|=vncVOEq%-$$r@cI zG^QR&B1Gfq(8fArOlf}C3Nv9;(+um)vk!(E|LgY{-PIS%NT}tVf zPf+upFw2mBQm&|mGqP&)UHE%7uL>?gdnqLbFn27`{`$Nsh_dY{NBz4GE?E#i=>c&! z91T#-2ogP}a|Ln!0?Q#xM}1{wH1X*(gb^7~N5heS2vCuJ@{l< z^=%75<7QfR?X4=r+9p_eT_|3)OI!Qd=(PjtL1MH60bQn$vXcKNECJ}$HK1WVhf!3S z<{Hk+SxC`?1F2_>N{0D@69}J&j1%U8(05o-WnUlcp2R0wEpr;k3hk6$9mf0BphrE` zZ8&@i{yn1Pf{X+NTM!Bs^zXAO8Wcz@TX;)>5>NS$dsL(2;r@pXfq&?umakzfYKY?; z$r%Psy<_Z?QPmz*7{t%Um|6uvqhs$AW{co^CAjf=&};jDCs5#uV1`02O2jWh3H-!Nq!XYt4JUMmdkPnk4eR_5?QUWk%H)uycW zV9;0=lvEt>#raSS1Da1`zt^L9wg`=;?IK?5vMQ(kES`h%#fE(yYrV8*TZq^o=CnmZHC;Ph8u539_gTx+n_kj zxPJ=I?pOe(LPYF0qTGkdJ#*LkwcZ)$<+X&>--k0sMp$es(yk);AIvqA!}L)@T}s5^ zeHP}c$;KiN<2W!pPzRAi)GWiATTO9RB6+1>OJ5v;LlFn0z~BE6*@#?0dL4#ueej{e zz~Q-9*Xdb+1X$^5Sc1P)7U`X-TUD8-eLOQU1G=J4!(_Uo?h(jS{@}|Ucjdr3-;k#R@y0pG6YjkMv{xs=GbuhcQ;$?M{emlmo1{Xhi; zl0(2jD~p0`qs#94X~OS`r80K1NL7n9*wy;zH91bSJ&~bj`0#mO`e-*QRbYY>`iiCq znK*<~?C0F$&@f^JIrw@}D=gi(>VuaQh3#3OOwdEYSpV#=+414s@*plGoM!P30l(e) z`X*Ib<|PubE-o7`8D1({Q@BlHaX9}xOa3rrQQmsrQDC7_WL~2i?{%k74|O5n{Ke6sG;Q6K^91UbV36GROq7P!4m+XR$3Nk>yv70$FLoKv)V<1!v$; zl-yXq&;?7TTwXz;BKiQv>1|>qsRzXK$oQdp>>Im-WKGry+xHf&u#x| zT0&>0*1ycN+y~u$`N_%yr{4TZv}}v(GM!f`p>Lo)2|2y?6j@z0hTQ-2_=Bz4zTfV99WG+TdfD@uuqJ31SP6Hq@;9t7bUQAs-i(Jg4^@_R=n~Tvfq&mh zZpWGg&s`yPa(?BReSEss{nRMz4GQ0hj#&z}Nb!>h!NSY^|sSh4!M|lQn<_4@5ETwo_i0t4+RZLw3tI zxUY19x7Ybn0H@K;T!JHzuvU1ZkvoTYrn7z>?z6p8EY@6Tnlo_&j_GBt?8=oNyAi|K zOH-K|ga0Y^&X}@S==&#@oN#VAer1U)X9W#;lAK*;jqf%AcqTa5v3b_@rcZ9+Q+BrWqEgWF^vL#}uk262Kxrg(^J z4NwS7hEk6M5;t#2yxkO&A$!lrH*d5aABtPDPp#k+LD6!Z@vWqFv@f(Np5(7?)~|f% zv4J8LwGK8QIOSVqYa8Gi`wxd5vhoPi zb4c2l=S#mZ_Z57)p2vcg*@cbmkh3H(#%WEX9b?hQ zL5~5S6(eslT48lsj3yMO&gX-Y%?bj`^@H-R)ed#`axOP(3AO@@rZO?db;AriC1wfh z3ORwFf#zPyT&o&I+==5H89&)xk>-G$vNFmHThUgz8i*^nV!qJgb!N5lpaC9lZ34ZC z{efG;y~EDLTD8CPQb>lVTQ#S$HJtF|MF8-;Z`}X1rX7@i?>WzouByvgKS%`K`;XoE zule7dU5l{Pw$;*O?ky{%8xuMNyWA*E9lw1}B#5L1wY-@&xkP<8tMdiKkk3g3v$(Lt zK`!djeKhOO8%u;pvm(1uM@odjfAP|KrYKKJ%}<&k%gWoSq%+8dD2zct4ra&`p~I z@(vm&v=1&26UA`xqQwMCM_lz+e8m3%f-%(og z&(cNOAdB>$Ag%dLL+yJ07z4pcBP%#biDW>C0y9R0D4;^+LKHA4iUIE3Dnbf>xsbwV ze?kgwu@G`LBBc8%#bXGJUXI6rStw>M{>9d-^R#?IvwFB#sJ=?r3L3LC9i-ynp-SCv z4OQxwh9!f1jc{lCA?=U23uJZ}8rN7`4w% z=Dbf*rBPWFGn?S^&wwE^(ouypzvH^4$Cz;+WYz}b&%W5Unlh(wFe zx67x?JZ=$jed>ENH#8gq+H{KjQ}AB$#b2E%#ay`XFA?l)!+qO`S0+iGiJ8fz!=y($ zki|^6(#@@FR7H z4^*CvrAIZElI9TZ_6+!2a*LOr!MWS~1cw&fj>QrP>0f?-?*ygi>x`VQfvTZSsG&|j ze}8ul36%TP@&kP2hAM_we>bW^rdGSZR~iax)WMP>mjY-2B&gSE5+7s%omom2z{XGw z-!`eLz$zw(_I@Pek>aD`aTl;7Qqh&gQkrj-p3)RbY5#K`(QKjAop=V?5sj5Bk z+&*5`R~HgJSx4a_vm4gb_u%WREvp-JmAm0nsZ0)iZ?ddLxamDreO+%^ZK3y614}%3 zmsLkS;;QM+NR3a^f3^=+P&@UVDjBUNlZ^o zp>D9#BkTQXe>IAo+v*y{aQ>&&Cx*%RrqqgLYend)&7RSM;6@so2)nkiDHrv8gQ}5K z1ZPRUqH1|V?-4l}=Uq|38SaKOh)Y^C*?E3gmQDi8(zz->?u)e^)T`7td$ z&@*JO6lA4CKvtk{8tTXqR-~kir~n*M1t1FkpBGc5f9e@e4tG}~;AKP?h52t)>iS_q z_*j%sK@R>9Aw0QIR*}JbRZ`L0c!h-I?z}`)uP!<0Vp$kBOfXHe{vBod>k(3Z^=3rD z?f!rN_x}w!QZvCm6e)e}4ij9m${om{1BQi)fzB;Ci!p%$3?HEr$hRRaC`_pg9I48n zQAf=+f3#Ldje4DF5B!SS196ZlC=r~cN(5Z3a6ebHAT-vM{+>3c9C!+mSotRJg zf2K=dl}wic9uXAk0zz4QvwEZ^({DhGtuq_|8JDuB4)7Jo_ARh)i))tQR4Nn8aTNjy zkmlY@95F=Q#niIl41w|VCE?cmy8hcKyS`OG{AIHgq3Q>Uzn=40dnXb2+?*GkBeDX> zjX#jdjXsnWlgj~0ZWDjK);2In^fBjI| zc6D0~(ZabkRL%UK&nVm_53kXuWAgA39nnu;(EdNk!!M}+o;-BXafdv#QMg7PuF>xy zd6=W0`{ZE{9dD3_U(o?g{GJKW3G|@ps_W~`%`LE7b=B3zX1xx!s;=%*=v7x;-`Hw3 zwQa!5yT4a`aPHRhqm!%Cv(AUJe}nULQ*m5akV6R7qaa6T$mv%{CwrYXJnVH&4v)^- zyWOMC$+@X8faEL3?Ryh==u^;ci%yPE!d~a(Z>tZUW7gD}IJKFznkffs9 zTugC(d~k4@BnZYBPvQH)*;(i8VBe%s9{_LN(f2y-Qv&C1Dt#8x(N@TqfAvjQ-Q1`* zS{fRguG-kDZ?0-+V7h8+b+g$Lq_y_5FvFuIys({$E;#)GV7t9%#@d}$fZClt1Zg*| z%%uE2MC~ZKJA|Bb9a+H<vMBIs*fumCt3Oi=r~F+UFn8Bp3p;AnI1EpYV{W+UbZuf9>r`wUZK3b$3eg zwXgNFgS~^JF9%oWM;}g(PT~=;X261lP9M~92GwKhRv7wDZx-S}PkoOfw40}$#g!cH z9vzDgcgN)v-vqw?VCTJ zcTRMo-%ush5_>0oI_r&{{wI6~Ml54!EH?M$?=>X8w#H-ccF)H)%%?RD^nvFeSmNMd zZ2^8$=Dvzam?8}&xM|jnGlT;S=75)=Evzy2Lsi-HW@F&(f5MtYVM~)lwP4l@?t&0c zYK}|7-}OK>ihaG-20pHbSu|IG*Ez3wer@dat?|eULS4~NW~61UAX=bB+)qR3b0nVv zKC{`0pp)PtdZY$Z&kZm^3l(;O=kIgq(EixLZU{eN-cSI!tlJ|S^-V_)oS|!hlpBpr z2ZWRUM*>rde+G1xDOc$X?o@!+09zzPG8-pqpdqpkTpj)(-V$SxYld;6S{h2X!#II! zSzNtwqV_eE)Nh=qBy!Yt>}7k4dr+_oTi+Z!(LTd`Y(dk`jvFU_SDv1J^5Zvn9N=0= z$h?fo5K>4ok_p_aOrbiTy9IRcRYN3OM?!~TbchPWf4k$ulO3Hz`>F1!vatyn4GI|z zTF``i6~ciQF6n99wtb;(pB*>c6s`eQ=)q+gNqwvPBg^0OY`hz)^;C%`?B2sR31<=& zD$fW_xN0XgLHVx9ZaPrw9xIn!xQVn_Xj2&Xv(^heOLaBf$HbdgefRG-?}kWutB9}O z!K*9rf0YSu#Jk;T)(%TNzXBWrhaC$F!UFmk%IT;08uk#Sj*_?Oq6S^2dN;yI8j|a_f|sP-ORzGC4p4ag9+Hf!6-YLJ|W2x`pd@Y z6TYkYLWUYe#jatOL=tZw?p~dp9_`mG*JeLDXGb57PHNb_aeU7urk=6sMa}YYEx@7v ze{WZL1I}w?{Jxr;B!8X8L~ifwV7Gg~DRP7kOBh-q8x5ox6LJdjjeeD(LjeC7q4$#O z|51cKOJ1L;T7*940&QnmSU-N{tEm=J7M8Y-Lxfly=GQP(q8`H0ihT8& zh%M!lcCPwJHXQV*0P5_kUDZXH9+2pDf2K3Y&v(ZWw3L$W(0StB0mTrbK|g!Fvzhya zXf0%$QvIqSN4@5)k@m(xvNe(P#!f;=tUQTTu)7BrfXe;LyAD^7x}TruaTos;u}Y&qGtxq>`Xe<}R9 zotL0S;>oi30~Wu|L=sZwisrTmgDFVie&J?PF^6mR)Dn>;3XqLPh(O@; zELRzP<6(?%Jj~!5gP0gFr>UNce-L?dtp8fq4-dL~AFtkjK04mNIyyP*T(O05u#bEV z%*xa{8t5mQO7M6A0vS1a-E}ECytY>C}LoLVHzXEh~1GNxZWx)Ng{o|7Ke_-U@s#+Fy zI539{bQodPHdS@BY@CvIj)ZmwXhdO)S2M81wW(M`&s5dPvKl}vaj=gj^oDIt(L~b_ ztT%O7kDv{OxCO#u|la?LCuOuj6z4pGL?4$y>JBz zP(I;T0+>+)b6vWJ6R%|t;X;h43#jVziLkISHNT!uI#3|}B! zJdSJQd1mR5$Tbm@KzlCJNLg{^vg)*TF1?-bxna~xZpkeW{=oQnV+>{BTma}7uZ+2?=)+E>t z;kd!BttysnQwtibvqum@@UQr0Lgw;l9}*^09M^fH**ut|Ob;yg^8f!sT$YN-j472W52f*cyL2F_A)}xf%njwdY$yqCS>+Q4Qdc{0O6h*L8r|=v974Xw81B+B zq;k9~E*w+Paq(z&iWwV;e6reLNriFptkYSTZQ00bDkJTg-a zM_PfrfZoDnjxJMcjKh%2v(!3@6|~H1e8J717CmA^x#x{N-%x&ff3UZ^zpfx<#UN-N zim?Fq+@TL3Bs5V-WK5o`-;SIRBYFOwH$NX)ws&hN^;&Z}udPn!wR+7T_AIrI8qF4J zf3B^ex?W$`P>rT&iYdr{;j0owXiBm7p{+uxbp_>{#**sb0RztD`SzCfES0@#9~xU_ zeQ2zaJ_NY$xi;xV<*|(-WP>-hpPr?VN}GZLscIHf{;CaMb9O5}Z zk+5L_ahV`Fpj4VkP&tMUn;i~=L%nsuf9IY%V%Z9{6jb736=HX&&|%DH^kyMZ+bL`u z<0_&Iluk*Oq%PF;X8jTEC-X~Z9%shF_dEauNR34V|3Pv{O;#Ur%~<;y?kFs~VuS=F z#C8I5`9Yq^w1s_Q1k8-Y(7?nxfa4%raDE%{XYk!ZQ}{J<#ln^LpNri zYN~zVUZPQaZ}T(mGFFTvF;f>28j7xHH<5;>%yY&z3E>l+WdQU@i_qFyYrX8K>5`+S zUv|_aXNi@ZCDxz&Eb&a)NnyFpf5Zww|4berqOKB59k;d`)L`QK}N zH}I_q4r-7}F&2Oh{QoG%g7`-bJbwaMAH?snwO+UJ5Qs#ip+LG10>4i{a&8?v9Favo z!p?9MBI2Pj4$0EzOFMuJQ^!R!wrgIQX0Wmn6s;u1nG6-Q2>iYgqGS=xe|9{b_gYbq zH4Y66kp>tpqSb@aDnhgT3iC8D#_G%1^la@jWWoBy#16H!wN@|XeomRs)z?qt;YPkV z*VeW+HYgvoy0*TxLHHou1+j4eyiv1RU!^`*8;#ZGIHfAWm{1wAl&RKqH6XB#wp+f;g+zh-88?`Hz?DW6>$ zY2KzLF?#KEj6qL0f5PKwZ5GsecQtQ{p(!;>K}t=@4X9!%Xh8w)ASPj8yn8ov!qKb; z$NalsV)-Fmcm43%38_pOK=Ix=K`_I?I~N0tp3<8QYd)TOK42x$-VV)4O6(bjKgoG7 z?ZCMmPuGs{tYR|i0eFsNoRz7wYs#N08#$%snon9;e(#hbUx4n#{6fLWC7bUS zQ1FGe1N0Sg1+SQFhO2A_7toJVei^Yb7IWOl3=i*D+^1ZE_zQ8_AgAu@ubO(UsRtTa z&2#fQLR+i#f2|6K=-1_E=f>vdI+Y=?gAh(nkWkRWlbxe*c(&^G^*VLcWk)I;pX>Ft zW*v@CSKZp!*x1t02x{19*0(?r=&Hn7TSGl4VQa0fp$Tb0Yh6RbBNAi$%@y>Mh z=^JHhux@X*ns~6afj3vTS{v)DSPyQ7%C_K;7_+3ee}8V4^s34kHPO51RwZoQ9pTm} zDj$%+T4&0aZt$(QOj71g`y*4k=Aj12fZ@J7|qjdowajUEMVbo}SRHrh)=8xi;BU501G z0gjGEe|P7j>cRQ`I=32U?mz$ku<=%n$Ge|WALQcR~19A~}4bR!x%Z%RYwO_mXN z1y3wzOyUHttT+JKEZ|ydNSRteaO?RtOEJx+h$6x40}6zFfp5S>pI&;vG*J&`J+S3; zhVGH8E=ZMzi+I__2t*J!!VU4x#8lY_SI1kBkBBZx=qhF)`I&ILlb5ZHuh1g&0DZly ze|M*v3OI@Hlqk=1=OM7Z&VtYx+{KFnS+G`)LOcnQcY>@=k8_LYS^hHgtU3xN#yW)a zSViNZ(L(dF(Ue_985C{yLqC0`z0rkjmoG*EiIoB@?iV25AQO63N1l65CdU{SG+2ra zwppQf&4(0NWw@HDA&+-+KIZ{q4AEL0e*njyuHdmmC@@-sYiZ1#0p1b15-u56#W=kc z8piH?vL&(bEhiujd#UD=jS)%LigXc;3j`evC0{I+91-NEub;ptfuK8Sk6H@@lEyX| z1ws@&Lph+oD19{)*YhXVSV7e5-c90QPE?jrV}v^yb0kr53})l;FJw);s<@5o@cE zvP)g=cKZZ+n(n8&{9V0l*;4r&obl(eN-IJNoIfC-a$H^46^&t&p;H-a!%rV0b@n)( zo19Bo_<&40;&P5{R4OQlz`P(9e*&DMxw;U~N@J=YZ$z4=p3sZ)R|dhouriH5s%?mxE7~6kIBWNtP2_gZYb?0*0w`7D%tLamAgxP>QdcBF1aLg zM{DHAeRHF%kvw0OYypHje<4iuk~)K(V!ZTaS;6JY7_+e>{$IJ7akWL!_HdV#&pjd; zyts`0O1hmDVD>d$Gm_ccYLCN(`u*c9qC1Zn;f2*NIGAcAEk+dT4 zkTU4X7DhB(urCzsS1p)0AsNL(K)+LG%fgx+p=Kwknc2Jq_xGd?ndnJ4;%cGkb{eYh z2T<+d3)NmqwI@rc_RW7W)xP_YRQu++sP-+oG8Z(sNgdWtuQ@e+N%S?60a5`xs^f_S_Erqm%Go!7olYQhnYtZRbuMQi~D91_4B% zGdFzGh%`fa!|0#KKNQs^i>xERwk1KoD?vxEJkvxB{EK0hIL z2Bw7e+&oAK?ez~LwDT82yOhvgFCnzu|6)Sh{*i>X`&@*!e`6-xnV^=xxJ3P#?_)Ro z?2oxcKiYjVvf24o9@%#E_AWT@pLITW4~$qlGY7KM0kV@cKO~`WKyQ@rpEzA_>DQMTay>3km^wWJzHOSL~bIvYQ!Ma2>ACtwH>Z zs8s;J2?4WOe=F}-+!Cj-Aamtgi6ZKy>t%l zfLA2vI5fYKThOmb0E+h@Ik)uBzk(k?N>Fd~P%P{}M``=NJ>+BC0n%z5qS)in_*MTc z(zf5nSQ1pJaddLjJ=#6KI`8gw4-_U*|7<$?%@%3ZNArDzi0oV{nvbK55Ll)e>Z36l zAe)Qqe~(5)QtzPlHF>bmuXXYeAe#cz_~`4DJa}N{$n62uS^8>8X96ya^a&t!gaJ1d z;fI3MzUkcGs}9YbKHp6x{aZnO2?vl(1@DBEw&OAaq3X<5Hye{Zv?1@UJ(gYZF?M^Z)nT0!c-^zQFf zkB?3sQ!dFWzE#km0F^M8K5pAUiolno7vD-!=gLpN7jt|*-Iugqd@D(vD?k07<`D7y zlGQ_hiz#T^k`x@vDoH_0Pg2m|kb*+r(GWi$KA-Kn1J zIVt{`BpdypM2H+1Wy;fEDUn6gje91TU}qJh&JW^DgSD+jW0e{othJg1{$RoGqV1XU!FOz9!Oc@zfA_dS z2(!X$&zwEWw?7hVE@Kfo;TU)CrryxErlULV)tvQw2D40NtZ6K02s~p!oX|T^e^Yp8 z=qzw@Y#bhfSq~WX{M72N*8A&ViIOT4STG2%dqw zT)a831`SrOuj6ZdccWfM;N(YsUTi=#^;9*!ephE+_lb`mFYoa1@cm&UZs%YySno;N zY1z#UD=~@Xxd#K=vaKZd>T0XCf3DEhC_mY)=Abz!=yYOLYs82R%1?u}!TMlRLDqEo z-tv=yi%>|+XZbi2-W{sJuBQ6>`&~K=`i3Tqrt;HfV-s5~h*;6yna+|e*ab4YhsR^+pM7U6;&v$wA5Ro&m7RM{n*R&6DPOJEquh2D zhm5scX-wy}zyrSo2HsF(fB(}PO-+dq-_D8c_S+^i#G_rPBW0!bKYv$v64L8tzF)zt zH)8Eb%F^=#5P>-$BRIxl7T^;+55G`rHSm)oy*#ug&iKwy-hvPVzop>v=so!Sw5|R* z`FZHMAv*JVUg)8ZczlE5@``qS#~P!+a)Y-4_ML%(dTc?-77G%Fe^_slp(plosj=7V zlF>(CVEB<6`0K0dtIaJ)#kN3pus1g}1rZABpEK(GR$ryHHJ8-3ma7e1(H>h{<3upR zhn#A23)SfVwOlW=OHgP>LtiWG(Ie}CmakQ;$9970*n+9zREJSIp}eNvXs#`vyk>oE zbCc9sSWUCMn$1e}e>7UHRtr)IJ4tz~*PG>ax60~n=@lw&)mv*D53hJtSeT7fp^9Tt zaEr|yeb>geGn(Z0{D7U-Sf1>eG1*PWcu< zG)?FEb6!I{NuwYMcsth_$`hn{+mIz{YC>&m<+a6_Q6;stcx}z4wQZKy*5VjeOKNK^ zuZ_cDNr!+{f45rFe_kCK?s`$8xVjcAs;s)Tk^x9nxB4X2t(Uf3tZ#E^eSD;(gU;&P z;Po|@t<3eJL~(sr3lfuTUTD+v<`ESNR0C zmR1N8^metRLb4dvDpc64FRgHc%}{BDWHdL5Mr$?Me>P3Noxia{GCf;WDqO8p;nuPW z$!ImIRJgvh!cAV`T1kcRXq8n+7U(9cxx7NM3QKET=fkzE##X&rjg4hBZt(G1T4Qr* zja!v!+~fmRRwFd4waThqQX`b}cD2;VR}-q++GKTq zbCsmFe^!MmSL+q4TwPWrjAv`DN|nv!RmR8l+l`VcTYQ?zs)V^-U1fDIt8#5wm8*Q3 zmR7l5R^?@ko<|)NLFhHY6AbWq5h4L%q{8r6TjMkIi5MOeGeC|rJitD7`y6!xU}b6} zD{%h?aR#wl1E@mB8iN;b?QJcXO|h?PsT2T6e}Qc!iFg`)zfd(P97zDBNHA4m9nl#c zjB!7_zkkJ^66A~f``jx%7+DhrO!2BgfG+ZCr&HgX-|<9s0=2?AyKjZK5TzqmnF`6# z#U&C{I$&b-s?LB`VtofhNR2z|rFDF&XIiSZlPlfG#?hmyj|9kHr6(gRvM)Ba20yYgQi%n4cj`0zpnm zyQi}8dE0npn(<8L@M1_bfzCixE?g^gZg8#d+4xf2Q{%J|+scZncrmEVR0U`o$=(RH zozU=8qn>h#R0r~j7s0iJYK2)gLxdv+2F28RU#LCOdvvvt0`?>k=A>%Fm6cN5ev6y{a{bOf>#?|KvvNHR?v(8N-*a9`jhn<8zd&{(!b z21GlbAp(>Ckh9{w=Z&!?j0MHFf9VX0P79Xd;RnVrS)&tG7ORp$l$qT4HsldFC9}Bg zn)#;r!pu7?gt%+^a&S7{02-YEmJ_joxJm7Z8JRj31bYbfAHter-SM~Mz^SYxq=Lyl z89(wy*-aT_i z+H;Qm8|+tY!ohc*BnTlgcKVg4==}Rk5iu7!W8tr#V%ZCM3U@%p0WpVv$&HMfQv0N) zXrI))G@5vo_w>~FCQg8Le;-29Ul7}AQUM|nQ0PZF-cf+Vt~0^jER+Pb4OM>4p-BMV z7s!!@F108dYU(@VN_MN`O158cB_D+=+4=L}O75l>ahKpqwqra=`nMzEN*-6nm7M=& za3$vqSF!-D6AT$g5a((qM;R7$N(|-0L03V2AKSn~SmOX7*!$y|e~pzWGLAC0ucK7) zso?UdQZcdOFv1!p#WpWn3{KA0|*AGFciMG zu(%aTibxFGy`K^aP_~o@z@(mwbW6rWz|kjga3ta|UW-#kr_ovYMS_*^=i7K{R-9$_3lui_6$e+A1Zq=@kmNebIRVwmokWrt4KSUNhOBLw2v368U7M*F7=eAeD08!@d?P=& zAFxa72A5)M>|@KmtKm8B&w!5T3T3Fay=@KFHI!jCe-NBAj@ewXz@Xh{Y=FUjkt*)* zRn;;1Cv9bgaVoxs>Hx(G1E;O5yh?Z&A6XZTOU}6P@#o%!zF9{Q5yUbtXtl_pTk29n z@RRu+)+x|Z!*EP%yXRx;Ivv-(=ILY^ym`Z&E}&8bRT9i4l6cKXQu!uHV3`;7%WW`m zcH9}Jf5|os%k*?_3gKs`s)jrr)(QQQB;{7mWT`u*>X7Y_UNws8qO+q!9* z(5w6VCVSGfg=f~|Vk2juw%DhY74?;Ke-G{aABX&g$A35%Es~3Ng>-|C2;^Ol^Rn;% zfR&!4hF>TiL&)KXNt>yp%}d0_0T@k7$fURaL*|71Xf}=&^Ji#Wo4z{`P#XXh|dwG}+d+AMyJ17r*nF>Qn zLyuBs;?M#{>rN$%49g1#&XOeQn5FX6a7wY{^f1AUPa$yijubElrk=NG?xL ze-BKSft{jd31jCQf%8ozm7rvkV5&LZ4*6VEcB*Owz`z+}U}du@$?;5%W;8Rs9Y^&v z!-bG@F&Aoq*VEYCXV))N4a|_Q0}^^j6Ryp{PGF2ZhWqLH&JY53ArgOTkLYT61FqGv zz^|YI@L2R%mx#wd6O{?9R2-?oLHt=rfAg^*;zXSIV-i5)qxn^pglw~L^6KSwk_|!(fAP}< z@-&;$JnM05R?%w}^Lo|{R+8!Hz=5b#aB>Ullq6WE4cU?wy79m+9*AAs$WFpqYS_2r z4c=r8_R|f%QhnCoEhDM#JRX}y-QX>~gqWC`wrs7w78dp&%M$;QEbKor3%g)B$Ba?& z&ySy03!Jna%;{t~vfi621gRS|WuF z@OZET|43!Dw~lLjw>$JtEQT;$eYoT5LjzO$3}l(U>QHEI&$J@cY;0^SkNoY$tKn50 zS_e{3;uBUISPq!$Y-cwJkZmeT^fgi9<7g=Xkn;uvIB(PtmJBT2f4E_d#>Q$B<_zn2 z4#D#zp3An^C-erk?>PpYBKf*aD%X8LrQZXnLoF|Fh_(}N^SBsrx4YqZ?Z^emwQtt9 z{eOssZToNDXcWaq#ZdDZeA*3F&|oBhGS(2n5a^-zc{;`Zo)utKW3iNvPEJ2}S#;#? z!N0n@X9v5A5$e71f6Q0e6(qiVQS_gLwyTQBTF{w5Ho-FB=vS;~JLP}#21HY2b zAok||-jzC=W8JcCk^^WFu@(vSf!Ch}Dq--pR@YlC;&b95}?b~h5y9h4t@5d^>2rf}Tn1*v4#>}uF$RO4&z`er? z=N1o?l_%0r$5arl^VSLswn2Hjmdb4-eA3Ob;jX`9H-Ts~O#?c~SI5NFI z1W(^oPxV^cf4YW_`WQ3}Q{TIBY;4y+4&}HvAfK~I!a%QyV+Wft*HpTpJOCb8z`y3J zI-v#wbH;2t?(f-9ku%Ly2c{sHA81@)05sgPNrWcbBZFm|gNwIs!^`clYNI|W&DH=E z>vjYep-}VL1rA2cx_J8*G+?42IulEeH3Lx%8efImf9^kgqCsPKEuupUNmGdM4Dshi z5*ttGfOwGm`TE+{v|4>Ibq-z0)D{MQ#ET5^1Pw7kBb8vtGHLnthEbZksoX|pmID}x z$-Og-BxDy0nosxzXD^D==|pQ~h7sDRudl6@9x7eNvrU~0t0q&zs(z8lm%50py9gGe zAdDr`f48!dE-z&b7G+JwV(lv-6V*a1LKjJBMfcJSFWgIwTbON2tX3atG`L5^#dscK z*A8k#JXBNOu)BDuy-|R~fq2=f30gBS(SkCSl=2^LSRl9&?9*^W0qT%wXUNRR!kvu4 zp=PL}*_CL02zuLzi!*I%Mau8FL1Li9nl(YO$F1%}_X_~6T zu1oJ4_4<8XL&@dIa75b-cH83b(99njp!lX%9iPvRDP~3fewWqcB$=RGEkbY=eRw{4 ze|1f6Ia-8zW3N}CAQ-OqW3Q)PBt>3=wMBmn($QI>-~_ZENr6^`m>y8_(TmU!hcYAK z-~u?fWAB!8aF-DpS%KW1IF%5VX#gtIn9uCPD@TWz(`v}Xh4=T$5Q9bvy#g>9-E+sD zWs5WK0L=&HjrE$MNd&5<`*=DAdzN?qe@E5-zM~lz|L5Q5|8_6`u3r2*`1kqc-*>dv z?}ihUwc=(r6`>iX8w?_D^5r5#?xltRN693}O7PDc1u1V_h%Ss=b*945Lu-kk!SsNPo;%^@P!v)1|3bg6oy54|S01j?Y8Sw}v=2FJVIM>wPB21&%d{^kni^R+P}6f5A+e?CkNi^x6@a1wTTo&D9NZHOPTQhGyypmgEW} zw7I&m-b&y1e)0Tk3~^T*dh zuJ}t16(0_j1ePm8Yt7br13C(qrN%mas&6K7uDE=qwYt7u*K!;~iTS_ie>fp3AyUUX zqAOmQ97o{RuC8#<_Uzdh!<{~P&vug;zX6Y+we_v+T~D-$$3kg4IDt#Tkx+T~xXQ`k zWGW{IX}nS53d&tV(r<}ximDlvyapcAazvZ??E}zQUoC}S-A;q(vF-f|rsW?S+|%KR z;jMN!zl}h}9iyy*64xVee-CEk(p1>9fSk+etr>eVsf|`+e{B_j-Kelo&6<|P zL#-1Y9egH&m6ePIrts~;x|Dk})v|O;RR{#rKaa_g5-=l?nMAEfLh9lhP0c?56uX`( zhj1AXv(~|Gn0iH4d*2%;FJtytcX4>@`PbwV@jIfDFYz_pP31uL#LX}O4+dFWdJ5s1cMm>Anf2XH?Z)VX6~sAwv?u#i1!xsAr@X2E8=xJ2Vj(*UcO zycU}WAi?CN*hG_Av7#{_ML;T@sbdX|la`u&G!}`Ma82Vfe?+oAe(P$)Ob>+-v%Zed z=31*!DhvLU)2lGVW`crPZ#CQ?9y znk`Xkb&I50q|_G(!zls@vYKEPI;$Xx4Pato!r=$7y|5j&!}h`}FTAuJVSDv?GjB03 z;8$>*llQ7De~|k6`)2-Q{}&QbRe3piKY1>{11Dy1db;=a=*^oWz={P?=jmw>#lE+$ zIzgP$Du5ht@GM1?o7cM~P-rx?@t+@liDv`)bht_Dz!XV%& z+!wpMJCD|N;gJ-4Tvi||olV29r>a_Z!+KJ7I4jr_e|NUm?ujoB<(~NcbNn$S>9N%L zTyaTOaZ?*&u_uDizpf8#xj-qCba9-=2;0JaA($F6^gJi0@ce#*|lXbYz1 zcs?q@K&+{75as2`8auScPcZ#Rk>u^Rd`^oSHhL|M)yUja=o+GhR;8mA1x{es6^OF$ z)Z%$TfBD`y6rkNFe=ElMRS-Q(wpJkE?viOTZ?`u_EAnvXad-PR*@Mm04u+&mwwjQ0 z5p&lD$#qS*C1;5@EVK3dr1Df-*2-`TUj2cXJ{0Rwx+pa91~NEY;v&KncaodCTX*Z> z?)JKA{JjMjZ=Kg%pVyVu0X2djztRB*e^MS;z)*=O@?I2Q*a!R_z^rmWLIuYr z3ciJi5JMoiY+E)7PfuU$e>gpDw>M;MS@DwRe^7?b6hT3>3Yj<7Q%)(4loO$cIg#IQq z?3b@3<9RJmxG$W*#V9Jr4bZ4mKV`zIqUD<__`=}8Qtqozd3VAYGF2j* z@9WJiLr6{?aqNB=EjF&bMY$d7uTA$@#5D0)88m^C{&lf!1!Xc9sSm)P_ZJ-8(Uh=K!uGVKmnGgijER#lUH}&@9t60rq4TWEkZV?gxt%7_mu_ zMBWbu!6uxTo53)Me}e_EiLQ)LOYr8x`o!2-F~L@HEej;A0L&d$K@Alsn}i5JrYww9 zcMk(JMbhNx57-IA!1A>hag;OgvCzd>hBEgV$%IyZt51U;{5Cu7Boj>^9NrQA|oX0t)%R`dBbn(2=NvDjJbhF{@}ibr_q z-L{eMO zozc7~K@6lof1ZG|%Rra9{cyWMChO5_Zz!&{VjpP2M+Wa1{R}nIaZ6vtS|!iU&nc&f zA)rD=Q7Iez>Ae&izJKKe!O1))UTV!rXM(_oAd5w!Fa^PIeZWJ7FmGM21us?p>6PAu2B$6O-a3f4`(Gp*n$hmKmhu81p%OiI#aR zb+Fjj)Ica3$EtYcAC-o==*wbVQ!MXn$bXr!u_9G8&uSPGKLM#c;nGzvpU$sXl8Gne zXOmn!%sBm&q~bR?wN@;R@6b#jCe~yT!7ZDL5Hda1BoRSNY|&M76`R*&GQiB#&?vCJ zRf>R>e@_5kK%l=K?>ybUtMNZfhS@YL!v`PvN46Y%WFPtP!8sUTr1E%0vw3ZB#*=Q3 zf2|G@H2yAuvxNU7x&<@HE#T;y>(n4aD+l>7>P4HIxlRO*d9t|TSuPS4;6B@n?%ywr zcv6&}lfqGnHJN#W4*r??P159Ea1S4-al;0c$;XdD z?RAlC@Z~aHEt-2|`DOxKfj+lCvIplxevBz8OzMc- z3xeR@=G-I>g5be9x%crSe26yjyEDq1sFAig-efZ|};r^*g7YDDw(Tu8ORtYwx>a(v&rX5f^ zmRNp(-8vvI-yH3o#KFsHo~l>JC+}V#zKR3E;>nla9v!{e-#d&0$#BTmhwtCKiG#!W zbShu$AHF|`gMBu?k}ux8K0b+qH(8;IKY#l6dx)|unLy{|sq8)RN%o*r-TuLz)04-e3wo8> z{b*(pl;EFAP@FSMp6|WcdsokJJW8i2ucnsmuNRL!QB95Ab{m7N3~j!r-9y?=S{ z7WkUY=AzTx)F=DzUhX~LuT$`vm6T7?5v>yO{?OYY@0q7FU{=(V!YuKotdp%LRK1N& zU5738_n)3pP6j=@++oD|vH$bQ{^7ATJ@%D}k2}&%IyKN%TANrats&D&TNxB9xicnK z4r@rP)Otj$lx9Gzglaq-8me9FkbmLyu*oL0y502wHoucfGT|69wWMlKpFV!HBQ%L9 zlZ(8rh7C8LGLjC3ejS;E-m~ge-D@p4KEUAfn244L#%G0ZP3#BM=VJ(2EguH%CP3ae z06S6$GTTuSVh|0JrbxRSWG`S(SP`h%v3lF>!a=|VlVW@a7>^=Q?5OFc@qcHTo>#)y zsl|mo_ZRU%E^gxjFAZIFS?I2Mb@qR`1XTOr+kAW@;PK7?98V>RXlb7H>4qwj?F+03vEP4fyAD?;|S* zzISY_iJj#|2D?iqh`fc1#((SL#p7RD!OE7%f`dfNJHNbiT^_Uw^kFS)Ci} zTg$or-XhrBpJwMl9DMu?L2rY-gSSB(wBc7enwM03>B93U<0J974S$d4JpCj;Z^5$= zUBlx;cr3H&SbpAt=lRuCJnaI)-qG7%@F{%?Pa`_cH&Dvg0SOLGqsGuB zN2b&d|1}#jf znmiOpPEA!5#xA{@$;p)J*#V(@gVeN~LdT_wCJLpV@lR(d7k}-AVn=3vP?#U)@$3mc zvQi`l3P<_u#!RizoO8;=GZa0hf{HUBZ=8WEFg{P9Txzu)GE>ub=vQjB4(g?)7|RKi zMRg0H&nG+`b+<)LWA(f%o=5U|M?S+4o|kf-W)=yMF*77Ux{Q7viE2_9oXnyKip|7{ zgT=zc%`{Q)G=EKhpXVYo&^RsStiDP|va=!8RW{-x)!9RQ9FKEZB=iwGD`p}ww3^9J zDb&u)phDQ|AUAE9z#!+kEfW}u+z<~jnS-2R;zG_c z7^Px9>xx`Y#giQRZSk}to}jkk54B*%(Anih&IM@`r~=TF3-J}|m|GnPy)ZW&2-MB3 z4upDDAEeMjbKN5_G&fdBK=6%P6VQ1#I_V@>-2>^v&ci2LcRoP2f;jkp{;&TdAVGKg zNe~DB?tkC>&+vN(-v7IQ{a@p6=$-%jKf|Bf`1-%Y-#hsGf5P9p`1`-d-w*Nk|A4rJeTdEYPegKP#$S-~hoaX19e+cu ze-VWs<^L!CgnIt+zlu(O^!VxSqdRvx`l-QyQigU~u(>XR8w%UzA^>rAmd{}-P1B-m z;d`|i!X(CMMDi^nfyVepy_%)4i!1^N+!+UptrdP~rRO=Wy$i~%*9E>uj7$J}Hu*Bv zQh#ZzY}VTXY(|3L=P56#mu~f`M!NZ6Q*YkZ8z8@V+91E&)(lg4r6npqHs&g4a4OWB zB0kg_qF&q0Q19xEz%QOA;QQMepo*=KFY+Ss*OXrRXvg<8(&by5a`~!GIDGKX4XmhfX-gu}Tr#H6|E2^l_3i*)K zi+qmLywZ{Q+D8U_@X!ITZzDvOS)l}Tig}tbJP>Nc$PeDxho5}Y4?o;G|5VA<2`F+S zSp^;Ca5&p!v4%ksX+7kK54VvctE!PBa|6gXobov@*Y2#mgt`Hu;fMOwrx<9S=|F6=WQEc$G81;YMWoB zr>^p*o`R(7cCAZKh2o{NXI)k*yuNIz5R(3XZ^sdPO5=RI5cBb_8;05t8V4<7Sl(?b zU9IG%a^Mp-k)_zF|FlN`X^sBV8h`!Ax<v7&sRW*m~QZR4ZI^x26%$wUUWA+T?D4fFl%6%49`U%DaZd6H*g;==`Ia& z>#(ShOT^G2r?8xs&Ybehr(k8%iNouXDu&1+}k7D^5r0 z=z^Y}0+6lN5tu}v2g*1-JvFMOrV;>g#tkEB5RHWxKw3<%DIi&75Euu5E9e;9E@aMl zvC=Uws@V(7DSZYsYzHIew|}QOfI1{<0acz(y7DCLu!JVhl-XGYB?Xisv|~dT(K?-` zDAc8-G58vnD-uF_;UrJAL9QFTwoj91O;K%Q3UzD$z@D!{3#x}nn9FWk#At%e6~ZKu zCvCo5*4!moyA1|eyO5e$ORyCWSL23)_)t3-yJd?*@Io zufX%fb$P7ytZ^}mYJW~=c3@MOU(2NmJzVz))2?{FN`#kM3~O;@ zqo^~w$fjdX*>Z_yjp8AJsnpbEf!qv&YS#h4rh>Rvfv=8RVp$ZetMo>oIHKEBOKeVR zV*xZr1rGENr1id_t^MNz`KndiurmEj(2jwopzz+LoopOI@PAtBZ*#6@(4Bm#(1^gh z=5TLY7c8)@v~8Yj^|acJQuGoyNH%u6*<-ZF9yr_irzw+TPCF1@tVj?gr+KU!dU2Kn z57MHbW$_^JS2L0>+PE>96ml%ZxheMX8mN;t`%Zl4>CW~}_Yt^^`#wJDZa)H~W#6}l zkDdZpq`%Ouoqs1?i1y`eOIQHJg)g53fSGzfKHhn{^AJLc_zRszWb7yO@iySiU-&;h zeERrtL}uQP-G@&eK90zl_v7{x2p-Y10y+C*Q3+t}GF5*o#2m;sbF+U1;MWaV>&QQQYGA7vt%Tz~bXn=ej{8-GVX+I{lWYT5Pr zC|mW=g60*6_->AR!%C;MQ6%q0+c z@BntV44t9V4$I4IA~F1nj=USa=Tp)9Il!shbbgHBV9zFD4!hwr=afe#LY<`=vc4k; z!ec#2l7B))BUuRitkbaQ%=r|sz7{}M92_2HfQSNAFG#j$Z}jsyL7503l%o zyjz=C#{gACv_z!=hQhJIsx4+1BE#J)0k@Zde^i<4+?Lf6wV+t8keUbo;<_mMacA>E z1nxX`aKujQmwYble_%sNTi5ig$VZp7>`45ueSiO&d9?G;b}T;r_Y$x6@|JkD$4<=k z&+52ebKXdA5l@I(^~DKP>xm#rD=yS`3HDl`o%VmIIIjoRLcc^D_RskL5&nN-`-C6e zIl}Al|8F9^9?J-?(A2$T@QGZ95gC#G8M-sgZcW37zm737*(=imgOYu<#j&ed4D zmVe8rZ3p22#A1mevGiVhq9Z;J_dCD7C412dxA+&yYZ3EDgk05<{{a&P>xcmPs9xIilq||TrmLu-DhMr?GYB90Rp-|gOiP?}KYt~! zZ~%Ys_vgdiZbUvLnlkcx@*<3SzjuoHSux_-84YWF{kz2wG@kQ4D)0tAwA-_3jEY((Bbp8NDrZVR={=ME|Kgr$_t^7Ip6$}2pflb}n-HFJLeui4W-%;xS z3Xq8rp`{0zQ{il4xFL0?AROi*rGK3tqOftQ@y_#{6>xzRlgBe@HC_`157}fPBDAO~ zH_(^b+-k+m5@EB*LL>oE5?pNrNJzLve(YSnib75FJppg{Rs;^=5XA&9sWZ6sj4_ri zq%&uo6>#JxpJO_ZOx%DrU#9((r5JuC5YGXCvCKO6qPSlD_S5=A<{d?i#(#8N0b&6J zpD<*%;v&ZPssxj9^|R(IiUL~9$v*#Dim8=Bpj zXQAmoR;Gpit(g|tRO?zH-+%nQS$3NLN8uJji@IM7kY00)p+W@OELYMQ0Ckx?wcE;nNu&k2@rux?H~lE2QD3J6M~GmPu6m-J4LWk;(zV;N zOglWC#Itr1inT*037v+4-sK`f$N0vHbw@Ao9pE%%w6I~+=*)=%27eGv5@u&3VNF4B z>Y=@v9oxo)O4s->_Hds$N3L0>J?E$tN22r+hv*jrdNCA>Lk4*#j!QT_v8u2oMUK;$ zlj!KR@q#Ey2pu0J+ZWMw6t(>B6 z>^?ai!PJ`1DoQroR)6(J*$ZStY2SJ>q=XN(BPzqF2k1g-oM#|_m@~~422l^xKoUGs z%ThQJ3#-+l^;$%BI2ALDazzR4oc=zib80<QhQ>VR{O+?pRG?yX} z=6n9#49?trn92h-?1()Be&H4s5k&#UyA|a{z0FM)_3Vc2tABmSs&md59AFwe9n4#0m7W8Pi1~xm1^)c&V3x z^h}0YFedgH%3A~H+#Oy41!n; zn4X9O-hnYPxGad3<3M5`hxIa~c@+l9lOdV!l1T#2id<@S+O#+1(+l~}^_o>?y$??s z`cOJyBVEq%7}bN?9cf0QHA)$r@MrLAI)z(h;U4!5G4s|Is^>1{mTRz8sMF9h%9C>4 zSbL_hL4S2r+UE_+Fk<#>g@JbmWdnCTa|2fT!woJ zB$92l+oaOLmY{pUT8K<<6CtvJVxDBvlJbB2eS?VHASstq>)&f9aXOxl=-;c8ByTMH z#}nN0S(jvhd6hcA3M5ZbdmXbc?^v$2ArEzUY03(G23In^pnP5p0BaQ90H*nA>>a0cOI9w z^lxfIu7>)uR9d|h#d(-XjoBdG+=M`xD}T+Q0f~0Va3O4Qw{TS~=7Y^-nwAHDzn#`y zC=GL8L*WjFM{v7Cl79gsiW8^KX z=*lI&72?1!i#C!Zs}-L43s*gI6#|4_RzcWi{Vc9bXVZ(BHRs?$3Aa{|;u#qntWZh# zBr;aAwF2F1DxR!z)GeVc$r8##-GAb!w-K@=3n4~C&S*~^9!$tOdMG5qX`hPFaaf$X z^H%rfy0)YIv-G+`W)QL%k}%?Sm8xEysx>pjmTSUn%qPB6<!5v8X{CAs0IsNmZ2FGow2j1_-$ooqqkSQtZ_qWI5G9f~ z(ISILho2A_{4pJqi@Ye`Q7|FJnHYcqQSh)kb>_j(L}493^veBH>3^AF5BRY|e+z?`fJf3wZOr~$6-0uT{vAXvsDD3b!Jl#K zUIp!6A`S=l0P{Zpb2vauKg>;0MJwgBl}@MmH66FEFDPrx!O8`g5s8;6BoM#PDZlBo zj@a}@e{nK*f+*Ha+1-tLKEO@g2XM%Wn3-@yI+2!Y`gg>SS6htiB!2@DuRj>FI<0@H zeuFQm7W;_+Ya5pE!Pd~~=7=;b7aCzaZZ&D- zs={cb0xa4Ox2ne|4zTkBQdmH$vCQg%tLhX*tjex}rvkw$vw($FGTjv!u0XJB&v1x( z>S$5kAfM}6S`3Df41YbnSgntfR}SonIZP;S1E%!nPCN{`T!g5wWrIoQl z#5a}on)EhmBM-GXLD_DXmb$k#Avu9Hq}PX7dwNDPd)jca`zRt@h`_30GZ0$bYW-`& z0WD5XIi1A5z#8<0#VBcvM_-IKFGx5RY>()n6PT7BsX%`QB!Adiwbekr)>N^}d~3>d zP;zxiR@!$~S_eDVm-sg;vBv22C46Zmw6J@9Nq@1DY8YT&!f&mFHaM>@?RzV&!S?l~ z{LV^gV1a!pzp_#qL}6dbKNL*9xcB`QLO41466Piylxp=IqJ2#$*;=U&gY@r2`nQ$z zivQK=zJ&zxzJIV-^;l;DD7!^N*kd3IqOD^b8g({t4E$*7$aI7j`im|-O+vn0E>_Wi z+1p3Y%9oma@BL)g$r77{wP*biGEx#CiZGpjWp&JVxAn+Z)daBYEj?rH(7$(b0rGjo z%2X_JE4Zg^*kw1}3tIW41*6;w?&;&7i4X(#07^WN2Y*>Hp8+dG#~pNx(h(q)KNOTx zsjmQ2rTi1+qx^~@N86faS6PXtk8`d+d}y!oS2mj@TG|;ajNk%|gy8tI-gyrNRyhC}O=M@sYt-@Zhh~U+k z4-`a%{(s=|YM_`F%F>^bK_FcrkRJ##Hk!^6=drlVW&mCwOa=j+4$x(#t6e~bg#J)5 zbF{I3rGB|YpHvVfsyf^!up$zdEa$BdqA!;lq35*@zHDx|l@e8l*Yoy0?_yxQJ4MdR zP`Tfj<;wl+H+Y(s16a4j_<~f)AVFwx(I3JrB7Z>?C?$+l2pMsZrTW31 zuYX3s4>ovcM@Q(2KnPEVcl^~DMy_AMo{j$wYneNzgl8=iW=GYq2>aO)52n*BE&B3r zN7|oSJAjq(d$n41+!Yyd1Y+MRM!%PRoho5RrpyiVB!$TE&=)^q%n@LIPfvjfgqnb7 z$nC3(?qK?Jm`6i#mh!&5qvcV|lR-XQd4J7KJEq*o3bd=<38A71^Rh+e3GWqO&vm#L zL-ZUXhm8_!IDH=Gghd_u(nF-TOO=L^s(57c$v@gGAcjitu}WQsqjc^VzT}98SvL{) zvdiS&J_eQ&_i1#?8@CiFxb_@uy`}sjofT*z&L|zjX?)Go8QO*8)lZ^$w-6R3IDh|r z8nnvvypN%U;|CAM`KaiKn8HPwjxMbj!}rA*@nDp5+PNsNrvLo>_o-uD?x%eBvAWV# z1Rl68dzd@lZGS`eUsU70nxrHfw@FFviSPm#?6GB$CdAKDkdZO$xQrH^777evi>IQ7 zYqCWaPmILcc)Zj`T1j2MPP!!6yMH>%&gc2OsEuk2UW{d$vBF#oOCzc<@)t+QU>Cmo z)Cq`Ax9weI3&W7#ab(sCqgK&iYiL!o<7`%cg9_U1jSaECd1iqVwo>kY5ytbW?4i4V z1zGFlPmWCEp>-T?TMnl6!Ed*vEC!5&Y~kDiNSNf1D`}ZEJAsM5y_APr?th8)$h+74 zN4nAY$bQ)My4%>pYppglo|fB$lG^2rHuZK>aSyk>JKSKaS?<#?qe{^jF$aWYm7=tP zru79q+;OMDQ&fGxlJD6;$hI&Zr$u^?ea&l*2U!B{3%xZ$=}b!51nZlb`G}eHL`|2= z;A$@JgzDM0jKg>89L`n^=YN5yY`H9#%dku`RO}fMT(3zozOMo_)@HYuwg3^JmK|v+ zGD*uZ2L#xV)E4hr_u5^1KX_6L>}kX8fbSZxm7i*nuZ*b~+@#cXk$G84jdO%ToOYZ3 z0jf-0sA4beL{UXp`q+@U(AWIflu>}lgc#*X3;-(X0l(>?20?IaX@48wnP6|mw1a@+xNfdi#j1xr>eYz9MpV4wDWXN$4IE_M_8B3QpP_pm9sUrZ-7}-j^_-X|a z7=22`(@-vwN}S&Ht7Pk$iBz0LjjEb#I;H37REtn7fP&2CDz+b6k+w}MODE<|*)I`+ z>ZFrTZ1?oiKFxgkJAbIAOfj#Oi&q?ZF%*E=`GjR>=3MbiW`svtC{ui)5J%%7aLco- zDLKS?xl9=0D_ep2>q!Lj7{)Y2ZCpgkwAsp7n@&qA6KYvaqXm@5NCJ&Pea7dq|01si zg%zGzbw*#-5k@guO@<}&T|lkiNSc+CwP4sxs~RD46*H=2Xn(i~e?k6_M3+`rWch}p zbwmk%=s(~0N4Z6k1$1nWf5h! zAOu#cr2HylDSz@qFilD8`XU=$w63%1R4@)KZ_&vF)Fp&R5#c>+%sd0+8yRl(n%9KI zH#!XiRsI#F;*#`~i#=^T4*XNpvR*LPA`t`@Q`i%>QebTmJ!9oy&j_I9O`ob6Yf3ZzU3bb7)>%tBI>7Jp-8quW!?XKvro@~Bpz+j*)& zVVW)?_ma{NHYH-Uk+Nv`x($BwGhjoagN&LfpdyUQ zE`~%Vw5WMmjVFrJ-CQgxJ(k-6MV-aqMzOTZuYX4rt<~Y1D8AsBO&K#4aJ9M`o7V_7_p57_Dp4^^TsCOFf#(=1I zs$MtW6DIX8L#?717J5bKc%hJe?Go^WQf=7#Jkdx^$~%m$KeFl<6;Thj>ZP?lA8t#p zCx1Xw+|`DBin0|cN7eY*w#|4swH4lfWhl>bu3ZU8mQ-O-NSX{NxVzl%62#%0tF#I` zlT6i*349;Je-{bujdP@HM$VGW%^ZX=O5A*voVD9PRH5}mlkg0=qEQ0(p|QFT$vgRE zFtH+}&yy*cCgaX5pM?>*!hBgYPv#OZM1Oj{t2_HSD91k~Tja*Mc+aEWr>}1m0iV>x z`#QN9d>Z!72iL=7KDZvP=E?a=6?K|yk^N+=xBs=Kd|zcePKv?)5W>A*ieKGfF9TqQ z`^hPKY)hZR%YHal&IHHcOmMon8O8I#@i4hut@4D6+dkS20HLG+T#j*879_)uIDayP zC%gk81W+?3dT!d!`gxoV@?or8hb5B2Jel^VgV8X)&~lC>N#+q;k1{r=y=l8W5vsM3 zP&t2Az^I^Zcjv@Bl8&TXq%1n`Uq$f7fz4GIHG9V=t;2jw-4L&34l!QmGR7<3b54?S z5|(5x#EoZo?K;6)!q3Txy!4Yf8Gn%}nUHZ5!JT;&2@iRo1r*tz1zBg&Vj`wSPc?6) zO>y*c_}p%Xg=q0$L_QBAvT-KbWt#Oliss2@Ihkrju2#AuKeyXg?Y1dyK8(m&UuKEH zIzx_HoDm${I43Z)aY}Gt;5Z!m_;jQmz3S)>W;Q<cd8BVc{F8C$Q)~DIBEk5K+J%2ahR(?!NM9fHd zr^x;=KI5>VEX)O>q6y}mF-7+ayL-V(1V>sFrDa0p2y9eXU%rpUpRY4(0y)?;?RI$< z4vevsw2~SUitRDE&TYUH%WzoE5Y@lsa;Z(R;L$4KlPSUS7yxB~TJN;UWdLh8b5^qq zIA<+lYEzE2+g;255r5|0DCf}8ErFi~27kuVZ<2FV_nGO(o9A4$?A@-i!eXE&tI?7n zrR{c*O@wC2p4b{nO<6g95h?46-rZKA4zi|RO55$wS>vfxMAb}=#fOM!bh6v%v=9~a zQb$eGnJBp>R;kmPFDD1k7)uH5qN|Q6G20m~bW{=H47{nVWPf3g2o9hushV+-lmT3+Y;QpK`wP10-%Hl{Y(vJ%!6lq1>%%7a?QV2yXKXi=o+)X|XaDqplrAXf`{ z8Yh`Hr&^Kn+Si(dc8sG@7|hcE6s}@*Pdb)Iy6ZFYP2@dD?k#XyGcR#SI(1R``GR*7Vsex+pnK zudMGU?sr5P{1$P1tV9QHqFFYxwMIvJ?*av>8J0=K71;8bM^8JLivB_x-CpgT zbkFRh=!GZjiwOs40O{^L7*>4Dks-oAsblF^CTXX*$bTkf==H^f!+lFbU&HTEL1_{R z6A2Ee+Fi*|SqRrUN>X(ds_*U~;vRH|!p{j930uK8hb{mtf;9zzmdv6_UNsbwrLWYH zt17Eup4bOF>x08eoN0}iswY!jX8IuJ=5v({@gkKxIVI%~6cG*@fgDLt1YG5xD98pW zqdW}8X@8jpB#%6wB=Aq+{RZKg=Dsf=btx_yKBDUe zZ<`G?DxRL@FAqmMOqw!C0K@+aB4{c9z~i)Wd3#j#nJWoWv6DnOfvrEZ=sHz~5vpjRve~>;btE77b|eDDhBy5DM^_WE2cLVrhhzIu%4g3 zVAK4;YCVMOA}PsxwuRUgSU|&~mh6X8X1J(8g%LlK3o;{T#qY zOisuFIU;*b`QKm2@^y)Cv_tuu&NMxvQ{hqG+KRP^I!Tff`nh~TNBI~6D%r=S^+8|t zB}P7m8N8q^%06X0XTlJ0CV!62>$y_sawX(xz!Vk5Ll41;+&x&I`9Fk?!6 z0LQ@v9{Po?KVV8d!(c6i!p@PE_ff?QvB-im@N`J|O%jl4BB6lhD%ZRtg;qs4ilTn) zE11d(Z*yNxVGucrqRo-ITXi^{P16w#9}MmV!w2Ui2&{J>dtv7vqJIbHSNOW**;N?D z!To?tlHeo%$nM|Qk^_u+76jxXK^}|DfD4sFm2}a+ztx4Y+L%eMX0Stc)DAz`B^UC_ zITUHPV^|?qNqCmL=@bwpA&R7==sY?-&dL?paS!sDd;5T5Gd_M<2oxDx@?6zFJp*(vik`8DOw(*iD*x=1*g zWb}~-zZHmKSz!;g3vml$y|rWo$ScOJYJQOVNJa}lK;UHjoPQ`9_anp{J4s4#5B#hl zWANBLi8Scna;dlH6Cq!V{Od5pu>_2mJ%f+Bz1N<6*c5VMzw%Vds}u!{kI*pcP~#j(h>vG+6_< z8!CJxyOwmhOf_Pb6d*p27Ui$ub2vSm<)N&42Ro!ISLu$8f&um94fW*9Wv=QW00+Br z5J}1p){W5e=oH3`0W6(n|LnvBwGCo1ciFT1U1I>PR(~2(dzibb@aPq3*k)Iy>6HL@ zm8~ilNa-M}t~Jk+ovp2QyL@3=dI|tg+v8S5^DC_oubSHjQ^Vk$ygf zTkq(IW}oO-M&4_|zGg!U$tZwP@0J>ke#d)_d#h!(cf8BNwG&Q2yvh9IOrPKdYNo z`F&Uddsvs02+=Ca}*L1ixb^tg0y-IM&KM2g~BWcD|N+z7qEa0)GbU^6tqB5ViLlbsn^wvoGNUMra!iWJ6k-}Ebx!iuB>Rl= z0)G)lIh{_ybqeydK(dma(^fdmE-88j7V(1z*Voq_HoN+*K%YRF=D~>PMR8vcE=yu% z2GNs%ZI(0;q)7zFg5X(YE+S-oSC+Fk8M|!RafVtiG5B)|t0Df#J~GK?3);Zzqjk@! z^ShPg=uID0}mMMNEvwb5x86OBuF@NO5idCep1f}VA8R6n1YoUWdjNep=;i5I? zS=_p(bWHb%q;C~{gis8St<`c2*>^w?)Aa{bd%W{>+rA2K+3OHw6ANLUQSK;J|90|Z zinO%cDb z12QBeTDgYxzVUbzT1^JHTw&1dBYzeR@a+z_O%Gf$YduMF9G-xb1PG5d87Y!{(+nB6 zhDSA0TT7PPU=ya&e`EnEpM)Y4Or8k-MDQ0zqc9zyMr38Y0BQ~EIez7$TlI{uxCk_5 z4mzEVn*Y`))FxQ8s`?Z7`q}XTAg)yt_PTG1Ld%g10`=z%D8T+;q9?fO34f1If{zFs zVpgMuC;qi{%kZmy($3E2tkxQT|6D+-H?cw51`6NV*{nG)`gt>58TW{FTbkuJu`ZeI zP~kT&aB-wMXVZLi2__|FxAW%L2)PaF_&=BZAczCp*()X%ELyoP8_ksUgObl_5C@ZV zTF_u+xpvfJl>mzvtSpC*b$=~3o*+D*nz9t48#Q?Zx6PQ6$|6R(0Q& zayRs?O>3bs`!GZce`iA|utaQcDV9h1C}fe`3!+AMm^CAyYg5Aj^nb7XeltG$EA&CG zKtUw=_Dn;o&)K4(hxG1cTnxm?YRZNkOH4zDBH;v6;x4Kk2@A2G!^YEY$#aJ5{>%)G zRj-}f$a78ikO62q??VPS%l*m;$lMb!HuIZVvpN!E#XTHC< zf~xiVT(h6xpWKS{Xsz9mY*&iiTg0(&+;*(n1_1&6Q0yeO5dEQT#aoZ9<@HeP+8&DC zVH^ZKOEt40WPjBtil#~>Oq*fX06nksTb_X^*mjwM0K$P4pSFBti!7do!NP2j)Y>9f zc7W9K>EFNuv)VquV-w;Zx>;^Am&zvq=F#y7%B2A8kUcRK#!G#F~T@uS+YPdwuRK@|9^-eO&eQ8KJOcy<3<Eqz-(eX*JS`n5u zI1Yg=jhW}H7A}1-Bs|&f@w#D`j2z<{cIi-L3vk{OnBzW&8m}(b(br~Z!7JJmk%j7# zrqtRZgMS#~j1`8G;dD$vs67S5>&$*moUb5?Y$zSW2*I#Ik-91@PX1036JRY# z8IDM~6-8vBrcy>gAsE|%5LlsMTQ>A!_aL!VVt?eIa$82KqLJSgA7I@b4ek(KDz&W> z_tx_T74Uimi=1cY8B3?wtty5xR=ZOERCjD0j~Xzq`G5{Pc0I!cUr9(!l8J3(p1ARo zd}=1tyMj{<&!g$Wmfz{bQ*EKF<$YQy*MUO&&TW;p{T4I&s>ScYJ;)oye3NE9R;so>aQnhNS% zB?;uwi$wWONl$JJ zmAlg9}x;~BKmP$ zVP!1VCHHYIh2cLYqI-|TBe71|czYxbj?fA3U8kHfTF8YsN@^d-BpHdD!$mUce4-rM*PDRqYY+&1vz#{)K=;0YPD&;b zxmc4*mJ|$=3o*fGO}s@Bk=!sZXR^<8WH)qw=FR?B3B7=b17jN0e=(;a-Li% zhKhVjuF%j2dh3(f0Nd@2spzX4?JjPgZ&p$;Oqzy@J6U-2)WYHhAQ0-BS>WfH#Gk(L zdY6NB)(yIjx7&8TuDzg55V`RlzM}A!l@fzb;AXvXE)PJ3cEaXiL{5|IjyVa*esZmj z$*@dL!8lxHOZLU+9+S)D%YT8l9lTzPEnJb$U`h(W!s_g6D(YAjRfYOJHpNBcBtaMZ zF#sHZW4$aD27lgeZ^&l{h#9Xpm!hrWGLZzY_D_O{oGh20qs6)AeDyEzmBEeUAPKJK z(=wZ-ynJw#eWv4H(EHqOpS0T^z{uc0rM+)AqG*kCJ77-h8$o_VK7aQQHZ5anx$=5; z=HnS1CEd;zsojxcG$q|kL}y^S?XB(YttZ>N^~4d;jq8Z3SaN_t7N94RBvD->X3tT= zMqx%iMPx5I>WEX4yh)BMw`u6{H#+pnG<*~FvSd%-u>f~)j*Ajlgij=RD=lR$<4u$E zxe0DkIbOAe7wqM?AAhR2--j7FuUd);Q%JMDE|fV|T*`wM!d=(~c^;#9t|SuNXB1zN zV`T02gMXoC&POqI9%P*o@HDfiU;co8j&b=j*tU^78r3<*o8Z5Zo?$2x8A+5~G$QR< z97c(bgo?vp4)iV?gGOCC-dA9Fnc8uaQpX>uBk`7LMA$4TQ-6i#O4wNv>~tP?x{m|G zuKZ?4+g-p&pVG3$&XX`op83GA7jjFC*(ZXAura$?NhcxgE)I}IHI+=+m;mDWuGF&m`+kB-7FLQ2YjiLs8GolpsKg`YKigtS!O z*pmIT(Y4Ay_PU4lg@4y&^k+TfVk+)0mkmCea#^59FZ2$8N)$JJ=yEU*JEo;_vdiX( z3|;3%pss2kYvtD%5y#eqv6_YRM(%=IJnd9~ZAj|!eq3=9zZPS>UNy{P(_5a&>_$K!tfA2YuV4cM$Y$Dris{ z^+J&{sq7cHD0n0}75f9MMowg|g&;XD2@EMj1lJrVCXiU#>~m8nL+0)V7%bG1*sv2# zx?JXf$Dhgbh3oCYh-Ki^6C`HU)&fYp27e^-*!BVQO3Rp?*m$8p!9s{e*(ESBVtc;g zeYw-daO7EM$w9?ozsh>s!7c%3A3!Tn&_w{qQn`o_5oB$nOGe28cy6DKnjhuE*4u=z zNNm~c)P?@<+u1fZ3(2{9@HoJis5eSR;sU_XnX2kma{qookQqTviNlsX2b4_JD1Qhb z-~f++8w6ycUM4+lw^LKp%0b&Vjf4R=iB>{FDPTo_w*wUsN=3nqB#nro#kRwo1An?v zwA*>RE#1_3v|5p|6n~C*c1FXAo^AE+8F%K)q{M53nGr`84$_`Ea zjsh-3{4&gl!Kg#mcgrcAR-Dr5t$$AGRC{3wlrjl`0M1pC01ZvX-gxgDPap3*d>Rq< zJQ2~!*_+Nq=jH4DH!tj%<@ok+?_gi5QS7LOjw0c;JzF>Ea_L$xTL$tT=t#}aK%L+% zhP1rfdv&mXcyfCD_TB#8i*}p64l4o8MOaxwgdM6IDB2dmARb}(wl^V$HGh-N*mejP zc4!T|5R(yRLkczw0Z`H}1&9JZfcp{LZXpVhz^}qb=hkYi2XR>2QZn$8Ls5-?kH8(m zkp0#r`yidwraiMZX@((!sSdl28?%YO!4=~VChAs%Bh@1l$B=PlMET>)rLFA+<*8*fZw$Og_7s{ zyxlg|65#4G)wh)ioPgtGfsnOT#L{aiEv=61KFGuy+w-T)Q#DvBZN*=$r0Z&PKT`tkOY`JWh2+QS}XQf2s%v&>b>6cR}FRxdg>9Da8 zZk)+WH`1sHi&o^kVK=;Tsg3M7)<$9aA}puj1zA*fopawNaPD>c^e+Lg_nG1&){Lw> z!w`{6KtX#8RA4K%jJ$uQETs`yc=E>n5}R!x6({9{bJTMIn5GqI2$3K8t?7PSb@Fxm zKE1oF#6Sh6&7Q?x7Q{eYSfRv$o7q5EfyM**M{!eFvr8_QTa`DRXzHz%ny6Bk-nH#Ix_!7!^J9b6W}&trVB3FILX=-Yx;?TOf{dMUx0u9IHv+!0ORPTtxI~-X+bc)tMsOIodQfy-kKM} z!~c@rK)}}Yik5$r!-rx{C@g#GO2|5@7)V{j?V&9tHg#-3-NHG4beYN_wA}guf zDqzSqHcBDVQ6ua=HC}Akds((~mwSJQ3bO*a#SqkV8ylrFk;Ae!lac?0J65|b+Ea~o zZ`W@l+v%vh7#!HB;`=lfdxdxRt?&J}t`1#tEbGMSZeKXg)7J#u#Nq$OsK7=4TRI-Owq~uaQvEYFyEpX!X5L zwf+*Vyn<3`CM=AC=Vt=+AfNLQIz3qi9fM(vb}XuOCNjAKaZmf~1BA;>8_|hG<7^46 z88?66^2PVm|2_WO^k%y)Mp6XOz*mE-K{z@sQ0(|1UoVjU{dc8 z$4Y^n+f#m&vJss+tI{1|ITm1ZZTi9yzw345k+-iR;tRKcRxJam#wepuh4%m;wqKOM$vkqj0HTPP@&U$`U0?eta`?D znth`DOEm zCpe^9n`+{!Qy`YDnqB(-Cf8-_U5&~_Q<(&qFL&T~I*3w*x^8X4&XLOQt3ZRM}%`8S9_E(BMYN`PVS_vZp zLL!RKXkS*YLV6PQ*bgE5U0RR*>ea7wAMNf&g#BCx^Hm&=#bw#>aO_715E&k!Q>7UL z`&k<|39FicP*e-Mh9O$lge5@RDI0$uWfGt_Q)xt@_yVP$>KPz8Vf_>N`kz9_FaTVX zgu!myb0`rF{!&t^u0Tyz3pF~qi*iaM|D+i(K{6t-BU{*$zzeZf@e5|k4-58i=W%yC zB5cc*9}u>!UbseggzenQlu2KhgOsJ`lmq^jc=4J|a#Wow`|h-ne*-g9Rt)6aTJ{o7itDNt-lQ~n~qX6PpuTKsG3VO%x8 zB27Ncdp$@AS5I;b6Gqa`b((*bFLQo$&BPv)u%}@rO#a{I(`?$vR^ z)h`gNox|pwmcp~~^;p`NTqJZmOqJccw%NgF@Dxif+U*M|#=Nj&m!*C-#(%xDHf^HZ z*B0m08}$WF6?-BGap@%ISK^qH-6Towj3vO|ih$2N<*29v6A}pvDW11hcOuPlT3bh+ zB0(p=y>geiz`0zzV>o~Jzs6uTVt=XJ;Q+xEtb}NN33K-?EMU-^I9)8*9kG_Fnlusd z-zBojC4y|}3m;nvU}620i=*CZJQ(KAIj2mr4eK1&Hnx=G8g~0RErFF2`9hFeN#02B zA{{28y&WUu>T-!4Qs88$O2ppGIkEaRrY@?*p|RCZWk4^6`Ez) zGs4~)9LG6#AIb2Z_%uwFt=Sh$_=~i7ne!1HzZ3T^UWh=(Eyb=^H_fQhNAuY@E$L5q z7RVULV$-aoJE!G~Y%&R>9{7z(wpG%rXcDvaZOUO=LM!HW8=_)@EqSgFBIv@a&WlKX zA&ZrjOmq@Bd#Qgq`k{19;@}|yC0idsBIOJNTvK64<#>UJ-|lMx_$^=MY>Jz%B-1U& zo*1gM1VWy~nhvy?lG12I_xAUSO#P1HbO5b{EDnA`qv0>EnB|f^3iFP{@HO_x^41`R z%9`{%!bn1nxiSnA#AhvE^8CuA_2L?A$h%olE|(j6SoD8OIbsCEiL~3k6vijGtgmdS zz4;1*Yz|EPcAE|85Of43dg6#Wm|Zrcw_NJ9W)ED{e6@Nu6MM&&slq@sFhJeCrx+2# z@zzqb%&2;6ENp5DdyAJ-T6csBK4kGOp2BcTJ_d~gQs$Ic-#9RfNElj+d0ZnC=Vkp? z2f^6DX%l~ufj*_vcxwf$bi)RRuIXZ3rEGj(E+&ja+-G*egvSBP?_*NmXY(Ml#F73k5aTzJ@q`DPU*NM zyE@e3{8|K45=0hsw~_6K25(*1NjZ4y%6qKT=5BvA`x3z9y1vLp7e@0nrlV=fLHYHS zZkmq$+WE*{WMe?EZe2n2*D`NG59=nF)rff5G#x{LUiEd+G9|8}J_z^BURK#hYU~q1 z&8)Tl6MwqKT-VMvn zIbwU6@5t4?s^!N=?9fj3{32!N)RnJ=3N=QV<1}6$uz11Raw3OUS6MaaE-X=bBZtfZ z>&DB2=yDMP$4!z(q*5mKZ|4jdv4uG5JW-{0(b&X2{ z+$ES1S6NYJBZOA+oOu~2WOb9onFf)DfQ7THTCHmks3>^n8kUwr9;=aOANJ^gD9VM~ zLe7vkeUGhl%@lHJp(OTouu~{jQD*|!G1D9Sj*_E*Od+H!muy!Uak*l4bxk?R*DrtS z`lLb${VQ;={_)MRCEHL9rutrLwb{Wh63)Xh?Z{uN$htPwZ+FV*#hwcsZa4O1@FH1p z7)4wDf)jxGr;2d>t!VE`Y3-CV*Fzutwx$WAM)a}$eY-y3Y%`BQqSw*0?(zMj~Ee}QG+UltkNy^R{&(nYLC@o3} zGE-B$;r8)1pHAV5SywKpYox`Bt6>*?EwhHTV)I$8)OCe!-JwwQhXE~+HDfAwJhWhB zZW1Gzw`C$cvBCnnG7*Myde7{1=jDmx4nd)#x%M z5z7h1cz70g1hDBUip@>o{s@1Wl`-BJDwTql{aPZ7-HV;h!-F%1zgyAzR+DfP5P7$9gwnwW%3)sWSt)J_iJca>O@ zHiL01P$w;Rpg}pAVP6kk_S@eS<%^kbajGg|O zSn}tLl)8HW7B3CadZd3o8*dSSwJOLZ6+six@|m@FO-K--?<}yy_351!#r%rCz5*Ph zv#DgAi$0A}KW!f#E0m5_TppLpsNN^Duy zt~J&>7|p8m+Z@knvsgTbo@L!m?n(m)1(+morRV)TW?SyZJnDaKaAoLFIj#s=j@VFL zniI1*Zm`hSC&xyTI8?RU&SN4%TnnfI&-oX6Hhcgqt4yvsE2RVyRT;gi%%|{lD3f@E z4jv{GGNS^LwR$&0YjkF?vF>1A<;MNv5h2GESywXao_%$c4w6 zaE_*6oPue)lv{sOGV)pl+DXNY0#hpA4H)yW>Kj>q#m+`P%8ymcN++r8d(~MJmyu2` zA~JD|H{nIYLR)hH*B2wEQ8s99fwkf!x8`)7l07?mvv8vuRmJ30Voe#%LU~*84XPd{ zbs3F%1uOyNb&zy}DrLtV6hnTM1{4QIg6^%xu_mpzsw#h{H;r1iZMzCY5P69iNyW^B z8~VAprwSo@Ro@58S!~2gISAK`p1)nJpu&8y^|A>zFxrr!Ne}JZ0iSKTB{(J; zwHaoP0L6|pt*`J47MOi*>HWfbS6PbIg++;C-HZJ?d-Iwtt0zD57@?2fg{lolY;@k0 zj&%yKkIjEAW5Q-E%y!+lfa2_`-+^k3zly`*)uyoJ(q+5w^3=@N*|#cEsi>9mK6>Jq)_@n!27^YM_5==TjIEn|WR??JFr=flcF%JujZD z_uU11j5UA_)z7aF-@HEDKUJwLsvrC6`5|ND&hhiTH+%0+Pkwp3@A!nesgAz=e*gK& zZK+-#p6tJSx%YhkwuJ8w!FTVLMEi&D4{opV?fa8cKXs=0oZhMV`#+!TA0FS*`o=_+ z#y5Yav)bO6#x#9Rb=8*Zq{7m$^c)Tzyu%gYtcGsLdBU}2D&ZMCp%E+LX#;GVIB9EU zI#te>EA+NCu!kP(H3916R4q|0DA@Ox2_Rb30xp!Bn-LhHTj3VUVQ&qPBB|Gj-O3YBUqV&^9r9sWDPz_x`a;=^b=7z9Y{{a`HYi6 zP)zeOAbhmBNnWHSnBQNA5xIjy9T`e!_c(}F7iodf#^gi=f@s2v9_>No_!(enBh-J2 zthbfHbcd=7g-9tM2QtMFy}?1QIhVblRtX5G;L?UTNOq2-jEL@)Rzn&-kH|(BP%#y~ ziYn6t4a`!_y#o1`NMtZE5U+2J2EvmU9z=gC0WQi5yI>B`veeJ7*cGvru8HLe)7SD!=S8G< zDp444_C2hV*XzW7uv6M~aqz&l*2P2_o@>N0Wl3H}iJm=G=NNro6)zLK0 zidkOJq*PyKE`TVb*Whc211xR{)3JKtJIpT9W+mfQI`hJYp3^2wPxy40kEx9p3i@B^ zhFmEGQZ^L?bsP9kC}bl^tQLP7%?&h=%lpbT<)Cm5xp{i;#rbaGD4APgZ4!dQN{onW8`lpk{S1 zQZ8_y8MiWkb5Erbk?0QdMM1TQMdZvHw@1|EiEbHI*>#bc7^scKUurVxa>Nfz;LIsq zf}&Nst~kp&luHF{rttEPAf5ag*El~T{Iu?0R`EmP`$iKPGRx&M>esvOHqbkL{2BN9 zauqXcw>!3l36`v**WiD!>Liks5)gBVE%Oqi5`9j(TU%BoCnjPQjS!o%B`rIa%K)H) zIi{PW*>ujS9si9VxIxEN^fS560NIMc*lYYbI$-y^LwJQhtdfo__D~fhL58I~({O*Ll#*|pFm*HthQ|0Y z32_(j>&PV)?zu6}czJ`|Jg3as`S3lW#0!Zp7?aOSVRWt}yRcEg#YZgVnPe|EH^FRZ z&b)Uh0Aa60%j&8%C_!!HfNbzXp$^uZ-*a0%jEM(ZLwB!GbW-2h#!sZO*J=$3(kWWi zx2%@{W2h=qRP=xOYr&_{DCS3@p&_d6_%E>Qsv=G7Q0@Ec^se1-0HJ@U>OPh|P}vYA zE8tgYi+hu#0ydHFRB10OZiUE1mQLEQ&`)Yrsc@2W=jhih5_?x|zn)PxK5{Y2semdo z;|KG_ctX#LgkN@M`7Dft8>vB9hmQ)P%R|)*$h)Q|AUl6B2K%O}h7faV%hNmb%BDbx zT7gW&z1F2w=08%2^FP_D-ZY<^O_N`D%zX!09mB}W6)e%+NNKNL?L_Xr6$kZTh!d7Z zef|rMWX!)+K<$Q#*RBN~Am9*w-Ldac`~?|MQbKWmVCr_8zr}P%p+?*?CB6_PQg@%& zBD6BK@iu=#_1cAaUQAs^aObgHRaLU?Fk!1o$yTHQY_8cfxBFFJ0q_r7Rf~0@rB!t~7Qa<3KK|QpVbh<)XP`ceC zOOYli=)+Y>QeU#YY9Vq4vvwQ1%_9EW+lk+BsCSb|A<&k90TGdqX>CQ6gzqWV3OuC_ z;LfX^5~#EFy%)N^rcrP z7nOfjp(+i*D6F^j{R|PczEZJt?9DR7zE#q!%0#d#|4KBt)DzZlu5RU~*|L+YLjKSU zoEOKtqr1`)Ib2$=l7;#VwwUthf}f&i;QnuI)IZfA zm%%O+(NHy`Yf`JkyuPbzLwOB?keR?MS)zZBIswmU}c_4fb~~|MST_rs-uD)-*1YIs(IRM7)nvHo*w*IfVFdLBK%;m zir_|*`sRZY1UG}aJM!?*l9-7>{*XXDg#WJnE(`&`R-`ZDlIW2@sr?4&1P|=1^z(mm z`RL)pokzs0=rwE*`l7%Mc8{MIXfO(L=jWh_`+?ppmq=aB`V1UVtf|el8WSHaHKzHA z@&8my(wYR&&8I;JVE6%rc)1LP$UG&&LxsOV6=QBDcT$?)B=<0Y8dpdTd#cb=3-qj& zTzFW~>4-axm~MtZBmPiS!5AvTdVYUxNr9KkkpI43?~XDFF&Muqt_?gf%v{KA#4ouf zB&4C*K+Mc7Jc(^?t;8#hon!9cE*WmpRex24mMIBfYj5=IXIh4`s>m(7u7ndI7H|{z zf!-v!da%bX4>SKv0ozDy4rDFlZ_lU~YYPyQ1&WyKCr=^swT0LVC&@_Kkwt&+g?Y zf%QYw858cO$2&O#14`k?mo$MUR=^VNg}v&j@G({=dxh(&AZyUz4f@S%g{D2^{!&cU z&KbKS*hTH%fsSfmOId#x%DKPWq^U5nJv1aC$bTcqC_)T!h35YZslR-jhki{(41FP`diQUwT^FrTi9Jk0@M;s}=ngx^IX_sN|=J}rl6x$92HZGF+V^S{m9qU_nj(4YkSEaP;bL%a_9eA%G-`xZ2 zvKvaL3V>|Il8JahH0Pk6OAujzIZ)iz0hF<~Oe8|~k{5CcM^fpB?ehzvP?_Gz#Eg$6 z4N(I3dwLVhX*GXgn5-MYczb_@veoK2Ql(oN+EbrHJ{;izK?NS=^{t4y_zR{tx6+FB zO>gO5Ubd`Qy{js*Zvv)TstN>1x0PIRyB@Uj=40o611Egy_m-Of-lL(_uz_qlC?pPv zp`oU(7R=pN!jNFDh8_lO*gLhtg9COSrueM5&Ti^%S)+e%stQgg*vE>s1MH(B8~E_Z zy5v#q51Jep!inc!?iscN0RY{=R-{0;qkcXneARcqIFl>w8G)HEBss3bH0EvLRctB$v~}YwKLMqY`xSq)svM7$jbL z1qx>_1rdLwqtBa@t~wM|q=n#>s7Na-@B6HnT^1mcE>B9iUio*JBZ`$NKrrZSZE zKZRtaYtmWb3B>VqJ0ZzQc;ip9J-GxsyeGNrd>wyL+G9;g*pAE+}gFbn7vXdS&+ZdC|Pw1q^ND$C##{N z`Qci&B)@OPz(>zRrvSwcJ03Tyh>|LvVfGV$hY~3tRF8JE+@qCls&zvk7Z;ZGNC=ZT z{WX80@gfxoAL2z4Q8;+d+LR_yn=&uOU?;e?C8HlIoxg1W&#nwY-%Xm6SZ^I4$CzZZ zoxpr~T9qs0bApi4)VpRgR&rnUib|40ylSUooCVOj3n188R441Da-YTj#N3`gCW=4- z!M=7T4@ijI#(r^TKY0=1#@)L}a0vhE)uDf+^nF&z*65M5h&hWPbM|IZr8r$koo2%{ ztw^5wv=VJv&a1_4SI)CVOrjz0Ik3o3vyh%5W_?to<;3LqLDs#13?9fLe^4^x7Nb!TO6;w}5ixtRh#^*V{+NH{ z-rNwbL~mzrrK?NlY_Wd@570fChdgb}R>gv)WFZ|)pr(6Nu!wi}fw`lSEmF)P5|g2u z8E>}}E;TPY5GxwUM(5k1G!bH-(ajjMnLO|ex!Q-N z6G~H+NnIva96uJ8=ptoN9#0GHYmeHGX$nz)l5k3A^CTJ)wAEL*750YROrtGcJPzOcF3;gxk+_q*wV6ADP#MTe~xRjM0e-sGFkIcO!ya3Nk;UF z<&aNU{JN}GY<;7DB7>yOZ)ub9maGX{Y(pH>GKSmts3IH$?s&Vo(s-!m=I3by|CUpmv%cy@8d+{ zH+w^Du7}+?Eqvai&ZF?QGX<4z#GRMkLt@f*wph>q`gaG1Dd%a&V2nL_fd1SY437#O z-j-Z;%42R174mz?$w7adJDO57c0wf8T`*kPlm>z*+^tKhvz~<3p5%CTVx-Fu7mTdH ztxmf&Jl-od8qbo}xCDWQZ2>9DIT$@XQ@ZVN$9F8WET|Nx>cD6nBh`Sfwktt24GQ<1^ao1tw$(KHlCsnak z9YH1IVBV{|NveZ%8YL%mM?V&aw>wJc%%%bpW8jsj0OD404&>ZW{v$}>jhFblcrj+hBX8VkM=b zR0)Xpa$++%tM@t+5VI67=4xF!YYoQYz##e$h>t6-RDm62hdLXK`a(~y;we*G z$ZmhfoHK;;2J;6SNFGUT<@t%!6jhp@!gcu)Be*29)lDA)$3A{Kk?7%UK;6<0XNd`v zk!E*HbXg28~;vE>cr6yJRjY4k%#z3(X>r8;a7CIh7@;`;pdU6dRJ3xNpBmlhK zV+KG7qR6uXW&kB%LJ0H0PAw>=E>I&3-wW<=Hf{P`mS?>l`jf*zG;97)SQRBYANig)TYY|MU3E%7chB;*h)-&opA&Z zbg1`~ZBh4sx)!l>{If_w(KJ<{80NH2TQS_-q*f>$)G&o$ zvHG0*j@H|%tkGF*r8Qs(?a+y{)FmfT=zNg~0g(au?mPF%!U&RlJQgBC6pw%6p%NUO zGUEx^q|_md+?wxfW|3#n@$#ICUg)vw*vAi_R5IBRNIY+8N#xRecWJ&`-t)Vq`mU>b z;n}F9qhv|WQ#!ezbPMP@1Txg*%HWr$ACF-Wig!(Nvbh7cu+)4L%Sn+fX`$&R*g6Wa zz^myq5J$NIs|PZp@oF;o4RU{GwRJP7w=`$#8%UzXb;=WE%7cZ}Z0Nu%%BP6`JnkZ8 zIuw*!kAiYbMz3YD^`LII;9wuX!-G%kS3en4eDH~S@soiyAqIjBvz`o2H*_FJcknO! z?SBoHbdz1NiVw23sV;#t3&@-XsK?f(VM1T4fiNE$EcEQb+e{F1{!4#-|6hapf^BQ_ zj3~(IkbAWJ_=}iObvzM1s@HnQ0)A<|R!m||9-GXuq)svA^i$kQ1kAW5jtN@7_@d&l z*#Rz>=@XH5sze-s9z#VKHvg17RxB{{&-{%kh-ror$W^>h#3n3VPHF%V$3#xl^s!<% zk#bUkAf0U}xHrw|BE5fAR}yZWESTXlK2n)n0Y)B^Ow$YT3)QK{EEr|v)+h%FCE5k# zmTuG2Ziyugl1mMkydsXgO)8=?Vi8wHB-j35V4kXJ z4xU{r2`R}{u5r*Prasj*Lb(-*aMvx}f`>hAqcR37f>z-#$K&!1CQXv&TPdk)vT+7n z5?Z@MEf1*WUoqy%x-`|+pe?|xI`<+KCBbNBIHnEhnPFp#gf;u5Zi zp@Y9%=_sCdMUR4mIi_g4K$Wx-?G28w%V5`cj^AKVuvcoSwi(sMj}{_6SZbES?L9JWkc zkZ^wt?_*_Nv@4o)j@5qGdpmr0qWU|1cXA7D_Rx&XEgr_;8NRz_;s8oE?}hSngGB7W z#}91Brj@;0GT~{6`e!C6FLe?}I_(Cj0gVV>1^xVyPX%0tbi)1+L?y(;REHslm}@~P z#KP$yn8?;?)J&g_PG|D%3;i_4B7DrK_VRx@lZ3~E@0dL6U87vUq}Rzde85yUFBj=; zI4`dUXmdRWE=sO(?Dsxi&UFZ2Uk7}!ehT?+icYns3c8la{it?WcxUDcYg~8mJ_O@V4Y>^eN&=|_!%X?9RDGqHUjRomP7HFKO3WkOhvgcAqjeTgWXpu< z6Ip9UHp)}(oiw>lns8FO{r$cp)SWZufz*uwRC>pHs`^|^)4#xiYnS6#E7gCOj=u~U zah3cMs}7&UwMRbDpTFkW*7}67$--x|!RY*bF&Z@4`Q#JZKH6L8@mGO53~4tr8$jB< zORA61f-KF+bTz2Tfms<&!-M4>|2ePDKC(SVGQSt0!5s0163wIn z>zGEo`4xZ^$Q&U7zv_brJ%xW6ba^j1jO&Sg@E}}}v2)*1v5pJ3Q#aiSFH27kq82dF ze!})V(q5D7;jdU_++Qyd@V_X)l+U|W4@0kSSFFx6zLI23!rJmNo>TnL0M)8~hv^_H zt7f3ih?xEb9N>d|ld&?k-Kmd{?Qj~_6SUbepUh|oZK90%RP|F#?&*Ib2)eI{b6}{$ zyRr+1X0*O1v~rYT;M>UNgaqgS*MBh+Hy4Vv1eGGp5j7Ih(>@ZZ$h+ZjoKV5yELdzk z-9Xur;5pdd-%RRQe(AkHZ!;5(cGn?*srbL9WBoz{qx=}C!2)lla5WGCht&g44;zgI zXe-BJW~ZOaLTFO}>xh4j7Ck@AoCK3P`Oh@6pWE#qxfE({5DQeP9~A~!o4OHv41U#+ zTY*&SX9YjO?o62E>J6KPgyp#WHX0T5Jj-w1loX)(f`9{+e0@j*x>Qg7P`hrQsW|g zJM82=yv}$DsT4(K1R;iWFlJ{FG_#S6*GxvExF;QAgVDs~aZE-7xfcoX<(g^+CTTd@ zat0YJNr;W>Xn35WEd6)Igi>)!E3bx9t~+H$bcRbP(ZZ$Mm)tB%9z@=AgIktJpeQDh zo$679fP3(K$a8;N3R@CahAj-0G!vM`8ksHF?EBrBP5}1D#h|F(QPFQI!D%oyuCq&L zyphW9i3Q^C5A{(?kbBS-=0Qp_2YgdmY<0B(n^b_KtEQ#zv@b2moCUn^C5TBcJGO0e z4m*1RFhXPZ(457$4uW68h%-zg-YEDxny?kclX8e=0r!8@$xq*$Jbm}_t+1q8VhU-U zyW_42h2Majs1Y&#!=$KVAQuK3_- z(yQ&Y9a?`3ortltoVsFaQvrGnXxlKHZt#h*)3#ua2&=CLwB!FsE$-8Y@2!9f+jw|c zTlek+=6Ok!lzO9#IFTn_VySAnPwPUwium2pi3zcgmMW0ST#4?XDQm=~j^gX8tgkGL zX!sar=I;T0R|%57_z$EfarZRAy{0Hjn4~PRfO>yjysJ$-!e%V#fyF9@@UFefvO1!V z)eh?*z?;+q<^{K_z*w(SDeG$6tV6UJ5Ivpr)5vhGXrM=k+VFtuU=0>j)EAN=2hX#} zin-RCh3wl^n&YvsmiaM&Q#zM==t^|OCM`bz*)iCdqbyzF^P5=OnMH=b@_jTfw^2dX z@gjeouCRa&$s zeq)k_IB-F4>RBL4>-PfeU9+CP9BEU3401!j}H8s$$uJWiA0!B(b(VUPKTRo5) z^b@f`SK954sUN=Xum;=;Sc3+FxtLg)tIWifM7;p9Y9B-Fl?giorG%7%^ixN^L<+1S z=9JV)G|2DR^E_FxE~<;5vJxpa^s0-R1XUqjZEw6wOxiu^<}Mb>%M_6 zaIUx_*Qv{10-KKFUZ^a&Ry!ERwS!>{L5G&)Kpm5FEjw@ExbG-n*EX|;gwbWz9RB7; zd^T#yH7PaF(>jP=+rxuKgsSB^H5mkeEwMvE(77aNh+wmOVTy}J*}9?pA%1^hB$+mz z2Xv;aSBW%-2k!}CjWIm8+pa;;{S zJhPnj5}`t_BryW8HL`SgG}ZYNPSUgJ+72gY=?U^Jyb_UYvX&>R1dG8+!WYC>pOfb? z;(kB`A#toIB4M2XY};sa=n#Kz;kocAFYP*bj5n~HU<_Rcl;a%evl$ro+=`48eH&oC zyHPN?vH(w&13zf%31&|M*_%sNr`zg%LWv4+O)Nu98Jl?Ky+WcD=Ce{+kY5*i#}WZ7 z68MJNuYn$q#{i@XK$dD!mFQ_u2&FzvNCx-Yz+V0p>~``-h;D$Ra?yW6gXMbT+Snu0 zX0#CFZv@BCkUcv#Dugn#@wkwNNyvn?m#35#WH?^do?z%$ZaTIk$f45+Fe1sN9W(D4 z9=SEbxW7lUkSYjg6SBjIW`X8jsfc!F7*3`pYPL$P$n-r=+lY}0?5ZtLeuMo6XueX` zX)ITbWq`^nC#+o24{v|gVKemC>5=k1g(L53XQp(J+;vQfJ}pH__#Pb@7bsZ4g-ilh zf^9`}x9%GERJ?+L#`1FOZP9sf>n*IUbA89QyYh+6rqnmhd%~H;A((OItD}2$b_?Yv zQv(gQ87qWR^p>k&9pqip8kYk14y9Rrx63Wsp^Dt@;duE4a8hbKxy?F4OvK~t59%h-fqRfpm#FXsyTXBoIdSBlV3S8>v-%s_e_`1YRP#UC*XhDlcgJ2P|c2# zZfPSVrvL@1o*jQDkI7|-m@#lvjVM{#IG)Vv6I&^)9Hp>@Q^_13QZY{;w9D14VX9rF8NLIS508n|7n1olx^hp0@d7ol ze78IAzIf!k7?aBg9zXP$c*3fyO-0mKV_a7MGoKd$tcQPlWD~{RKEX2FFj%&Z?y4m2 zA0JgsJyY*fyb*EYGvxl?Q73|feX-c@!}!;rKm+Vv$O7Dfh*4sp&j|JL3?Ve%p*%Al zUc=>tvSgcQA=4Zb2h58eXFw7n64)zlSjN+{vunECX8FaL1dN@XMaQ2V9Y2lkRJ(!eZak*?C*eM1m(yF;z}h2$qWt%~p`dDbu_dl|^Dv z8)Y3rZBW&&YyLvpSf9}%19d=mc{@8wT2ct-TuJlhw0cIbPOGY@UAw@j!h^ICbJwg~ zRoCP3Q2a4DJA3l>&8t^$&Yr${`TU1da9PVu7Hxk9L4pq3bg%VYm7XXEF&P#p6_=mjYz_Y9FK$nVNEunms?198IxfqEqz@$(P=e6NN!fJKk48JVA`sIIKC3VBD&zj zZ18`H4B*~M&J=}Al%DK?7?{c6pRivKE&;2=N>CR>9}l(#g&^W9RF*ZJC>V5~+YBF>;@qoYJfyy;cp&QCF8}(dm&{`mWCYnB zU<6U4m|l^5JiddbHEB;mv9n6Q6YtllI(*u&^ip3v}q_G$TAW1Oh0U4PL(-L2BQZbB(<9qj%m5< zFz&c?JDEy!Bx05H!Qs4<>FCA=(-)`p5;w6gcF?R zK)x5TQD;Dd;N6~p3)@4}>$`tI1u;4zj8DFkT&(?m4y~64_XG&z^a)33(DPxRc>ITA zRik?W3GLI~J`St^tNI-c`u)dr+57wT)_dJi-4KQ_^Q>cj8l5US7yCJfYGzf@dH~R9 zyaTCo24d~WZx5C<&)S+gR|k0}0|S)1VE~qaf=arX$>6O}YOEJc&jEiI4W~I}S3tm1 zG;FJ1tOsyRvRG)cQb|2PUF;`tF%1o^#KVt{|gb?4p8l^;X6cMq#L9 z06dkgehh>ug=3R|3&wx31M@HOs$Swt7EMykRFjn8(#-F*Q7ng4<;2VX>SJ z44_t_zy1ig52vH}*$-h4B3U z>Ybze_fEh}b64-U?Zoi;&OC69MP9D(&TvS&0^;bCA>&f;>SWD|hVmfqBCNH&PvTvb zPs8z5Jyj0%QLxG(n^*AaM_2h?AqTx1L+`BZF6n!C*Zr~`8Wjq$y7L9$VC-vp;yz?h z0iZ7oRfY8L+S7lNYm^%^6taX#Cs& zuI%nVL{4u-JSgN21_|+w=5v7NC6pH_@X@Yb*JT6DM#2M;6oI{3K|tgPs>&Q9ZqlKF_OMq~tcMhlmwLWE(t zkWMZbwqC9vk(blOincObwF9RVzjju4u+;4klJ$Sqos86j)}QdseOi?r8XkmesYdrV z({T6o%y1E}VHJ7 zt>fjL71z&xRNZmkarb4t@c<$b5#cg~0C~lc>QI0%W080cLv$vWw63#rnwF%VY_n#Q za-x6yPmI{<_%h<+X2jz$WF?mXnpBrIT~|C3(E;Kyi4lHyJZ-;DkERbFwy}9FiYiR? zE*_n?i$$t$0)-Dove;jN$8-?Emk@ntdd*Q?NGdbU*t1 zGjO`+ccqZ9lJOSy(HsYunxv|1-LPT61Go(RS)yL6oS?eAHqm5AdSYWDhz+573Y$S5)-D~!4+|gM|P{l zXFT!Zxw&NTWSdk9MnF1=Dkp43veoKTHXNWOLV5rUSaL%9Sp^|aqv^!0>0&@P9Z!F% zIAR;HeVAvKZt@PNxGulXjBWgflEy0S(pmiU8HAEhk>UyMGizeg4#o+Fd73MtFV53P z|95_tJ^XVqKRbH(clhJK9xvMZmJElQI|5jsBf&L$ zAp&0}^a_Mx;54g?**mGRYySRdsc;e^J|XNPa4KRad%`}1pFe*+m{8g9 zSqUv0Ozv>vr81WluiCB3lY$(+z2FC-Z`B7L0Axh(UCl!tBDiH4>oUr_fK&FzbHW0<^ZTJsLsm*5H=)O7f-# zKdzv;d-=@qjCNl?*2EaNeMIbkWh_@IG9;<#j{{XM(u!0fpe3@?(}HZAmkUeiqR9?G z<|@i0#Q4f~y9o4IF;miGodf-X-T-f9kcI$aSJ-aH=5zt@%Q;=dw>9M9IF@Ku)G?-w zAY0;Qs%*0QdwTPPpVv`kYo(a(xSlr)sDQzB&go*eTM?>hA zbxC1*4@}o`0Z4nN82JsmY^P)DgRIM3Ek($<8VEP7;iM5z0dm_vKN6Wap+~Il*SU z&=*>~ke$;6HIEbVBch}QZ`u@iwb%#HO03BPH9FN3Ti&P|TN_VIhDZCb zNm3Nn7h4{f{f2O^qwPh^JsCmp*mzueo3iY4Ga}KgdL_w-JtH%Ij`3Pa<5;gGk31#S zEQ&Z95UNGWE(ni*6Lt~zG?ZSkJe+xCcs$kW7hAz#cDLyXTOli*igXvD$8d(H7C$|m zK$Rt+#2rZ?|AxYRDvObOI@T-_;iQSe9J_~KSJHgCik1B>)Ai^cB{Z~({gZ;3 zFIP3@vD5Pk z>)FIaW%HWzg~AB%)GkNxA#u4><6C7BW^$pqJvxnlS;}OOPWd5qj#-QkhPA+pd3IZn zcGP8CvV*R!PpVC7^mn=ls&?JO?6B0^xiSZcX%@{(aJhtecI8p3naiWp0uvZJwk~H} z!U9wZn0d39>Q`a2;K&_YBIm%~#ra^<{A?f>f|22S+MCf@>^v9r=5=-f9&pqKgexH9 z=jfh)t+i+3^+79@>qE4xM)HuP%vEAOXnU2FM;qZr(s&#Ned+cSon3F0+Mk>8U!piM zg{w9SmW(rz;W+jcCOFvl*hW_BGZA}(cNDQGy8?QxQtbcsBc+0$iYBXLl8`W#k;N0^ zs0W1H>nl~fR25`BENu`?;G=cL&uKGCM#vU_%A1=}>?iG(uj;w*VD!I64{VF{6WRD@ zlD*imd^ENKx*vA8-5w8?mH0==Pt5z{xD5z1aeREY<49UiQ@RqYpT^^bVWaGI#A4<9 z(gbC7(_RXSHuf~CVggt2C~(Rdb!PzN(5tk@l*Od#@iDnroLAY615oi@idX~vpoBqx zG#ySwuNbEc_jz-i>08TI6MGkOvj6B%Bt0^crn5!7>~=$o{adcY5ZPy{EqPSebD3rOmut7-|8zFbRuiJYm*``^_=xCU;^iF36Mixz789# z*j;D8(Ch+yudlPM(gv$?&CXNp@2BL}0TGCZ4eL?|Lx7L~E9*v8DrA5lb1g5#E&74x zZ9`A24gr{^FLg^njnLB*EXDqvviYZrbjYV-^8+hSsQh@crSwA1o02epEf%sF?~?+V zNqHwfKgm{?tcfzI7lEM8k_c2XT}`xm0zY+`7Zm_#-qE#k-iVsn)p~ikEd-hJ?Pc~M zvBtqtz3A)g!wLJ7k_+KKNZ1d=K0+j2nqn{+K8s3G8{_YrNN0`pazuqsX(s(iiDXC> zsb&aA1FAD>?NYRWu274A@kdUH+mGxNuT&Yh_&FKE!JxU)jc`SK*IEdWnd#jcXCb94~QmVP|-Yo zU^JiEFv&!4`WcR~It?XwYR&ugZU;2d9c&LN%rp7S9vWXB@`ghR59Ff}*xXFsx6Eaz8N+_!~(j6l+&vK$_ zpR6q^E#w##lOicUz`4fniegXLbKvZ=xxDXkcrl3_#S`$^-SZdv_;(|VKkNfWh1 zkaa0HUEesN90n8u;nqGeVfFV=9wLO`bK^1S@G8b7)}W;xH$y4zn=w)rcD7?U zN!jzm&TS!)DFF5xR)_qnOj?`pIU!O2HzO}Aaig~x(;-NIF{8(7^eijS3-G9ORX+%S zmbXn%4pUe;Nf$GU_mbJJvX*|EnmUs_RTVqzRw^K#X)XQqMz>m7+>b_ewde6#8qyo0 z97p9MrDht#GFKVq_xAd*RE_bt<4DcN<6*1p$lu(kC+GPB7$8N~ZPS1x*9?TpTF5OR zUOe6OAO6UH7I6sB(mFN>J#lxLwwAlsa)Aogp~)3=rf{$&)D{`mc%T!Q?MW4rONsN- z5_UN&|A3yLkeX_@3-;&bA{{-=%1@dBoKyz*vB4)MQp>K%=o84jXYi*ui)V7)Jkaw- z0lEgG2OjX0sYF6C4qc*wfy;QdOjl9arzptI0Tc><{7jav^fiQh)jlSd4p8!hHZ#Fm z3IzD>R}Sm}cgcUR2J{)Wp;MDMsr;=CYf;Ljy3Oi3TE-T7W2vWL6m8WIEy*?(=xUre z=P7*(?$n8keH3{O&f#1EIUhl!zM5<%FWx=*_BGJ>oVOk)~O$=f!bCEGAUGO z8pIZV1=Q#9^c;wzUGA1TIwyHN9-lj%Xk%B^dfA|pVuKv9Q;~u}%d;1N7%&?SS*D$? zoLNFosMlMZR043Y)r$I3iiptm17vmTJ_JiG1KUGD!92W02&Iu}rSZ^yKbdsk2%TWgt?lNYqfu;a;kgM(q=;M z1HCp%fzy83y-KTY*{=7NVc`#D&k%XG?cUOW={tO4!WwBjSWzIY>oefA9le%HhW^Tb z05W6(x0Ku>pb0lyYH1;tIQKEr98{jJ@NvQUB6cUU0X42z@<0EDHh1C^;OW$jL9ZLE z697w@-g#l=m-<$9H(TETLj$A&92Z- z?UOI#R0>NEOY3Qn6ax(7R@BVjyet6XSipW!RtfPOp~PUc&Czu{ZZJoQ^`wPJCUkzZ zh=uU`1%49tZHU{*P}-YW+*OXmkWEH0=td&(tHk2K^SW~crBHu<#n_&_)|VlFx=E+u zwxWP08eD0I1Nq7p&TTWO|2Qh<+Dt-kAwA6c>l?(@RYFenO%Abb80R><9(E?x1 zHyMA@L`SH=jQ$ViEkyyvks-Nx3k=B|91;|R{p(n#+?mt`%V~5Bd3Wq5(D2@q1Wd~e zz_0EhLrOg!)8C`ovhB6wG5aNdY6;aJQ1+TV)bVe!jsibvY9SAxYPvC!%c=r@s(9!~ zf1{WmEz+E@Um`{dyLfeI9f&E4Fh>Pi-|a@XdtimCU>0W&(or&cP=TM#9_+u_csZ$F zs51WqgaW6lHmCOPZZedKFi0B*ni(%dm2wjzScwq9D$ddvkNO4CvU zp)zCc+LJrP&!7HG62z5P__7bvi^9s=?_|oJ3qR zZy2>_&K?|tJ1)}itD$yYwgDcZ`c|XAb%WR-yu#f4#Y<9DrsZzOz9sDYsPTt#Ky7HT z8)fDwbk^7KjXg%j31BjR1hd*h@_jJIYi4VH6ia8{#|ise>2%C;V+40q7)#JJ^g-yWH(9>l^>)-{C(=7i5i?t@oR&r2WAL6mrslO% z>uTga6!aJbC^4*mU?7PI2bqo-T%|aGtP*E9^mOlc2s1$?PG4YQ0UfcNo7S_V43>oZr6cmvLgef z0gr*kE*ce;s=x{+y%2~1=t(cWM|~nQIg0dnVwUe5@?5lks5Y0v6|QEiKf$N@RA~xuNRhN8{P&9!|+=`tRFM#4vTWb$5))q{glle%$KO!Uh?GYLI?*f*a z;gkyt2snj*X2JVfM8G3e@DWEyz+?IVVuUm)VN2FO=jB3Z4>f>o?91uAUW92d%;dT= zBFdeLg6+Z_-w=<7dtGe~mX#<=fh&4qfQB+g|5rg|)Xdm-iF{>Wf!j*_4Vn;6`xGBz zGxpvXj=+rk6BtSY-+=tK@>Lj*yW;GO6+=5ERGUeE17Wj-r5S*5L5&Z5E#|oNQ)W`M zL82*nDk5zvL<7meJ_Ze&I_;`w?03_yI-aqAz<>t6RL^SNuE6aU!qi1o+L%B`=J8%! z0L(Cc8XplK=Srrq-#Y|@-t6?Jii`233IQv`^ymTLw0_!dDSw*Pz$MLlBt0Nv8krrv zYY+l|&?i_733wZT>^H}(Q3EK(vNMy>!0ap{Q$e#qrr(^7921W&@Y9%Z9eEg5SAf5u z=T5UoOVZn*wCNJIxf)B4tWPB8DoQC{67I6W77a1u@wZaN@s!5#kbAK2-_j zEY^zgn8WE4BTXAu_mlZs-qG{tAGYEM6v&r<9TYu&gpP~fw{;mm;@rO1gXf=08$&oE z*Q7>sbX@6P#s=Js!MW|%}0m$OmQk&)AILlw`bagtf7NiXbzC3G)8Q~unJ_)s!TzM+@E;z3lXZGDUH`XAIy-&vK*tBy^EK|jE7cl}@fW{$ zyQuI}R$OPi1QOCUA@WCgBgjD%%7o8=<&=;8;>j`YRb%BHaU4j|=>W36s0j8nQ`9GHHQ zc{kY5yR;4o-eT2%0%wWMl*XdoEKCH-sG=)#p0x3TaxLEWM*2zZERG4ZTlMwvEK8bw67kf3F^4f@X5ql6T3wDn zmEb5@)5f@Y$72(Wh&RK^#!t!4hP$(j3AZ}%vE>MH-LdvAhde;)M;Z4byyVe4YnuvE|3OdP3M8V~x((!2H};pS!IF~-8_cmoNOh0n5U_@Kc-3FMQ6tClel zK>TZb7PpDcv!qlZ1Euw>U2eabxzzhdX;1A>T`_LF^Nm(JOVRvwkzG|>0G%y9e%#yT zEtz2*Kw(I+|E4T%gg%1VE-B{};e0ci9N?Zc?Y<` zrd-8!Yt(sKhFlRSmSNl|GI*n9+eg@?aD| zYa#%O@MFTLPYD#=&@u@*s&M`!K__0WecNy(IsoXm;rkYDpWNzpCBtD&SeaLstUL$P zQ=;5&){qW=kIk6E=}Jr;_2fQQ0TWwZ<+QF{jGRQPg*Qh<6rB+VO4qt4AZ+a^r!={} z1maEkU6Tu21R?mA*9SiHY4~A@{#I#XGPem}|N* zINih+Q?1}248bigCH^5Bk2COUi&L#UWt1Wk3>B$=I?6~*0KFl_RjcI5l%*{|IrP3V zEX+JsN^i)HRfRbyeC%dEw}C9kNFgD#>kzL!2Heb%Uv9A{tAIs7x79JQ48EzVf@Xp& zaRNzW)xT23+)wX{D2BjN!2`R(f3gOEHiVKwDGc$RYI;qEbUc#vCeo2!Yd=+VXO8#B zd{ZTVS$L`-u_$Vt*_~N{Tu@BR1gY(mR66vb4f?fn$mt$7CGU3hy9l|yE#uQRMw3}) zjys+0F%-NIwU+-i&6Sip?A&ZgW}RXcKPsvxno=cm*OcISg(nnYB!ZKqG`G3x4rP=B zoy}Q+NUP@Hi!?1ushyOy8bB=;hPMoGJzBSQDhNh>QZM(2vmMI&cMD(870qM2_jF7=H)gZ8dQ;sW2z@ zjB$2WMr;aeM<6&zhSoZw6*zxZaDLiviD%J_h$N!=OmR#NMXrPXVEA17L0{0{ipJccz# z;D@?KpRSSNoqmV#?$X(A73Hyi(yz1N=3Xf_A%#nXIp z#cI~j)ovH*zmae@6cVM|RSA}=Ra6nn>ZDnTozH>INqrEN@TeY-^VmX9S2lVY$dPQQ zbdNg}OyREQY9ziXX}+TxiO@#)WxS@X0>8tyYpWZ4JVsMFpRhIb11hY4pz8e?RT?6V zUa6>xrv(;XLnxfn${eofo+S)dVnx`eQAujRTALWTHN?n4*M(x_*3bigag1Em6C?Lk zJY9o|=f}vcA&S}Qr16+WYcIUmv}_M*2M9CDq0gxk|@;FB5J{mQ>8_elg8CMVU2;CN_sZs`6+Wwc$Ac+!j7D-;T178 z1uF@N6r6(%S;vIodK35*HrYa6b6gZiw~Z{ay775D%QZ+madhT?9JslAvOa=mof>x` z@ZXl}Y8H@T9a}##P>AQDG01VOOtxLRpbFGBpeGU}fu94!-q^mra2;2d*;e~P(1R;z zU`4;M&qYt{c8=KqxM49vi;Xh>yAE_i7OvfH2>D39iW)161DY7{s$tw{rm8CT3AK-# zMLY%UA^2}1egh1DMs!YUuaHLn4c?fUtbSr15nF45&yg&>g)(4Y%eD#ITkPYN4yzMI z;(0la`zLT2-%8^HY8#?+^a;I0h6{(pwhBT-yfW+(2z81x(FvI~CSO@r1iIS|Bh_7| z3+y5MvNJV^gyJEe)_Bam!hA;&%nOW_fSDkh(a6L^nWle#HIoj}VU7~i-L7~?RA>dV zlVk)88hdbU$^a9i5Jhs6h=$P0X9AC)NS-oM#oCCbK#1K`JbvtgU$aU?^{CCfTXDw- z0IsIPX7(05R3#W7j3K%v5SgZawW3j(Ad!HuqzvI~kv1R9k(gA-r_A;!K#S)YsTKz` zg*#fH%@{*}-T%8CTJVZ?MTNvDEaK>pI|jLQ24Kq>TxK_eB^?x1-3+cbv>XVkM>xtg z8w(TCl94c02S@J(%gzs!W_SypYMs)vy7nhdr`q%AmAVECcoE1CQhUz08P zufcN|6quS6+4JnP8(^%{S$cn|t~E!u)8gJO{fL+%qX$f#nM+#M;ZPMeh90u&PBJPFDB+ z9mK4tjlM&3k%F1~d{@&%!>6IdGzEuM(LZK{TLObY6K-@YEad#2O z1&9o-Hzb=^LUkk+fQ9gywgJ|d2a-$E*=2UKq~Gu=Tjg2Z{DOI=9hy8V478anod*T@ z_dn;oE8TR|jW-7p;j5MOcQzKlJck|@$R%kL#~A_O(g;d_u#gzbEWaS-hv?RS${oxJ zB+az!>e*hLh>7N^&}%?&YLdX*m3I~gLx8EzSl*q|2NS-_wM-SQH+)wSQOkHmx4;AW z=e?8&011m^ZZ3aB3=y%)RNtw0whAUP?h^TxsYyCF9ye&-_BpBL0t<5w9&!gsue&q9 z4mF5~Ic(2o(y20n9ON{Yxg3Rm30yGHxw)|F*kZAn3QG^)yS;^OS~thM?t}*q1h`&o zLc|wH4h+J{9JgPy5;VzMnN>rUu-nND@Om-J$Ut{-(>jX1S_bl%!xII zIs(tyyB$9gIu&v5310=+HZCveie-%wK!N=P9<y#)>54zC88v^4OVwCGV2a65c>NGTP71^KpgZ+nrJa5#qwe=A=gz#@mjp?@5+w zIHm$8^~RqEekw2Fmqe))5LiZ1(e%J#Wvj$qar=0GSVVjCOegU&-0^?4pu+icp9QY; zf4x3HeE>mM=NVtg;$=1hwJHy&Fn29dPjq0qF$nAwVC-0W_qxr0BX4HbJ~c^Dd%>(+ftrrYz6BXV%NmG$bj3=3PEv`>W62}W0=$J(sOyPaS{ z_8W?X$W@8o{s~K21){DPNaKi;DJ8b!uUs}JkoVeV6n4GQx4`|Gj~lP zvVe?qihxLnT-#WG72>8NZNpuAU`@JxkObytu6C;7F*vkH2ak}=g2Nn`H#*Zq2FV_A zk!G{j%E^(mQQ!kr-%Pq=YF06NadKhxkNAr_*_c^?-9KJ6 zP&Rx-8G?eT>Z~KXBUyr0BoEQpAQNu+hdPb*yj07y(sw=6Kq3#5^p5s4=S9U|vGSr% zBzDXks)ME87m}=P)o4 zxcMSm>IOJ}n;Yl04C*i<*q)OBN*FetK!$A`CY*QKS#cb)dtus8^yCVUPpQda6{9%# zzLcdRGR;cyb&)~@2-$dg>lz7fpKQ0hx}x7z%eTDRR&`dKY-#>ByD6${mCQ%s`zLJ< zFq;t>eOE1?6mXEgd5-yfo&(rzL`FYU&5NonSK{}7f_%f->YSQ##qYp_PvJ~l^wuYM z+f=7h+9qSA^)~zrJ%)(cCvRV#Ru|NM-nni*^RnEw4Zd9KxBV8{SJj*9*{3H@zNa_V zv-sQXLHkMn{TGz3>epGBol}l&dWwtH|9H=1;db=(ie1Q|58SU*GCE=9dEvb2ehmPogr{;`aSvP>AOQO_P+P_@mqHUt*hqQXSg|b=aqZC zuWjNfe_q*FVLS_#H>z*#doRnYtY8QU4&ClwGvXpz&7 zX5Qa>OCh6oZTVfb6aj?q+VXDs^1Rttd$MW0dp*$V7c^^HPHXdux`H=D^3lE;DDhj` zoc#FeRdo&yPxF?!2G11LGAmwH=db7$EzCpi_0fVj3*x(K8Tg*HVLFehi{V$^wWafa z^t-kUKM0#JZ0bdoU;G0tRnUIQ;rfV(>zl0Jpt)0Btg5DNc(#?lpYp1de?CJX=sSUA zkk?)m?T6P@$(l-)`fb+G>+DAU`kvCQ{vfPp^QZjl=XWpUU%$}hrm8OR*Ma~J+B6e> z1seG_J7*m>qon-Z%__tS+KmQOhNd6r*dEK(p4ZWmq zd3D7AI&s^;&*Zxa?-rEhL=j>TRb4QU$oml95{ Date: Thu, 22 Feb 2024 18:49:58 +0400 Subject: [PATCH 73/98] [AUTO-9079] fix automation nightly and on-demand tests (#12136) * fix automation nightly tests * fix automation on-demand tests * fix automation on-demand tests * fix automation nightly upgrade tests * fix automation nightly upgrade tests * fix automation nightly upgrade tests * fix chaos, reorg tests * fix ondemand action * fix nightly action * fix nightly action --- .../workflows/automation-nightly-tests.yml | 22 ++++++++++++---- .../workflows/automation-ondemand-tests.yml | 26 ++++++++++++++----- .../chaos/automation_chaos_test.go | 14 +++++++--- .../reorg/automation_reorg_test.go | 1 + integration-tests/smoke/automation_test.go | 2 +- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index 6df574e58d0..81d9606ef17 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -54,18 +54,30 @@ jobs: env: CHAINLINK_COMMIT_SHA: ${{ github.sha }} CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug + TEST_LOG_LEVEL: info SELECTED_NETWORKS: "SIMULATED" strategy: fail-fast: false matrix: tests: - - name: Upgrade + - name: Upgrade 2.0 suite: smoke - nodes: 6 + nodes: 1 os: ubuntu20.04-8cores-32GB network: SIMULATED - command: -run ^TestAutomationNodeUpgrade$ ./smoke + command: -run ^TestAutomationNodeUpgrade/registry_2_0 ./smoke + - name: Upgrade 2.1 + suite: smoke + nodes: 5 + os: ubuntu20.04-8cores-32GB + network: SIMULATED + command: -run ^TestAutomationNodeUpgrade/registry_2_1 ./smoke + - name: Upgrade 2.2 + suite: smoke + nodes: 5 + os: ubuntu20.04-8cores-32GB + network: SIMULATED + command: -run ^TestAutomationNodeUpgrade/registry_2_2 ./smoke runs-on: ${{ matrix.tests.os }} name: Automation ${{ matrix.tests.name }} Test steps: @@ -184,7 +196,7 @@ jobs: strategy: fail-fast: false matrix: - name: [ Upgrade ] + name: [ Upgrade 2.0, Upgrade 2.1, Upgrade 2.2 ] steps: - name: Get Results id: test-results diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index ed528d2490c..87952216d2c 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -121,32 +121,46 @@ jobs: env: CHAINLINK_COMMIT_SHA: ${{ github.sha }} CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug + TEST_LOG_LEVEL: info strategy: fail-fast: false matrix: tests: - name: chaos suite: chaos - nodes: 5 + nodes: 15 os: ubuntu-latest pyroscope_env: ci-automation-on-demand-chaos network: SIMULATED command: -run ^TestAutomationChaos$ ./chaos - name: reorg suite: reorg - nodes: 1 + nodes: 5 os: ubuntu-latest pyroscope_env: ci-automation-on-demand-reorg network: SIMULATED_NONDEV command: -run ^TestAutomationReorg$ ./reorg - - name: upgrade + - name: upgrade 2.0 + suite: smoke + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-automation-on-demand-upgrade + network: SIMULATED + command: -run ^TestAutomationNodeUpgrade/registry_2_0 ./smoke + - name: upgrade 2.1 suite: smoke - nodes: 6 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-automation-on-demand-upgrade + network: SIMULATED + command: -run ^TestAutomationNodeUpgrade/registry_2_1 ./smoke + - name: upgrade 2.2 + suite: smoke + nodes: 1 os: ubuntu20.04-8cores-32GB pyroscope_env: ci-automation-on-demand-upgrade network: SIMULATED - command: -run ^TestAutomationNodeUpgrade$ ./smoke + command: -run ^TestAutomationNodeUpgrade/registry_2_2 ./smoke runs-on: ${{ matrix.tests.os }} name: Automation On Demand ${{ matrix.tests.name }} Test steps: diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index 1d1fda451b3..f427b75f5a2 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -277,17 +277,23 @@ func TestAutomationChaos(t *testing.T) { actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion) nodesWithoutBootstrap := chainlinkNodes[1:] + defaultOCRRegistryConfig.RegistryVersion = registryVersion ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled()) require.NoError(t, err, "Error building OCR config vars") err = registry.SetConfig(defaultOCRRegistryConfig, ocrConfig) require.NoError(t, err, "Registry config should be be set successfully") require.NoError(t, chainClient.WaitForEvents(), "Waiting for config to be set") - consumers_conditional, upkeepIDs_conditional := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false) - consumers_logtrigger, upkeepIDs_logtrigger := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false) + consumersConditional, upkeepidsConditional := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false) + consumersLogtrigger, upkeepidsLogtrigger := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false) - consumers := append(consumers_conditional, consumers_logtrigger...) - upkeepIDs := append(upkeepIDs_conditional, upkeepIDs_logtrigger...) + consumers := append(consumersConditional, consumersLogtrigger...) + upkeepIDs := append(upkeepidsConditional, upkeepidsLogtrigger...) + + for _, c := range consumersLogtrigger { + err = c.Start() + require.NoError(t, err, "Error starting consumer") + } l.Info().Msg("Waiting for all upkeeps to be performed") diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index e889a1c6123..643101dfb92 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -214,6 +214,7 @@ func TestAutomationReorg(t *testing.T) { actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion) nodesWithoutBootstrap := chainlinkNodes[1:] + defaultOCRRegistryConfig.RegistryVersion = registryVersion ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled()) require.NoError(t, err, "OCR2 config should be built successfully") err = registry.SetConfig(defaultOCRRegistryConfig, ocrConfig) diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index c51b90c1f57..29bd61b9257 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -182,7 +182,7 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool, automationTestConfig t expect := 5 // Upgrade the nodes one at a time and check that the upkeeps are still being performed for i := 0; i < 5; i++ { - err = actions.UpgradeChainlinkNodeVersionsLocal(*cfg.GetChainlinkImageConfig().Image, *cfg.GetChainlinkImageConfig().Version, a.DockerEnv.ClCluster.Nodes[i]) + err = actions.UpgradeChainlinkNodeVersionsLocal(*cfg.GetChainlinkUpgradeImageConfig().Image, *cfg.GetChainlinkUpgradeImageConfig().Version, a.DockerEnv.ClCluster.Nodes[i]) require.NoError(t, err, "Error when upgrading node %d", i) time.Sleep(time.Second * 10) expect = expect + 5 From 8c01c7db62f1c8fb82e80c20c1da1f096bb87cf1 Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Thu, 22 Feb 2024 15:58:33 +0100 Subject: [PATCH 74/98] Fix chain reader test flake and make it faster (#12138) --- core/services/relay/evm/chain_reader_test.go | 24 ++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/core/services/relay/evm/chain_reader_test.go b/core/services/relay/evm/chain_reader_test.go index 02e9d4e3f6a..c5fe0a16ed4 100644 --- a/core/services/relay/evm/chain_reader_test.go +++ b/core/services/relay/evm/chain_reader_test.go @@ -52,19 +52,21 @@ func TestChainReader(t *testing.T) { it := &chainReaderInterfaceTester{} RunChainReaderInterfaceTests(t, it) RunChainReaderInterfaceTests(t, commontestutils.WrapChainReaderTesterForLoop(it)) + t.Run("Dynamically typed topics can be used to filter and have type correct in return", func(t *testing.T) { it.Setup(t) + // bind event before firing it to avoid log poller race + ctx := testutils.Context(t) + cr := it.GetChainReader(t) + require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + anyString := "foo" tx, err := it.evmTest.LatestValueHolderTransactor.TriggerEventWithDynamicTopic(it.auth, anyString) require.NoError(t, err) it.sim.Commit() it.incNonce() it.awaitTx(t, tx) - ctx := testutils.Context(t) - - cr := it.GetChainReader(t) - require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) input := struct{ Field string }{Field: anyString} tp := cr.(clcommontypes.ContractTypeProvider) @@ -84,20 +86,24 @@ func TestChainReader(t *testing.T) { t.Run("Multiple topics can filter together", func(t *testing.T) { it.Setup(t) + + // bind event before firing it to avoid log poller race + ctx := testutils.Context(t) + cr := it.GetChainReader(t) + require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + triggerFourTopics(t, it, int32(1), int32(2), int32(3)) triggerFourTopics(t, it, int32(2), int32(2), int32(3)) triggerFourTopics(t, it, int32(1), int32(3), int32(3)) triggerFourTopics(t, it, int32(1), int32(2), int32(4)) - ctx := testutils.Context(t) - cr := it.GetChainReader(t) - require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) var latest struct{ Field1, Field2, Field3 int32 } params := struct{ Field1, Field2, Field3 int32 }{Field1: 1, Field2: 2, Field3: 3} - time.Sleep(it.MaxWaitTimeForEvents()) + require.Eventually(t, func() bool { + return cr.GetLatestValue(ctx, AnyContractName, triggerWithAllTopics, params, &latest) == nil + }, it.MaxWaitTimeForEvents(), time.Millisecond*10) - require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, triggerWithAllTopics, params, &latest)) assert.Equal(t, int32(1), latest.Field1) assert.Equal(t, int32(2), latest.Field2) assert.Equal(t, int32(3), latest.Field3) From d19cb01a6ce4ec375c5181e3f9bf32ffe4c36e76 Mon Sep 17 00:00:00 2001 From: Oliver Townsend <133903322+ogtownsend@users.noreply.github.com> Date: Thu, 22 Feb 2024 07:37:22 -0800 Subject: [PATCH 75/98] Add metric for num logs in buffer and missed logs (#11852) * Add metric for num logs in buffer * Set metrics in buffer, remove ticker * Add missed logs metric * Remove logsInBuffer var * Add more metrics * Change to inc and dec --- .../ocr2keeper/evmregistry/v21/active_list.go | 8 +++- .../evmregistry/v21/logprovider/buffer.go | 3 ++ .../evmregistry/v21/logprovider/provider.go | 2 + .../evmregistry/v21/logprovider/recoverer.go | 8 +++- .../evmregistry/v21/prommetrics/metrics.go | 38 +++++++++++++++++++ 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics/metrics.go diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/active_list.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/active_list.go index 55c01939cb8..27c13f079b2 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/active_list.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/active_list.go @@ -9,6 +9,7 @@ import ( ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" ) // ActiveUpkeepList is a list to manage active upkeep IDs @@ -49,9 +50,10 @@ func (al *activeList) Reset(ids ...*big.Int) { for _, id := range ids { al.items[id.String()] = true } + prommetrics.AutomationActiveUpkeeps.Set(float64(len(al.items))) } -// Add adds new entries to the list +// Add adds new entries to the list. Returns the number of items added func (al *activeList) Add(ids ...*big.Int) int { al.lock.Lock() defer al.lock.Unlock() @@ -63,10 +65,11 @@ func (al *activeList) Add(ids ...*big.Int) int { al.items[key] = true } } + prommetrics.AutomationActiveUpkeeps.Set(float64(len(al.items))) return count } -// Remove removes entries from the list +// Remove removes entries from the list. Returns the number of items removed func (al *activeList) Remove(ids ...*big.Int) int { al.lock.Lock() defer al.lock.Unlock() @@ -79,6 +82,7 @@ func (al *activeList) Remove(ids ...*big.Int) int { delete(al.items, key) } } + prommetrics.AutomationActiveUpkeeps.Set(float64(len(al.items))) return count } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer.go index 9f11a1fca01..6418d683869 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer.go @@ -12,6 +12,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" ) var ( @@ -230,6 +231,7 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int { } if added > 0 { lggr.Debugw("Added logs to buffer", "addedLogs", added, "dropped", dropped, "latestBlock", latestBlock) + prommetrics.AutomationLogsInLogBuffer.Add(float64(added - dropped)) } return added - dropped @@ -331,6 +333,7 @@ func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit, totalLimit if len(results) > 0 { b.lggr.Debugw("Dequeued logs", "results", len(results), "start", start, "end", end) + prommetrics.AutomationLogsInLogBuffer.Sub(float64(len(results))) } return results diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go index d1360faaf6d..e06593a9109 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go @@ -24,6 +24,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -162,6 +163,7 @@ func (p *logEventProvider) GetLatestPayloads(ctx context.Context) ([]ocr2keepers if err != nil { return nil, fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } + prommetrics.AutomationLogProviderLatestBlock.Set(float64(latest.BlockNumber)) start := latest.BlockNumber - p.opts.LookbackBlocks if start <= 0 { start = 1 diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go index 13b8bb17245..2eef5db17d9 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go @@ -27,6 +27,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -305,7 +306,7 @@ func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers. var results, pending []ocr2keepers.UpkeepPayload for _, payload := range r.pending { if allLogsCounter >= MaxProposals { - // we have enough proposals, pushed the rest are pushed back to pending + // we have enough proposals, the rest are pushed back to pending pending = append(pending, payload) continue } @@ -321,6 +322,7 @@ func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers. } r.pending = pending + prommetrics.AutomationRecovererPendingPayloads.Set(float64(len(r.pending))) r.lggr.Debugf("found %d recoverable payloads", len(results)) @@ -417,6 +419,7 @@ func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startB added, alreadyPending, ok := r.populatePending(f, filteredLogs) if added > 0 { r.lggr.Debugw("found missed logs", "added", added, "alreadyPending", alreadyPending, "upkeepID", f.upkeepID) + prommetrics.AutomationRecovererMissedLogs.Add(float64(added)) } if !ok { r.lggr.Debugw("failed to add all logs to pending", "upkeepID", f.upkeepID) @@ -673,6 +676,7 @@ func (r *logRecoverer) addPending(payload ocr2keepers.UpkeepPayload) error { } if !exist { r.pending = append(pending, payload) + prommetrics.AutomationRecovererPendingPayloads.Inc() } return nil } @@ -684,6 +688,8 @@ func (r *logRecoverer) removePending(workID string) { for _, p := range r.pending { if p.WorkID != workID { updated = append(updated, p) + } else { + prommetrics.AutomationRecovererPendingPayloads.Dec() } } r.pending = updated diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics/metrics.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics/metrics.go new file mode 100644 index 00000000000..cebbac59884 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics/metrics.go @@ -0,0 +1,38 @@ +package prommetrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +// AutomationNamespace is the namespace for all Automation related metrics +const AutomationLogTriggerNamespace = "automation_log_trigger" + +// Automation metrics +var ( + AutomationLogsInLogBuffer = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: AutomationLogTriggerNamespace, + Name: "num_logs_in_log_buffer", + Help: "The total number of logs currently being stored in the log buffer", + }) + AutomationRecovererMissedLogs = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: AutomationLogTriggerNamespace, + Name: "num_recoverer_missed_logs", + Help: "How many valid log triggers were identified as being missed by the recoverer", + }) + AutomationRecovererPendingPayloads = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: AutomationLogTriggerNamespace, + Name: "num_recoverer_pending_payloads", + Help: "How many log trigger payloads are currently pending in the recoverer", + }) + AutomationActiveUpkeeps = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: AutomationLogTriggerNamespace, + Name: "num_active_upkeeps", + Help: "How many log trigger upkeeps are currently active", + }) + AutomationLogProviderLatestBlock = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: AutomationLogTriggerNamespace, + Name: "log_provider_latest_block", + Help: "The latest block number the log provider has seen", + }) +) From 601aa07001bae0ae1ebad04cf83b0feb8956e15a Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 22 Feb 2024 12:30:38 -0500 Subject: [PATCH 76/98] Mercury 1.0 (parallel composition) (#10810) * Implement Data Streams plugin * Try to make tests a bit more deterministic * lint * Increase DeltaGrace * gomodtidy] * Increase timeouts significantly * Attempt test fix * Add comments * Remove useless comment * Add fromblock to LLO job spec --- GNUmakefile | 1 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/chainlink/application.go | 1 + core/services/job/orm.go | 58 +-- core/services/job/spawner_test.go | 2 +- core/services/llo/bm/dummy_transmitter.go | 79 ++++ .../services/llo/bm/dummy_transmitter_test.go | 36 ++ .../llo/channel_definition_cache_factory.go | 58 +++ core/services/llo/data_source.go | 103 +++++ core/services/llo/data_source_test.go | 95 +++++ core/services/llo/delegate.go | 123 ++++++ core/services/llo/evm/report_codec.go | 97 +++++ core/services/llo/evm/report_codec_test.go | 90 +++++ core/services/llo/keyring.go | 79 ++++ core/services/llo/keyring_test.go | 123 ++++++ core/services/llo/offchain_config_digester.go | 123 ++++++ .../llo/offchain_config_digester_test.go | 55 +++ .../llo/onchain_channel_definition_cache.go | 252 ++++++++++++ .../onchain_channel_definition_cache_test.go | 26 ++ core/services/llo/orm.go | 66 ++++ core/services/llo/orm_test.go | 101 +++++ .../llo/static_channel_definitions_cache.go | 56 +++ core/services/llo/transmitter.go | 153 ++++++++ core/services/llo/transmitter_test.go | 7 + core/services/ocr2/delegate.go | 142 ++++++- .../ocr2/plugins/llo/config/config.go | 112 ++++++ .../ocr2/plugins/llo/config/config_test.go | 142 +++++++ .../services/ocr2/plugins/llo/helpers_test.go | 356 +++++++++++++++++ .../ocr2/plugins/llo/integration_test.go | 370 ++++++++++++++++++ ...annel_definition_cache_integration_test.go | 213 ++++++++++ .../ocr2/plugins/mercury/integration_test.go | 14 +- core/services/ocr2/validate/validate.go | 12 + core/services/ocrbootstrap/delegate.go | 15 +- core/services/pipeline/mocks/runner.go | 30 ++ core/services/pipeline/runner.go | 1 + core/services/relay/evm/evm.go | 76 +++- .../services/relay/evm/llo_config_provider.go | 21 + core/services/relay/evm/llo_provider.go | 90 +++++ .../relay/evm/llo_verifier_decoder.go | 67 ++++ .../relay/evm/mercury/config_digest.go | 2 +- .../relay/evm/mercury/wsrpc/pb/mercury.pb.go | 8 +- .../relay/evm/mercury/wsrpc/pb/mercury.proto | 2 +- .../0224_create_channel_definition_caches.sql | 12 + docs/CHANGELOG.md | 1 + go.mod | 4 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 51 files changed, 3436 insertions(+), 60 deletions(-) create mode 100644 core/services/llo/bm/dummy_transmitter.go create mode 100644 core/services/llo/bm/dummy_transmitter_test.go create mode 100644 core/services/llo/channel_definition_cache_factory.go create mode 100644 core/services/llo/data_source.go create mode 100644 core/services/llo/data_source_test.go create mode 100644 core/services/llo/delegate.go create mode 100644 core/services/llo/evm/report_codec.go create mode 100644 core/services/llo/evm/report_codec_test.go create mode 100644 core/services/llo/keyring.go create mode 100644 core/services/llo/keyring_test.go create mode 100644 core/services/llo/offchain_config_digester.go create mode 100644 core/services/llo/offchain_config_digester_test.go create mode 100644 core/services/llo/onchain_channel_definition_cache.go create mode 100644 core/services/llo/onchain_channel_definition_cache_test.go create mode 100644 core/services/llo/orm.go create mode 100644 core/services/llo/orm_test.go create mode 100644 core/services/llo/static_channel_definitions_cache.go create mode 100644 core/services/llo/transmitter.go create mode 100644 core/services/llo/transmitter_test.go create mode 100644 core/services/ocr2/plugins/llo/config/config.go create mode 100644 core/services/ocr2/plugins/llo/config/config_test.go create mode 100644 core/services/ocr2/plugins/llo/helpers_test.go create mode 100644 core/services/ocr2/plugins/llo/integration_test.go create mode 100644 core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go create mode 100644 core/services/relay/evm/llo_config_provider.go create mode 100644 core/services/relay/evm/llo_provider.go create mode 100644 core/services/relay/evm/llo_verifier_decoder.go create mode 100644 core/store/migrate/migrations/0224_create_channel_definition_caches.sql diff --git a/GNUmakefile b/GNUmakefile index 20f3eb92d51..8cbd0953ee7 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -31,6 +31,7 @@ gomodtidy: ## Run go mod tidy on all modules. go mod tidy cd ./core/scripts && go mod tidy cd ./integration-tests && go mod tidy + cd ./integration-tests/load && go mod tidy .PHONY: godoc godoc: ## Install and run godoc diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 9cf5111cf52..91697eb5f9f 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -250,7 +250,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index b6432cbe3fe..7a3f6b2f0c2 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1177,8 +1177,8 @@ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index eebb70534c0..d95458838bc 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -417,6 +417,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { bridgeORM, mercuryORM, pipelineRunner, + streamRegistry, peerWrapper, telemetryManager, legacyEVMChains, diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 07b9cb95aae..2e7bb0a90a5 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -467,34 +467,40 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } // ValidateKeyStoreMatch confirms that the key has a valid match in the keystore -func ValidateKeyStoreMatch(spec *OCR2OracleSpec, keyStore keystore.Master, key string) error { - if spec.PluginType == types.Mercury { - _, err := keyStore.CSA().Get(key) +func ValidateKeyStoreMatch(spec *OCR2OracleSpec, keyStore keystore.Master, key string) (err error) { + switch spec.PluginType { + case types.Mercury, types.LLO: + _, err = keyStore.CSA().Get(key) if err != nil { - return errors.Errorf("no CSA key matching: %q", key) + err = errors.Errorf("no CSA key matching: %q", key) } - } else { - switch spec.Relay { - case relay.EVM: - _, err := keyStore.Eth().Get(key) - if err != nil { - return errors.Errorf("no EVM key matching: %q", key) - } - case relay.Cosmos: - _, err := keyStore.Cosmos().Get(key) - if err != nil { - return errors.Errorf("no Cosmos key matching: %q", key) - } - case relay.Solana: - _, err := keyStore.Solana().Get(key) - if err != nil { - return errors.Errorf("no Solana key matching: %q", key) - } - case relay.StarkNet: - _, err := keyStore.StarkNet().Get(key) - if err != nil { - return errors.Errorf("no Starknet key matching: %q", key) - } + default: + err = validateKeyStoreMatchForRelay(spec.Relay, keyStore, key) + } + return +} + +func validateKeyStoreMatchForRelay(network relay.Network, keyStore keystore.Master, key string) error { + switch network { + case relay.EVM: + _, err := keyStore.Eth().Get(key) + if err != nil { + return errors.Errorf("no EVM key matching: %q", key) + } + case relay.Cosmos: + _, err := keyStore.Cosmos().Get(key) + if err != nil { + return errors.Errorf("no Cosmos key matching: %q", key) + } + case relay.Solana: + _, err := keyStore.Solana().Get(key) + if err != nil { + return errors.Errorf("no Solana key matching: %q", key) + } + case relay.StarkNet: + _, err := keyStore.StarkNet().Get(key) + if err != nil { + return errors.Errorf("no Starknet key matching: %q", key) } } return nil diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index b23be49458e..9dde7a47721 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -304,7 +304,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { processConfig := plugins.NewRegistrarConfig(loop.GRPCOpts{}, func(name string) (*plugins.RegisteredLoop, error) { return nil, nil }) ocr2DelegateConfig := ocr2.NewDelegateConfig(config.OCR2(), config.Mercury(), config.Threshold(), config.Insecure(), config.JobPipeline(), config.Database(), processConfig) - d := ocr2.NewDelegate(nil, orm, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig, + d := ocr2.NewDelegate(nil, orm, nil, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig, keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, capabilities.NewRegistry(lggr)) delegateOCR2 := &delegate{jobOCR2VRF.Type, []job.ServiceCtx{}, 0, nil, d} diff --git a/core/services/llo/bm/dummy_transmitter.go b/core/services/llo/bm/dummy_transmitter.go new file mode 100644 index 00000000000..b998c19cb29 --- /dev/null +++ b/core/services/llo/bm/dummy_transmitter.go @@ -0,0 +1,79 @@ +package bm + +import ( + "context" + "crypto/ed25519" + "fmt" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// A dummy transmitter useful for benchmarking and testing + +var ( + transmitSuccessCount = promauto.NewCounter(prometheus.CounterOpts{ + Name: "llo_transmit_success_count", + Help: "Running count of successful transmits", + }) +) + +type Transmitter interface { + llotypes.Transmitter + services.Service +} + +type transmitter struct { + lggr logger.Logger + fromAccount string +} + +func NewTransmitter(lggr logger.Logger, fromAccount ed25519.PublicKey) Transmitter { + return &transmitter{ + lggr.Named("DummyTransmitter"), + fmt.Sprintf("%x", fromAccount), + } +} + +func (t *transmitter) Start(context.Context) error { + return nil +} + +func (t *transmitter) Close() error { + return nil +} + +func (t *transmitter) Transmit( + ctx context.Context, + digest types.ConfigDigest, + seqNr uint64, + report ocr3types.ReportWithInfo[llotypes.ReportInfo], + sigs []types.AttributedOnchainSignature, +) error { + transmitSuccessCount.Inc() + t.lggr.Debugw("Transmit", "digest", digest, "seqNr", seqNr, "report.Report", report.Report, "report.Info", report.Info, "sigs", sigs) + return nil +} + +// FromAccount returns the stringified (hex) CSA public key +func (t *transmitter) FromAccount() (ocr2types.Account, error) { + return ocr2types.Account(t.fromAccount), nil +} + +func (t *transmitter) Ready() error { return nil } + +func (t *transmitter) HealthReport() map[string]error { + report := map[string]error{t.Name(): nil} + return report +} + +func (t *transmitter) Name() string { return t.lggr.Name() } diff --git a/core/services/llo/bm/dummy_transmitter_test.go b/core/services/llo/bm/dummy_transmitter_test.go new file mode 100644 index 00000000000..055b150ad13 --- /dev/null +++ b/core/services/llo/bm/dummy_transmitter_test.go @@ -0,0 +1,36 @@ +package bm + +import ( + "crypto/ed25519" + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func Test_DummyTransmitter(t *testing.T) { + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) + tr := NewTransmitter(lggr, ed25519.PublicKey("dummy")) + + servicetest.Run(t, tr) + + err := tr.Transmit( + testutils.Context(t), + types.ConfigDigest{}, + 42, + ocr3types.ReportWithInfo[llotypes.ReportInfo]{}, + []types.AttributedOnchainSignature{}, + ) + require.NoError(t, err) + + testutils.RequireLogMessage(t, observedLogs, "Transmit") +} diff --git a/core/services/llo/channel_definition_cache_factory.go b/core/services/llo/channel_definition_cache_factory.go new file mode 100644 index 00000000000..51906e0ff1b --- /dev/null +++ b/core/services/llo/channel_definition_cache_factory.go @@ -0,0 +1,58 @@ +package llo + +import ( + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" +) + +type ChannelDefinitionCacheFactory interface { + NewCache(cfg lloconfig.PluginConfig) (llotypes.ChannelDefinitionCache, error) +} + +var _ ChannelDefinitionCacheFactory = &channelDefinitionCacheFactory{} + +func NewChannelDefinitionCacheFactory(lggr logger.Logger, orm ChannelDefinitionCacheORM, lp logpoller.LogPoller) ChannelDefinitionCacheFactory { + return &channelDefinitionCacheFactory{ + lggr, + orm, + lp, + make(map[common.Address]struct{}), + sync.Mutex{}, + } +} + +type channelDefinitionCacheFactory struct { + lggr logger.Logger + orm ChannelDefinitionCacheORM + lp logpoller.LogPoller + + caches map[common.Address]struct{} + mu sync.Mutex +} + +func (f *channelDefinitionCacheFactory) NewCache(cfg lloconfig.PluginConfig) (llotypes.ChannelDefinitionCache, error) { + if cfg.ChannelDefinitions != "" { + return NewStaticChannelDefinitionCache(f.lggr, cfg.ChannelDefinitions) + } + + addr := cfg.ChannelDefinitionsContractAddress + fromBlock := cfg.ChannelDefinitionsContractFromBlock + + f.mu.Lock() + defer f.mu.Unlock() + + if _, exists := f.caches[addr]; exists { + // This shouldn't really happen and isn't supported + return nil, fmt.Errorf("cache already exists for contract address %s", addr.Hex()) + } + f.caches[addr] = struct{}{} + return NewChannelDefinitionCache(f.lggr, f.orm, f.lp, addr, fromBlock), nil +} diff --git a/core/services/llo/data_source.go b/core/services/llo/data_source.go new file mode 100644 index 00000000000..a9c3744f9e3 --- /dev/null +++ b/core/services/llo/data_source.go @@ -0,0 +1,103 @@ +package llo + +import ( + "context" + "fmt" + "math/big" + "sync" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-data-streams/llo" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/streams" +) + +var ( + promMissingStreamCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_stream_missing_count", + Help: "Number of times we tried to observe a stream, but it was missing", + }, + []string{"streamID"}, + ) + promObservationErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_stream_observation_error_count", + Help: "Number of times we tried to observe a stream, but it failed with an error", + }, + []string{"streamID"}, + ) +) + +type ErrMissingStream struct { + id string +} + +type Registry interface { + Get(streamID streams.StreamID) (strm streams.Stream, exists bool) +} + +func (e ErrMissingStream) Error() string { + return fmt.Sprintf("missing stream definition for: %q", e.id) +} + +var _ llo.DataSource = &dataSource{} + +type dataSource struct { + lggr logger.Logger + registry Registry +} + +func newDataSource(lggr logger.Logger, registry Registry) llo.DataSource { + return &dataSource{lggr.Named("DataSource"), registry} +} + +// Observe looks up all streams in the registry and returns a map of stream ID => value +func (d *dataSource) Observe(ctx context.Context, streamIDs map[llotypes.StreamID]struct{}) (llo.StreamValues, error) { + var wg sync.WaitGroup + wg.Add(len(streamIDs)) + sv := make(llo.StreamValues) + var mu sync.Mutex + + for streamID := range streamIDs { + go func(streamID llotypes.StreamID) { + defer wg.Done() + + var res llo.ObsResult[*big.Int] + + stream, exists := d.registry.Get(streamID) + if exists { + run, trrs, err := stream.Run(ctx) + if err != nil { + var runID int64 + if run != nil { + runID = run.ID + } + d.lggr.Debugw("Observation failed for stream", "err", err, "streamID", streamID, "runID", runID) + promObservationErrorCount.WithLabelValues(fmt.Sprintf("%d", streamID)).Inc() + } else { + // TODO: support types other than *big.Int + // https://smartcontract-it.atlassian.net/browse/MERC-3525 + val, err := streams.ExtractBigInt(trrs) + if err == nil { + res.Val = val + res.Valid = true + } + } + } else { + d.lggr.Errorw(fmt.Sprintf("Missing stream: %q", streamID), "streamID", streamID) + promMissingStreamCount.WithLabelValues(fmt.Sprintf("%d", streamID)).Inc() + } + + mu.Lock() + defer mu.Unlock() + sv[streamID] = res + }(streamID) + } + + wg.Wait() + + return sv, nil +} diff --git a/core/services/llo/data_source_test.go b/core/services/llo/data_source_test.go new file mode 100644 index 00000000000..c956e3770c9 --- /dev/null +++ b/core/services/llo/data_source_test.go @@ -0,0 +1,95 @@ +package llo + +import ( + "context" + "errors" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-data-streams/llo" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/streams" +) + +type mockStream struct { + run *pipeline.Run + trrs pipeline.TaskRunResults + err error +} + +func (m *mockStream) Run(ctx context.Context) (*pipeline.Run, pipeline.TaskRunResults, error) { + return m.run, m.trrs, m.err +} + +type mockRegistry struct { + streams map[streams.StreamID]*mockStream +} + +func (m *mockRegistry) Get(streamID streams.StreamID) (strm streams.Stream, exists bool) { + strm, exists = m.streams[streamID] + return +} + +func makeStreamWithSingleResult[T any](res T, err error) *mockStream { + return &mockStream{ + trrs: []pipeline.TaskRunResult{pipeline.TaskRunResult{Task: &pipeline.MemoTask{}, Result: pipeline.Result{Value: res}}}, + err: err, + } +} + +func Test_DataSource(t *testing.T) { + lggr := logger.TestLogger(t) + reg := &mockRegistry{make(map[streams.StreamID]*mockStream)} + ds := newDataSource(lggr, reg) + ctx := testutils.Context(t) + + streamIDs := make(map[streams.StreamID]struct{}) + streamIDs[streams.StreamID(1)] = struct{}{} + streamIDs[streams.StreamID(2)] = struct{}{} + streamIDs[streams.StreamID(3)] = struct{}{} + + t.Run("Observe", func(t *testing.T) { + t.Run("returns errors if no streams are defined", func(t *testing.T) { + vals, err := ds.Observe(ctx, streamIDs) + assert.NoError(t, err) + + assert.Equal(t, llo.StreamValues{ + 2: llo.ObsResult[*big.Int]{Val: nil, Valid: false}, + 1: llo.ObsResult[*big.Int]{Val: nil, Valid: false}, + 3: llo.ObsResult[*big.Int]{Val: nil, Valid: false}, + }, vals) + }) + t.Run("observes each stream with success and returns values matching map argument", func(t *testing.T) { + reg.streams[1] = makeStreamWithSingleResult[*big.Int](big.NewInt(2181), nil) + reg.streams[2] = makeStreamWithSingleResult[*big.Int](big.NewInt(40602), nil) + reg.streams[3] = makeStreamWithSingleResult[*big.Int](big.NewInt(15), nil) + + vals, err := ds.Observe(ctx, streamIDs) + assert.NoError(t, err) + + assert.Equal(t, llo.StreamValues{ + 2: llo.ObsResult[*big.Int]{Val: big.NewInt(40602), Valid: true}, + 1: llo.ObsResult[*big.Int]{Val: big.NewInt(2181), Valid: true}, + 3: llo.ObsResult[*big.Int]{Val: big.NewInt(15), Valid: true}, + }, vals) + }) + t.Run("observes each stream and returns success/errors", func(t *testing.T) { + reg.streams[1] = makeStreamWithSingleResult[*big.Int](big.NewInt(2181), errors.New("something exploded")) + reg.streams[2] = makeStreamWithSingleResult[*big.Int](big.NewInt(40602), nil) + reg.streams[3] = makeStreamWithSingleResult[*big.Int](nil, errors.New("something exploded 2")) + + vals, err := ds.Observe(ctx, streamIDs) + assert.NoError(t, err) + + assert.Equal(t, llo.StreamValues{ + 2: llo.ObsResult[*big.Int]{Val: big.NewInt(40602), Valid: true}, + 1: llo.ObsResult[*big.Int]{Val: nil, Valid: false}, + 3: llo.ObsResult[*big.Int]{Val: nil, Valid: false}, + }, vals) + }) + }) +} diff --git a/core/services/llo/delegate.go b/core/services/llo/delegate.go new file mode 100644 index 00000000000..b64c9c590fe --- /dev/null +++ b/core/services/llo/delegate.go @@ -0,0 +1,123 @@ +package llo + +import ( + "context" + "errors" + "fmt" + + ocrcommontypes "github.com/smartcontractkit/libocr/commontypes" + ocr2plus "github.com/smartcontractkit/libocr/offchainreporting2plus" + ocr3types "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-data-streams/llo" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/services/streams" +) + +var _ job.ServiceCtx = &delegate{} + +type Closer interface { + Close() error +} + +type delegate struct { + services.StateMachine + + cfg DelegateConfig + codecs map[llotypes.ReportFormat]llo.ReportCodec + + prrc llo.PredecessorRetirementReportCache + src llo.ShouldRetireCache + ds llo.DataSource + + oracle Closer +} + +type DelegateConfig struct { + Logger logger.Logger + Queryer pg.Queryer + Runner streams.Runner + Registry Registry + + // LLO + ChannelDefinitionCache llotypes.ChannelDefinitionCache + + // OCR3 + BinaryNetworkEndpointFactory ocr2types.BinaryNetworkEndpointFactory + V2Bootstrappers []ocrcommontypes.BootstrapperLocator + ContractConfigTracker ocr2types.ContractConfigTracker + ContractTransmitter ocr3types.ContractTransmitter[llotypes.ReportInfo] + Database ocr3types.Database + OCRLogger ocrcommontypes.Logger + MonitoringEndpoint ocrcommontypes.MonitoringEndpoint + OffchainConfigDigester ocr2types.OffchainConfigDigester + OffchainKeyring ocr2types.OffchainKeyring + OnchainKeyring ocr3types.OnchainKeyring[llotypes.ReportInfo] + LocalConfig ocr2types.LocalConfig +} + +func NewDelegate(cfg DelegateConfig) (job.ServiceCtx, error) { + if cfg.Queryer == nil { + return nil, errors.New("Queryer must not be nil") + } + if cfg.Runner == nil { + return nil, errors.New("Runner must not be nil") + } + if cfg.Registry == nil { + return nil, errors.New("Registry must not be nil") + } + codecs := make(map[llotypes.ReportFormat]llo.ReportCodec) + + // NOTE: All codecs must be specified here + codecs[llotypes.ReportFormatJSON] = llo.JSONReportCodec{} + codecs[llotypes.ReportFormatEVM] = evm.ReportCodec{} + + // TODO: Do these services need starting? + // https://smartcontract-it.atlassian.net/browse/MERC-3386 + prrc := llo.NewPredecessorRetirementReportCache() + src := llo.NewShouldRetireCache() + ds := newDataSource(cfg.Logger.Named("DataSource"), cfg.Registry) + + return &delegate{services.StateMachine{}, cfg, codecs, prrc, src, ds, nil}, nil +} + +func (d *delegate) Start(ctx context.Context) error { + return d.StartOnce("LLODelegate", func() error { + // create the oracle from config values + oracle, err := ocr2plus.NewOracle(ocr2plus.OCR3OracleArgs[llotypes.ReportInfo]{ + BinaryNetworkEndpointFactory: d.cfg.BinaryNetworkEndpointFactory, + V2Bootstrappers: d.cfg.V2Bootstrappers, + ContractConfigTracker: d.cfg.ContractConfigTracker, + ContractTransmitter: d.cfg.ContractTransmitter, + Database: d.cfg.Database, + LocalConfig: d.cfg.LocalConfig, + Logger: d.cfg.OCRLogger, + MonitoringEndpoint: d.cfg.MonitoringEndpoint, + OffchainConfigDigester: d.cfg.OffchainConfigDigester, + OffchainKeyring: d.cfg.OffchainKeyring, + OnchainKeyring: d.cfg.OnchainKeyring, + ReportingPluginFactory: llo.NewPluginFactory( + d.prrc, d.src, d.cfg.ChannelDefinitionCache, d.ds, d.cfg.Logger.Named("LLOReportingPlugin"), d.codecs, + ), + }) + + if err != nil { + return fmt.Errorf("%w: failed to create new OCR oracle", err) + } + + d.oracle = oracle + + return oracle.Start() + }) +} + +func (d *delegate) Close() error { + return d.StopOnce("LLODelegate", d.oracle.Close) +} diff --git a/core/services/llo/evm/report_codec.go b/core/services/llo/evm/report_codec.go new file mode 100644 index 00000000000..23ae02e1064 --- /dev/null +++ b/core/services/llo/evm/report_codec.go @@ -0,0 +1,97 @@ +package evm + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + + chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink-data-streams/llo" +) + +var ( + _ llo.ReportCodec = ReportCodec{} + Schema = getSchema() +) + +func getSchema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "configDigest", Type: mustNewType("bytes32")}, + {Name: "chainId", Type: mustNewType("uint64")}, + // TODO: + // could also include address of verifier to make things more specific. + // downside is increased data size. + // for now we assume that a channelId will only be registered on a single + // verifier per chain. + // https://smartcontract-it.atlassian.net/browse/MERC-3652 + {Name: "seqNr", Type: mustNewType("uint64")}, + {Name: "channelId", Type: mustNewType("uint32")}, + {Name: "validAfterSeconds", Type: mustNewType("uint32")}, + {Name: "validUntilSeconds", Type: mustNewType("uint32")}, + {Name: "values", Type: mustNewType("int192[]")}, + {Name: "specimen", Type: mustNewType("bool")}, + }) +} + +type ReportCodec struct{} + +func NewReportCodec() ReportCodec { + return ReportCodec{} +} + +func (ReportCodec) Encode(report llo.Report) ([]byte, error) { + chainID, err := chainselectors.ChainIdFromSelector(report.ChainSelector) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID for selector %d; %w", report.ChainSelector, err) + } + + b, err := Schema.Pack(report.ConfigDigest, chainID, report.SeqNr, report.ChannelID, report.ValidAfterSeconds, report.ValidUntilSeconds, report.Values, report.Specimen) + if err != nil { + return nil, fmt.Errorf("failed to encode report: %w", err) + } + return b, nil +} + +func (ReportCodec) Decode(encoded []byte) (llo.Report, error) { + type decode struct { + ConfigDigest types.ConfigDigest + ChainId uint64 + SeqNr uint64 + ChannelId llotypes.ChannelID + ValidAfterSeconds uint32 + ValidUntilSeconds uint32 + Values []*big.Int + Specimen bool + } + values, err := Schema.Unpack(encoded) + if err != nil { + return llo.Report{}, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(decode) + if err = Schema.Copy(decoded, values); err != nil { + return llo.Report{}, fmt.Errorf("failed to copy report values to struct: %w", err) + } + chainSelector, err := chainselectors.SelectorFromChainId(decoded.ChainId) + return llo.Report{ + ConfigDigest: decoded.ConfigDigest, + ChainSelector: chainSelector, + SeqNr: decoded.SeqNr, + ChannelID: decoded.ChannelId, + ValidAfterSeconds: decoded.ValidAfterSeconds, + ValidUntilSeconds: decoded.ValidUntilSeconds, + Values: decoded.Values, + Specimen: decoded.Specimen, + }, err +} diff --git a/core/services/llo/evm/report_codec_test.go b/core/services/llo/evm/report_codec_test.go new file mode 100644 index 00000000000..e00314306ae --- /dev/null +++ b/core/services/llo/evm/report_codec_test.go @@ -0,0 +1,90 @@ +package evm + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink-data-streams/llo" +) + +const ethMainnetChainSelector uint64 = 5009297550715157269 + +func newValidReport() llo.Report { + return llo.Report{ + ConfigDigest: types.ConfigDigest{1, 2, 3}, + ChainSelector: ethMainnetChainSelector, // + SeqNr: 32, + ChannelID: llotypes.ChannelID(31), + ValidAfterSeconds: 33, + ValidUntilSeconds: 34, + Values: []*big.Int{big.NewInt(35), big.NewInt(36)}, + Specimen: true, + } +} + +func Test_ReportCodec(t *testing.T) { + rc := ReportCodec{} + + t.Run("Encode errors on zero fields", func(t *testing.T) { + _, err := rc.Encode(llo.Report{}) + require.Error(t, err) + + assert.Contains(t, err.Error(), "failed to get chain ID for selector 0; chain not found for chain selector 0") + }) + + t.Run("Encode constructs a report from observations", func(t *testing.T) { + report := newValidReport() + + encoded, err := rc.Encode(report) + require.NoError(t, err) + + reportElems := make(map[string]interface{}) + err = Schema.UnpackIntoMap(reportElems, encoded) + require.NoError(t, err) + + assert.Equal(t, [32]uint8{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, reportElems["configDigest"]) + assert.Equal(t, uint64(1), reportElems["chainId"]) + assert.Equal(t, uint64(32), reportElems["seqNr"]) + assert.Equal(t, uint32(31), reportElems["channelId"]) + assert.Equal(t, uint32(33), reportElems["validAfterSeconds"]) + assert.Equal(t, uint32(34), reportElems["validUntilSeconds"]) + assert.Equal(t, []*big.Int{big.NewInt(35), big.NewInt(36)}, reportElems["values"]) + assert.Equal(t, true, reportElems["specimen"]) + + assert.Len(t, encoded, 352) + assert.Equal(t, []byte{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24}, encoded) + + t.Run("Decode decodes the report", func(t *testing.T) { + decoded, err := rc.Decode(encoded) + require.NoError(t, err) + + assert.Equal(t, report.ConfigDigest, decoded.ConfigDigest) + assert.Equal(t, report.ChainSelector, decoded.ChainSelector) + assert.Equal(t, report.SeqNr, decoded.SeqNr) + assert.Equal(t, report.ChannelID, decoded.ChannelID) + assert.Equal(t, report.ValidAfterSeconds, decoded.ValidAfterSeconds) + assert.Equal(t, report.ValidUntilSeconds, decoded.ValidUntilSeconds) + assert.Equal(t, report.Values, decoded.Values) + assert.Equal(t, report.Specimen, decoded.Specimen) + }) + }) + + t.Run("Decode errors on invalid report", func(t *testing.T) { + _, err := rc.Decode([]byte{1, 2, 3}) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + + longBad := make([]byte, 64) + for i := 0; i < len(longBad); i++ { + longBad[i] = byte(i) + } + _, err = rc.Decode(longBad) + assert.EqualError(t, err, "failed to decode report: abi: improperly encoded uint64 value") + }) +} diff --git a/core/services/llo/keyring.go b/core/services/llo/keyring.go new file mode 100644 index 00000000000..1d6eaebad38 --- /dev/null +++ b/core/services/llo/keyring.go @@ -0,0 +1,79 @@ +package llo + +import ( + "fmt" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +type LLOOnchainKeyring ocr3types.OnchainKeyring[llotypes.ReportInfo] + +var _ LLOOnchainKeyring = &onchainKeyring{} + +type Key interface { + Sign3(digest ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) + Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool + PublicKey() ocrtypes.OnchainPublicKey + MaxSignatureLength() int +} + +type onchainKeyring struct { + lggr logger.Logger + keys map[llotypes.ReportFormat]Key +} + +func NewOnchainKeyring(lggr logger.Logger, keys map[llotypes.ReportFormat]Key) LLOOnchainKeyring { + return &onchainKeyring{ + lggr.Named("OnchainKeyring"), keys, + } +} + +func (okr *onchainKeyring) PublicKey() types.OnchainPublicKey { + // All public keys combined + var pk []byte + for _, k := range okr.keys { + pk = append(pk, k.PublicKey()...) + } + return pk +} + +func (okr *onchainKeyring) MaxSignatureLength() (n int) { + // Needs to be max of all chain sigs + for _, k := range okr.keys { + n += k.MaxSignatureLength() + } + return +} + +func (okr *onchainKeyring) Sign(digest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[llotypes.ReportInfo]) (signature []byte, err error) { + rf := r.Info.ReportFormat + // HACK: sign/verify JSON payloads with EVM keys for now, this makes + // debugging and testing easier + if rf == llotypes.ReportFormatJSON { + rf = llotypes.ReportFormatEVM + } + if key, exists := okr.keys[rf]; exists { + return key.Sign3(digest, seqNr, r.Report) + } + return nil, fmt.Errorf("Sign failed; unsupported report format: %q", r.Info.ReportFormat) +} + +func (okr *onchainKeyring) Verify(key types.OnchainPublicKey, digest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[llotypes.ReportInfo], signature []byte) bool { + rf := r.Info.ReportFormat + // HACK: sign/verify JSON payloads with EVM keys for now, this makes + // debugging and testing easier + if rf == llotypes.ReportFormatJSON { + rf = llotypes.ReportFormatEVM + } + if verifier, exists := okr.keys[rf]; exists { + return verifier.Verify3(key, digest, seqNr, r.Report, signature) + } + okr.lggr.Errorf("Verify failed; unsupported report format: %q", r.Info.ReportFormat) + return false +} diff --git a/core/services/llo/keyring_test.go b/core/services/llo/keyring_test.go new file mode 100644 index 00000000000..bf728813801 --- /dev/null +++ b/core/services/llo/keyring_test.go @@ -0,0 +1,123 @@ +package llo + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + ocr3types "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var _ Key = &mockKey{} + +type mockKey struct { + format llotypes.ReportFormat + verify bool + maxSignatureLen int +} + +func (m *mockKey) Sign3(digest ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) { + return []byte(fmt.Sprintf("sig-%d", m.format)), nil +} + +func (m *mockKey) Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool { + return m.verify +} + +func (m *mockKey) PublicKey() ocrtypes.OnchainPublicKey { + b := make([]byte, m.maxSignatureLen) + for i := 0; i < m.maxSignatureLen; i++ { + b[i] = byte(255) + } + return ocrtypes.OnchainPublicKey(b) +} + +func (m *mockKey) MaxSignatureLength() int { + return m.maxSignatureLen +} + +func (m *mockKey) reset(format llotypes.ReportFormat) { + m.format = format + m.verify = false +} + +func Test_Keyring(t *testing.T) { + lggr := logger.TestLogger(t) + + ks := map[llotypes.ReportFormat]Key{ + llotypes.ReportFormatEVM: &mockKey{format: llotypes.ReportFormatEVM, maxSignatureLen: 1}, + llotypes.ReportFormatSolana: &mockKey{format: llotypes.ReportFormatSolana, maxSignatureLen: 2}, + llotypes.ReportFormatCosmos: &mockKey{format: llotypes.ReportFormatCosmos, maxSignatureLen: 4}, + llotypes.ReportFormatStarknet: &mockKey{format: llotypes.ReportFormatStarknet, maxSignatureLen: 8}, + } + + kr := NewOnchainKeyring(lggr, ks) + + cases := []struct { + format llotypes.ReportFormat + }{ + { + llotypes.ReportFormatEVM, + }, + { + llotypes.ReportFormatSolana, + }, + { + llotypes.ReportFormatCosmos, + }, + { + llotypes.ReportFormatStarknet, + }, + } + + cd, err := ocrtypes.BytesToConfigDigest(testutils.MustRandBytes(32)) + require.NoError(t, err) + seqNr := rand.Uint64() + t.Run("Sign+Verify", func(t *testing.T) { + for _, tc := range cases { + t.Run(tc.format.String(), func(t *testing.T) { + k := ks[tc.format] + defer k.(*mockKey).reset(tc.format) + + sig, err := kr.Sign(cd, seqNr, ocr3types.ReportWithInfo[llotypes.ReportInfo]{Info: llotypes.ReportInfo{ReportFormat: tc.format}}) + require.NoError(t, err) + + assert.Equal(t, []byte(fmt.Sprintf("sig-%d", tc.format)), sig) + + assert.False(t, kr.Verify(nil, cd, seqNr, ocr3types.ReportWithInfo[llotypes.ReportInfo]{Info: llotypes.ReportInfo{ReportFormat: tc.format}}, sig)) + + k.(*mockKey).verify = true + + for _, tc2 := range cases { + verified := kr.Verify(nil, cd, seqNr, ocr3types.ReportWithInfo[llotypes.ReportInfo]{Info: llotypes.ReportInfo{ReportFormat: tc2.format}}, sig) + if tc.format == tc2.format { + assert.True(t, verified, "expected true for %s", tc2.format) + } else { + assert.False(t, verified, "expected false for %s", tc2.format) + } + } + }) + } + }) + + t.Run("MaxSignatureLength", func(t *testing.T) { + assert.Equal(t, 8+4+2+1, kr.MaxSignatureLength()) + }) + t.Run("PublicKey", func(t *testing.T) { + b := make([]byte, 8+4+2+1) + for i := 0; i < len(b); i++ { + b[i] = byte(255) + } + assert.Equal(t, types.OnchainPublicKey(b), kr.PublicKey()) + }) +} diff --git a/core/services/llo/offchain_config_digester.go b/core/services/llo/offchain_config_digester.go new file mode 100644 index 00000000000..cd4d9afa3a0 --- /dev/null +++ b/core/services/llo/offchain_config_digester.go @@ -0,0 +1,123 @@ +package llo + +import ( + "crypto/ed25519" + "encoding/binary" + "encoding/hex" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/pkg/errors" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/wsrpc/credentials" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier" +) + +// Originally sourced from: https://github.com/smartcontractkit/offchain-reporting/blob/991ebe1462fd56826a1ddfb34287d542acb2baee/lib/offchainreporting2/chains/evmutil/offchain_config_digester.go + +var _ ocrtypes.OffchainConfigDigester = OffchainConfigDigester{} + +func NewOffchainConfigDigester(chainID *big.Int, contractAddress common.Address) OffchainConfigDigester { + return OffchainConfigDigester{chainID, contractAddress} +} + +type OffchainConfigDigester struct { + ChainID *big.Int + ContractAddress common.Address +} + +func (d OffchainConfigDigester) ConfigDigest(cc ocrtypes.ContractConfig) (ocrtypes.ConfigDigest, error) { + signers := []common.Address{} + for i, signer := range cc.Signers { + if len(signer) != 20 { + return ocrtypes.ConfigDigest{}, errors.Errorf("%v-th evm signer should be a 20 byte address, but got %x", i, signer) + } + a := common.BytesToAddress(signer) + signers = append(signers, a) + } + transmitters := []credentials.StaticSizedPublicKey{} + for i, transmitter := range cc.Transmitters { + if len(transmitter) != 2*ed25519.PublicKeySize { + return ocrtypes.ConfigDigest{}, errors.Errorf("%v-th evm transmitter should be a 64 character hex-encoded ed25519 public key, but got '%v' (%d chars)", i, transmitter, len(transmitter)) + } + var t credentials.StaticSizedPublicKey + b, err := hex.DecodeString(string(transmitter)) + if err != nil { + return ocrtypes.ConfigDigest{}, errors.Wrapf(err, "%v-th evm transmitter is not valid hex, got: %q", i, transmitter) + } + copy(t[:], b) + + transmitters = append(transmitters, t) + } + + return configDigest( + d.ChainID, + d.ContractAddress, + cc.ConfigCount, + signers, + transmitters, + cc.F, + cc.OnchainConfig, + cc.OffchainConfigVersion, + cc.OffchainConfig, + ) +} + +func (d OffchainConfigDigester) ConfigDigestPrefix() (ocrtypes.ConfigDigestPrefix, error) { + return ocrtypes.ConfigDigestPrefixLLO, nil +} + +func makeConfigDigestArgs() abi.Arguments { + abi, err := abi.JSON(strings.NewReader(exposed_channel_verifier.ExposedChannelVerifierABI)) + if err != nil { + // assertion + panic(fmt.Sprintf("could not parse aggregator ABI: %s", err.Error())) + } + return abi.Methods["exposedConfigDigestFromConfigData"].Inputs +} + +var configDigestArgs = makeConfigDigestArgs() + +func configDigest( + chainID *big.Int, + contractAddress common.Address, + configCount uint64, + oracles []common.Address, + transmitters []credentials.StaticSizedPublicKey, + f uint8, + onchainConfig []byte, + offchainConfigVersion uint64, + offchainConfig []byte, +) (types.ConfigDigest, error) { + msg, err := configDigestArgs.Pack( + chainID, + contractAddress, + configCount, + oracles, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + ) + if err != nil { + return types.ConfigDigest{}, fmt.Errorf("could not pack config digest args: %v", err) + } + rawHash := crypto.Keccak256(msg) + configDigest := types.ConfigDigest{} + if n := copy(configDigest[:], rawHash); n != len(configDigest) { + return types.ConfigDigest{}, fmt.Errorf("copied too little data: %d/%d", n, len(configDigest)) + } + binary.BigEndian.PutUint16(configDigest[:2], uint16(ocrtypes.ConfigDigestPrefixLLO)) + if !(configDigest[0] == 0 && configDigest[1] == 9) { + return types.ConfigDigest{}, fmt.Errorf("wrong ConfigDigestPrefix; got: %x, expected: %d", configDigest[:2], ocrtypes.ConfigDigestPrefixLLO) + } + return configDigest, nil +} diff --git a/core/services/llo/offchain_config_digester_test.go b/core/services/llo/offchain_config_digester_test.go new file mode 100644 index 00000000000..0de9117e391 --- /dev/null +++ b/core/services/llo/offchain_config_digester_test.go @@ -0,0 +1,55 @@ +package llo + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/require" +) + +func Test_OffchainConfigDigester_ConfigDigest(t *testing.T) { + // ChainID and ContractAddress are taken into account for computation + cd1, err := OffchainConfigDigester{ChainID: big.NewInt(0)}.ConfigDigest(types.ContractConfig{}) + require.NoError(t, err) + cd2, err := OffchainConfigDigester{ChainID: big.NewInt(0)}.ConfigDigest(types.ContractConfig{}) + require.NoError(t, err) + cd3, err := OffchainConfigDigester{ChainID: big.NewInt(1)}.ConfigDigest(types.ContractConfig{}) + require.NoError(t, err) + cd4, err := OffchainConfigDigester{ChainID: big.NewInt(1), ContractAddress: common.Address{1}}.ConfigDigest(types.ContractConfig{}) + require.NoError(t, err) + + require.Equal(t, cd1, cd2) + require.NotEqual(t, cd2, cd3) + require.NotEqual(t, cd2, cd4) + require.NotEqual(t, cd3, cd4) + + // malformed signers + _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ + Signers: []types.OnchainPublicKey{{1, 2}}, + }) + require.Error(t, err) + + // malformed transmitters + _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ + Transmitters: []types.Account{"0x"}, + }) + require.Error(t, err) + + _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ + Transmitters: []types.Account{"7343581f55146951b0f678dc6cfa8fd360e2f353"}, + }) + require.Error(t, err) + + _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ + Transmitters: []types.Account{"7343581f55146951b0f678dc6cfa8fd360e2f353aabbccddeeffaaccddeeffaz"}, + }) + require.Error(t, err) + + // well-formed transmitters + _, err = OffchainConfigDigester{ChainID: big.NewInt(0)}.ConfigDigest(types.ContractConfig{ + Transmitters: []types.Account{"7343581f55146951b0f678dc6cfa8fd360e2f353aabbccddeeffaaccddeeffaa"}, + }) + require.NoError(t, err) +} diff --git a/core/services/llo/onchain_channel_definition_cache.go b/core/services/llo/onchain_channel_definition_cache.go new file mode 100644 index 00000000000..af35d237b98 --- /dev/null +++ b/core/services/llo/onchain_channel_definition_cache.go @@ -0,0 +1,252 @@ +package llo + +import ( + "context" + "database/sql" + "errors" + "fmt" + "maps" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +type ChannelDefinitionCacheORM interface { + // TODO: What about delete/cleanup? + // https://smartcontract-it.atlassian.net/browse/MERC-3653 + LoadChannelDefinitions(ctx context.Context, addr common.Address) (dfns llotypes.ChannelDefinitions, blockNum int64, err error) + StoreChannelDefinitions(ctx context.Context, addr common.Address, dfns llotypes.ChannelDefinitions, blockNum int64) (err error) +} + +var channelConfigStoreABI abi.ABI + +func init() { + var err error + channelConfigStoreABI, err = abi.JSON(strings.NewReader(channel_config_store.ChannelConfigStoreABI)) + if err != nil { + panic(err) + } +} + +var _ llotypes.ChannelDefinitionCache = &channelDefinitionCache{} + +type channelDefinitionCache struct { + services.StateMachine + + orm ChannelDefinitionCacheORM + + filterName string + lp logpoller.LogPoller + fromBlock int64 + addr common.Address + lggr logger.Logger + + definitionsMu sync.RWMutex + definitions llotypes.ChannelDefinitions + definitionsBlockNum int64 + + wg sync.WaitGroup + chStop chan struct{} +} + +var ( + topicNewChannelDefinition = (channel_config_store.ChannelConfigStoreNewChannelDefinition{}).Topic() + topicChannelDefinitionRemoved = (channel_config_store.ChannelConfigStoreChannelDefinitionRemoved{}).Topic() + + allTopics = []common.Hash{topicNewChannelDefinition, topicChannelDefinitionRemoved} +) + +func NewChannelDefinitionCache(lggr logger.Logger, orm ChannelDefinitionCacheORM, lp logpoller.LogPoller, addr common.Address, fromBlock int64) llotypes.ChannelDefinitionCache { + filterName := logpoller.FilterName("OCR3 LLO ChannelDefinitionCachePoller", addr.String()) + return &channelDefinitionCache{ + services.StateMachine{}, + orm, + filterName, + lp, + 0, + addr, + lggr.Named("ChannelDefinitionCache").With("addr", addr, "fromBlock", fromBlock), + sync.RWMutex{}, + nil, + fromBlock, + sync.WaitGroup{}, + make(chan struct{}), + } +} + +func (c *channelDefinitionCache) Start(ctx context.Context) error { + // Initial load from DB, then async poll from chain thereafter + return c.StartOnce("ChannelDefinitionCache", func() (err error) { + err = c.lp.RegisterFilter(logpoller.Filter{Name: c.filterName, EventSigs: allTopics, Addresses: []common.Address{c.addr}}, pg.WithParentCtx(ctx)) + if err != nil { + return err + } + if definitions, definitionsBlockNum, err := c.orm.LoadChannelDefinitions(ctx, c.addr); err != nil { + return err + } else if definitions != nil { + c.definitions = definitions + c.definitionsBlockNum = definitionsBlockNum + } else { + // ensure non-nil map ready for assignment later + c.definitions = make(llotypes.ChannelDefinitions) + // leave c.definitionsBlockNum as provided fromBlock argument + } + c.wg.Add(1) + go c.poll() + return nil + }) +} + +// TODO: make this configurable? +const pollInterval = 1 * time.Second + +func (c *channelDefinitionCache) poll() { + defer c.wg.Done() + + pollT := time.NewTicker(utils.WithJitter(pollInterval)) + + for { + select { + case <-c.chStop: + return + case <-pollT.C: + if n, err := c.fetchFromChain(); err != nil { + // TODO: retry with backoff? + // https://smartcontract-it.atlassian.net/browse/MERC-3653 + c.lggr.Errorw("Failed to fetch channel definitions from chain", "err", err) + continue + } else { + if n > 0 { + c.lggr.Infow("Updated channel definitions", "nLogs", n, "definitionsBlockNum", c.definitionsBlockNum) + } else { + c.lggr.Debugw("No new channel definitions", "nLogs", 0, "definitionsBlockNum", c.definitionsBlockNum) + } + } + } + } +} + +func (c *channelDefinitionCache) fetchFromChain() (nLogs int, err error) { + // TODO: Pass context + // https://smartcontract-it.atlassian.net/browse/MERC-3653 + latest, err := c.lp.LatestBlock() + if errors.Is(err, sql.ErrNoRows) { + c.lggr.Debug("Logpoller has no logs yet, skipping poll") + return 0, nil + } else if err != nil { + return 0, err + } + toBlock := latest.BlockNumber + + fromBlock := c.definitionsBlockNum + + if toBlock <= fromBlock { + return 0, nil + } + + ctx, cancel := services.StopChan(c.chStop).NewCtx() + defer cancel() + // NOTE: We assume that log poller returns logs in ascending order chronologically + logs, err := c.lp.LogsWithSigs(fromBlock, toBlock, allTopics, c.addr, pg.WithParentCtx(ctx)) + if err != nil { + // TODO: retry? + // https://smartcontract-it.atlassian.net/browse/MERC-3653 + return 0, err + } + for _, log := range logs { + if err = c.applyLog(log); err != nil { + return 0, err + } + } + + // Use context.Background() here because we want to try to save even if we + // are closing + if err = c.orm.StoreChannelDefinitions(context.Background(), c.addr, c.Definitions(), toBlock); err != nil { + return 0, err + } + + c.definitionsBlockNum = toBlock + + return len(logs), nil +} + +func (c *channelDefinitionCache) applyLog(log logpoller.Log) error { + switch log.EventSig { + case topicNewChannelDefinition: + unpacked := new(channel_config_store.ChannelConfigStoreNewChannelDefinition) + + err := channelConfigStoreABI.UnpackIntoInterface(unpacked, "NewChannelDefinition", log.Data) + if err != nil { + return fmt.Errorf("failed to unpack log data: %w", err) + } + + c.applyNewChannelDefinition(unpacked) + case topicChannelDefinitionRemoved: + unpacked := new(channel_config_store.ChannelConfigStoreChannelDefinitionRemoved) + + err := channelConfigStoreABI.UnpackIntoInterface(unpacked, "ChannelDefinitionRemoved", log.Data) + if err != nil { + return fmt.Errorf("failed to unpack log data: %w", err) + } + + c.applyChannelDefinitionRemoved(unpacked) + default: + // don't return error here, we want to ignore unrecognized logs and + // continue rather than interrupting the loop + c.lggr.Errorw("Unexpected log topic", "topic", log.EventSig.Hex()) + } + return nil +} + +func (c *channelDefinitionCache) applyNewChannelDefinition(log *channel_config_store.ChannelConfigStoreNewChannelDefinition) { + streamIDs := make([]llotypes.StreamID, len(log.ChannelDefinition.StreamIDs)) + copy(streamIDs, log.ChannelDefinition.StreamIDs) + c.definitionsMu.Lock() + defer c.definitionsMu.Unlock() + c.definitions[log.ChannelId] = llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormat(log.ChannelDefinition.ReportFormat), + ChainSelector: log.ChannelDefinition.ChainSelector, + StreamIDs: streamIDs, + } +} + +func (c *channelDefinitionCache) applyChannelDefinitionRemoved(log *channel_config_store.ChannelConfigStoreChannelDefinitionRemoved) { + c.definitionsMu.Lock() + defer c.definitionsMu.Unlock() + delete(c.definitions, log.ChannelId) +} + +func (c *channelDefinitionCache) Close() error { + // TODO: unregister filter (on job delete)? + // https://smartcontract-it.atlassian.net/browse/MERC-3653 + return c.StopOnce("ChannelDefinitionCache", func() error { + close(c.chStop) + c.wg.Wait() + return nil + }) +} + +func (c *channelDefinitionCache) HealthReport() map[string]error { + report := map[string]error{c.Name(): c.Healthy()} + return report +} + +func (c *channelDefinitionCache) Name() string { return c.lggr.Name() } + +func (c *channelDefinitionCache) Definitions() llotypes.ChannelDefinitions { + c.definitionsMu.RLock() + defer c.definitionsMu.RUnlock() + return maps.Clone(c.definitions) +} diff --git a/core/services/llo/onchain_channel_definition_cache_test.go b/core/services/llo/onchain_channel_definition_cache_test.go new file mode 100644 index 00000000000..28e89a9c987 --- /dev/null +++ b/core/services/llo/onchain_channel_definition_cache_test.go @@ -0,0 +1,26 @@ +package llo + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" +) + +func Test_ChannelDefinitionCache(t *testing.T) { + t.Run("Definitions", func(t *testing.T) { + // NOTE: this is covered more thoroughly in the integration tests + dfns := llotypes.ChannelDefinitions(map[llotypes.ChannelID]llotypes.ChannelDefinition{ + 1: { + ReportFormat: llotypes.ReportFormat(43), + ChainSelector: 42, + StreamIDs: []llotypes.StreamID{1, 2, 3}, + }, + }) + + cdc := &channelDefinitionCache{definitions: dfns} + + assert.Equal(t, dfns, cdc.Definitions()) + }) +} diff --git a/core/services/llo/orm.go b/core/services/llo/orm.go new file mode 100644 index 00000000000..e046d62ad89 --- /dev/null +++ b/core/services/llo/orm.go @@ -0,0 +1,66 @@ +package llo + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +type ORM interface { + ChannelDefinitionCacheORM +} + +var _ ORM = &orm{} + +type orm struct { + q pg.Queryer + evmChainID *big.Int +} + +func NewORM(q pg.Queryer, evmChainID *big.Int) ORM { + return &orm{q, evmChainID} +} + +func (o *orm) LoadChannelDefinitions(ctx context.Context, addr common.Address) (dfns llotypes.ChannelDefinitions, blockNum int64, err error) { + type scd struct { + Definitions []byte `db:"definitions"` + BlockNum int64 `db:"block_num"` + } + var scanned scd + err = o.q.GetContext(ctx, &scanned, "SELECT definitions, block_num FROM channel_definitions WHERE evm_chain_id = $1 AND addr = $2", o.evmChainID.String(), addr) + if errors.Is(err, sql.ErrNoRows) { + return dfns, blockNum, nil + } else if err != nil { + return nil, 0, fmt.Errorf("failed to LoadChannelDefinitions; %w", err) + } + + if err = json.Unmarshal(scanned.Definitions, &dfns); err != nil { + return nil, 0, fmt.Errorf("failed to LoadChannelDefinitions; JSON Unmarshal failure; %w", err) + } + + return dfns, scanned.BlockNum, nil +} + +// TODO: Test this method +// https://smartcontract-it.atlassian.net/jira/software/c/projects/MERC/issues/MERC-3653 +func (o *orm) StoreChannelDefinitions(ctx context.Context, addr common.Address, dfns llotypes.ChannelDefinitions, blockNum int64) error { + _, err := o.q.ExecContext(ctx, ` +INSERT INTO channel_definitions (evm_chain_id, addr, definitions, block_num, updated_at) +VALUES ($1, $2, $3, $4, NOW()) +ON CONFLICT (evm_chain_id, addr) DO UPDATE +SET definitions = $3, block_num = $4, updated_at = NOW() +`, o.evmChainID.String(), addr, dfns, blockNum) + if err != nil { + return fmt.Errorf("StoreChannelDefinitions failed: %w", err) + } + return nil +} diff --git a/core/services/llo/orm_test.go b/core/services/llo/orm_test.go new file mode 100644 index 00000000000..63a6ac21e3b --- /dev/null +++ b/core/services/llo/orm_test.go @@ -0,0 +1,101 @@ +package llo + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" +) + +func Test_ORM(t *testing.T) { + db := pgtest.NewSqlxDB(t) + orm := NewORM(db, testutils.FixtureChainID) + ctx := testutils.Context(t) + + addr1 := testutils.NewAddress() + addr2 := testutils.NewAddress() + addr3 := testutils.NewAddress() + + t.Run("LoadChannelDefinitions", func(t *testing.T) { + t.Run("returns zero values if nothing in database", func(t *testing.T) { + cd, blockNum, err := orm.LoadChannelDefinitions(ctx, addr1) + require.NoError(t, err) + + assert.Zero(t, cd) + assert.Zero(t, blockNum) + + }) + t.Run("loads channel definitions from database", func(t *testing.T) { + expectedBlockNum := rand.Int63() + expectedBlockNum2 := rand.Int63() + cid1 := rand.Uint32() + cid2 := rand.Uint32() + + channelDefsJSON := fmt.Sprintf(` +{ + "%d": { + "reportFormat": 42, + "chainSelector": 142, + "streamIds": [1, 2] + }, + "%d": { + "reportFormat": 42, + "chainSelector": 142, + "streamIds": [1, 3] + } +} + `, cid1, cid2) + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) + VALUES ( $1, $2, $3, $4, NOW()) + `, addr1, testutils.FixtureChainID.String(), channelDefsJSON, expectedBlockNum) + + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) + VALUES ( $1, $2, $3, $4, NOW()) + `, addr2, testutils.FixtureChainID.String(), `{}`, expectedBlockNum2) + + { + // alternative chain ID; we expect these ones to be ignored + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) + VALUES ( $1, $2, $3, $4, NOW()) + `, addr1, testutils.SimulatedChainID.String(), channelDefsJSON, expectedBlockNum) + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) + VALUES ( $1, $2, $3, $4, NOW()) + `, addr3, testutils.SimulatedChainID.String(), channelDefsJSON, expectedBlockNum) + } + + cd, blockNum, err := orm.LoadChannelDefinitions(ctx, addr1) + require.NoError(t, err) + + assert.Equal(t, llotypes.ChannelDefinitions{ + cid1: llotypes.ChannelDefinition{ + ReportFormat: 42, + ChainSelector: 142, + StreamIDs: []llotypes.StreamID{1, 2}, + }, + cid2: llotypes.ChannelDefinition{ + ReportFormat: 42, + ChainSelector: 142, + StreamIDs: []llotypes.StreamID{1, 3}, + }, + }, cd) + assert.Equal(t, expectedBlockNum, blockNum) + + cd, blockNum, err = orm.LoadChannelDefinitions(ctx, addr2) + require.NoError(t, err) + + assert.Equal(t, llotypes.ChannelDefinitions{}, cd) + assert.Equal(t, expectedBlockNum2, blockNum) + }) + }) +} diff --git a/core/services/llo/static_channel_definitions_cache.go b/core/services/llo/static_channel_definitions_cache.go new file mode 100644 index 00000000000..bf26dd781ee --- /dev/null +++ b/core/services/llo/static_channel_definitions_cache.go @@ -0,0 +1,56 @@ +package llo + +import ( + "context" + "encoding/json" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// A CDC that loads a static JSON of channel definitions; useful for +// benchmarking and testing + +var _ llotypes.ChannelDefinitionCache = &staticCDC{} + +type staticCDC struct { + services.StateMachine + lggr logger.Logger + + definitions llotypes.ChannelDefinitions +} + +func NewStaticChannelDefinitionCache(lggr logger.Logger, dfnstr string) (llotypes.ChannelDefinitionCache, error) { + var definitions llotypes.ChannelDefinitions + if err := json.Unmarshal([]byte(dfnstr), &definitions); err != nil { + return nil, err + } + return &staticCDC{services.StateMachine{}, lggr.Named("StaticChannelDefinitionCache"), definitions}, nil +} + +func (s *staticCDC) Start(context.Context) error { + return s.StartOnce("StaticChannelDefinitionCache", func() error { + return nil + }) +} + +func (s *staticCDC) Close() error { + return s.StopOnce("StaticChannelDefinitionCache", func() error { + return nil + }) +} + +func (s *staticCDC) Definitions() llotypes.ChannelDefinitions { + return s.definitions +} + +func (s *staticCDC) HealthReport() map[string]error { + report := map[string]error{s.Name(): s.Healthy()} + return report +} + +func (s *staticCDC) Name() string { + return s.lggr.Name() +} diff --git a/core/services/llo/transmitter.go b/core/services/llo/transmitter.go new file mode 100644 index 00000000000..eef211ab5d5 --- /dev/null +++ b/core/services/llo/transmitter.go @@ -0,0 +1,153 @@ +package llo + +import ( + "context" + "crypto/ed25519" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" +) + +// LLO Transmitter implementation, based on +// core/services/relay/evm/mercury/transmitter.go + +// TODO: prom metrics (common with mercury/transmitter.go?) +// https://smartcontract-it.atlassian.net/browse/MERC-3659 + +const ( + // Mercury server error codes + DuplicateReport = 2 + // TODO: revisit these values in light of parallel composition + // https://smartcontract-it.atlassian.net/browse/MERC-3659 + // maxTransmitQueueSize = 10_000 + // maxDeleteQueueSize = 10_000 + // transmitTimeout = 5 * time.Second +) + +var PayloadTypes = getPayloadTypes() + +func getPayloadTypes() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "reportContext", Type: mustNewType("bytes32[2]")}, + {Name: "report", Type: mustNewType("bytes")}, + {Name: "rawRs", Type: mustNewType("bytes32[]")}, + {Name: "rawSs", Type: mustNewType("bytes32[]")}, + {Name: "rawVs", Type: mustNewType("bytes32")}, + }) +} + +type Transmitter interface { + llotypes.Transmitter + services.Service +} + +type transmitter struct { + services.StateMachine + lggr logger.Logger + rpcClient wsrpc.Client + fromAccount string +} + +func NewTransmitter(lggr logger.Logger, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey) Transmitter { + return &transmitter{ + services.StateMachine{}, + lggr, + rpcClient, + fmt.Sprintf("%x", fromAccount), + } +} + +func (t *transmitter) Start(ctx context.Context) error { + return nil +} + +func (t *transmitter) Close() error { + return nil +} + +func (t *transmitter) HealthReport() map[string]error { + report := map[string]error{t.Name(): t.Healthy()} + services.CopyHealth(report, t.rpcClient.HealthReport()) + return report +} + +func (t *transmitter) Name() string { return t.lggr.Name() } + +func (t *transmitter) Transmit( + ctx context.Context, + digest types.ConfigDigest, + seqNr uint64, + report ocr3types.ReportWithInfo[llotypes.ReportInfo], + sigs []types.AttributedOnchainSignature, +) (err error) { + var payload []byte + + switch report.Info.ReportFormat { + case llotypes.ReportFormatJSON: + fallthrough + case llotypes.ReportFormatEVM: + payload, err = encodeEVM(digest, seqNr, report.Report, sigs) + default: + return fmt.Errorf("Transmit failed; unsupported report format: %q", report.Info.ReportFormat) + } + + if err != nil { + return fmt.Errorf("Transmit: encode failed; %w", err) + } + + req := &pb.TransmitRequest{ + Payload: payload, + ReportFormat: uint32(report.Info.ReportFormat), + } + + // TODO: persistenceManager and queueing, error handling, retry etc + // https://smartcontract-it.atlassian.net/browse/MERC-3659 + _, err = t.rpcClient.Transmit(ctx, req) + return err +} + +func encodeEVM(digest types.ConfigDigest, seqNr uint64, report ocr2types.Report, sigs []types.AttributedOnchainSignature) ([]byte, error) { + var rs [][32]byte + var ss [][32]byte + var vs [32]byte + for i, as := range sigs { + r, s, v, err := evmutil.SplitSignature(as.Signature) + if err != nil { + return nil, fmt.Errorf("eventTransmit(ev): error in SplitSignature: %w", err) + } + rs = append(rs, r) + ss = append(ss, s) + vs[i] = v + } + rawReportCtx := ocr2key.RawReportContext3(digest, seqNr) + + payload, err := PayloadTypes.Pack(rawReportCtx, []byte(report), rs, ss, vs) + if err != nil { + return nil, fmt.Errorf("abi.Pack failed; %w", err) + } + return payload, nil +} + +// FromAccount returns the stringified (hex) CSA public key +func (t *transmitter) FromAccount() (ocr2types.Account, error) { + return ocr2types.Account(t.fromAccount), nil +} diff --git a/core/services/llo/transmitter_test.go b/core/services/llo/transmitter_test.go new file mode 100644 index 00000000000..eb231494c0b --- /dev/null +++ b/core/services/llo/transmitter_test.go @@ -0,0 +1,7 @@ +package llo + +import "testing" + +func Test_Transmitter(t *testing.T) { + // TODO: https://smartcontract-it.atlassian.net/browse/MERC-3659 +} diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 754f48013bd..336d1ae3800 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -36,6 +36,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" "github.com/smartcontractkit/chainlink-common/pkg/types" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -44,11 +45,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/llo" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/persistence" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/generic" + lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/median" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper" @@ -70,6 +74,7 @@ import ( evmmercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/services/streams" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/plugins" @@ -107,6 +112,7 @@ type Delegate struct { bridgeORM bridges.ORM mercuryORM evmmercury.ORM pipelineRunner pipeline.Runner + streamRegistry streams.Getter peerWrapper *ocrcommon.SingletonPeerWrapper monitoringEndpointGen telemetry.MonitoringEndpointGenerator cfg DelegateConfig @@ -219,6 +225,7 @@ func NewDelegate( bridgeORM bridges.ORM, mercuryORM evmmercury.ORM, pipelineRunner pipeline.Runner, + streamRegistry streams.Getter, peerWrapper *ocrcommon.SingletonPeerWrapper, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, legacyChains legacyevm.LegacyChainContainer, @@ -238,6 +245,7 @@ func NewDelegate( bridgeORM: bridgeORM, mercuryORM: mercuryORM, pipelineRunner: pipelineRunner, + streamRegistry: streamRegistry, peerWrapper: peerWrapper, monitoringEndpointGen: monitoringEndpointGen, legacyChains: legacyChains, @@ -435,6 +443,9 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { case types.Mercury: return d.newServicesMercury(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, ocrLogger) + case types.LLO: + return d.newServicesLLO(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, ocrLogger) + case types.Median: return d.newServicesMedian(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, ocrLogger) @@ -467,7 +478,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { func GetEVMEffectiveTransmitterID(jb *job.Job, chain legacyevm.Chain, lggr logger.SugaredLogger) (string, error) { spec := jb.OCR2OracleSpec - if spec.PluginType == types.Mercury { + if spec.PluginType == types.Mercury || spec.PluginType == types.LLO { return spec.TransmitterID.String, nil } @@ -775,6 +786,135 @@ func (d *Delegate) newServicesMercury( return mercuryServices, err2 } +func (d *Delegate) newServicesLLO( + ctx context.Context, + lggr logger.SugaredLogger, + jb job.Job, + bootstrapPeers []commontypes.BootstrapperLocator, + kb ocr2key.KeyBundle, + ocrDB *db, + lc ocrtypes.LocalConfig, + ocrLogger commontypes.Logger, +) ([]job.ServiceCtx, error) { + lggr = logger.Sugared(lggr.Named("LLO")) + spec := jb.OCR2OracleSpec + transmitterID := spec.TransmitterID.String + if len(transmitterID) != 64 { + return nil, errors.Errorf("ServicesForSpec: streams job type requires transmitter ID to be a 32-byte hex string, got: %q", transmitterID) + } + if _, err := hex.DecodeString(transmitterID); err != nil { + return nil, errors.Wrapf(err, "ServicesForSpec: streams job type requires transmitter ID to be a 32-byte hex string, got: %q", transmitterID) + } + + rid, err := spec.RelayID() + if err != nil { + return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "streams"} + } + if rid.Network != relay.EVM { + return nil, fmt.Errorf("streams services: expected EVM relayer got %s", rid.Network) + } + relayer, err := d.RelayGetter.Get(rid) + if err != nil { + return nil, ErrRelayNotEnabled{Err: err, Relay: spec.Relay, PluginName: "streams"} + } + + provider, err2 := relayer.NewLLOProvider(ctx, + types.RelayArgs{ + ExternalJobID: jb.ExternalJobID, + JobID: jb.ID, + ContractID: spec.ContractID, + New: d.isNewlyCreatedJob, + RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(spec.PluginType), + }, types.PluginArgs{ + TransmitterID: transmitterID, + PluginConfig: spec.PluginConfig.Bytes(), + }) + if err2 != nil { + return nil, err2 + } + + var pluginCfg lloconfig.PluginConfig + if err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginCfg); err != nil { + return nil, err + } + + kbm := make(map[llotypes.ReportFormat]llo.Key) + for rfStr, kbid := range pluginCfg.KeyBundleIDs { + k, err3 := d.ks.Get(kbid) + if err3 != nil { + return nil, fmt.Errorf("job %d (%s) specified key bundle ID %q for report format %s, but got error trying to load it: %w", jb.ID, jb.Name.ValueOrZero(), kbid, rfStr, err3) + } + rf, err4 := llotypes.ReportFormatFromString(rfStr) + if err4 != nil { + return nil, fmt.Errorf("job %d (%s) specified key bundle ID %q for report format %s, but it is not a recognized report format: %w", jb.ID, jb.Name.ValueOrZero(), kbid, rfStr, err4) + } + kbm[rf] = k + } + // NOTE: This is a bit messy because we assume chain type matches report + // format, and it may not in all cases. We don't yet know what report + // formats we need or how they correspond to chain types, so assume it's + // 1:1 for now but will change in future + // + // https://smartcontract-it.atlassian.net/browse/MERC-3722 + for _, s := range chaintype.SupportedChainTypes { + rf, err3 := llotypes.ReportFormatFromString(string(s)) + if err3 != nil { + return nil, fmt.Errorf("job %d (%s) has a chain type with no matching report format %s: %w", jb.ID, jb.Name.ValueOrZero(), s, err3) + } + if _, exists := kbm[rf]; !exists { + // Use the first if unspecified + kbs, err4 := d.ks.GetAllOfType(s) + if err4 != nil { + return nil, err4 + } + if len(kbs) == 0 { + // unsupported key type + continue + } else if len(kbs) > 1 { + lggr.Debugf("Multiple on-chain signing keys found for report format %s, using the first", rf.String()) + } + kbm[rf] = kbs[0] + } + } + + // FIXME: This is a bit confusing because the OCR2 key bundle actually + // includes an EVM on-chain key... but LLO only uses the key bundle for the + // offchain keys and the suppoprted onchain keys are defined in the plugin + // config on the job spec instead. + // https://smartcontract-it.atlassian.net/browse/MERC-3594 + lggr.Infof("Using on-chain signing keys for LLO job %d (%s): %v", jb.ID, jb.Name.ValueOrZero(), kbm) + kr := llo.NewOnchainKeyring(lggr, kbm) + + cfg := llo.DelegateConfig{ + Logger: lggr, + Queryer: pg.NewQ(d.db, lggr, d.cfg.Database()), + Runner: d.pipelineRunner, + Registry: d.streamRegistry, + + ChannelDefinitionCache: provider.ChannelDefinitionCache(), + + BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, + V2Bootstrappers: bootstrapPeers, + ContractTransmitter: provider.ContractTransmitter(), + ContractConfigTracker: provider.ContractConfigTracker(), + Database: ocrDB, + LocalConfig: lc, + // TODO: Telemetry for llo + // https://smartcontract-it.atlassian.net/browse/MERC-3603 + MonitoringEndpoint: nil, + OffchainConfigDigester: provider.OffchainConfigDigester(), + OffchainKeyring: kb, + OnchainKeyring: kr, + OCRLogger: ocrLogger, + } + oracle, err := llo.NewDelegate(cfg) + if err != nil { + return nil, err + } + return []job.ServiceCtx{provider, oracle}, nil +} + func (d *Delegate) newServicesMedian( ctx context.Context, lggr logger.SugaredLogger, diff --git a/core/services/ocr2/plugins/llo/config/config.go b/core/services/ocr2/plugins/llo/config/config.go new file mode 100644 index 00000000000..15bb5e816a8 --- /dev/null +++ b/core/services/ocr2/plugins/llo/config/config.go @@ -0,0 +1,112 @@ +// config is a separate package so that we can validate +// the config in other packages, for example in job at job create time. + +package config + +import ( + "encoding/json" + "errors" + "fmt" + "net/url" + "regexp" + + "github.com/ethereum/go-ethereum/common" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +type PluginConfig struct { + RawServerURL string `json:"serverURL" toml:"serverURL"` + ServerPubKey utils.PlainHexBytes `json:"serverPubKey" toml:"serverPubKey"` + + ChannelDefinitionsContractAddress common.Address `json:"channelDefinitionsContractAddress" toml:"channelDefinitionsContractAddress"` + ChannelDefinitionsContractFromBlock int64 `json:"channelDefinitionsContractFromBlock" toml:"channelDefinitionsContractFromBlock"` + + // NOTE: ChannelDefinitions is an override. + // If Channe}lDefinitions is specified, values for + // ChannelDefinitionsContractAddress and + // ChannelDefinitionsContractFromBlock will be ignored + ChannelDefinitions string `json:"channelDefinitions" toml:"channelDefinitions"` + + // BenchmarkMode is a flag to enable benchmarking mode. In this mode, the + // transmitter will not transmit anything at all and instead emit + // logs/metrics. + BenchmarkMode bool `json:"benchmarkMode" toml:"benchmarkMode"` + + // KeyBundleIDs maps supported keys to their respective bundle IDs + // Key must match llo's ReportFormat + KeyBundleIDs map[string]string `json:"keyBundleIDs" toml:"keyBundleIDs"` +} + +func (p PluginConfig) Validate() (merr error) { + if p.RawServerURL == "" { + merr = errors.New("llo: ServerURL must be specified") + } else { + var normalizedURI string + if schemeRegexp.MatchString(p.RawServerURL) { + normalizedURI = p.RawServerURL + } else { + normalizedURI = fmt.Sprintf("wss://%s", p.RawServerURL) + } + uri, err := url.ParseRequestURI(normalizedURI) + if err != nil { + merr = fmt.Errorf("llo: invalid value for ServerURL: %w", err) + } else if uri.Scheme != "wss" { + merr = fmt.Errorf(`llo: invalid scheme specified for MercuryServer, got: %q (scheme: %q) but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`, p.RawServerURL, uri.Scheme) + } + } + + if p.ChannelDefinitions != "" { + if p.ChannelDefinitionsContractAddress != (common.Address{}) { + merr = errors.Join(merr, errors.New("llo: ChannelDefinitionsContractAddress is not allowed if ChannelDefinitions is specified")) + } + if p.ChannelDefinitionsContractFromBlock != 0 { + merr = errors.Join(merr, errors.New("llo: ChannelDefinitionsContractFromBlock is not allowed if ChannelDefinitions is specified")) + } + var cd llotypes.ChannelDefinitions + if err := json.Unmarshal([]byte(p.ChannelDefinitions), &cd); err != nil { + merr = errors.Join(merr, fmt.Errorf("channelDefinitions is invalid JSON: %w", err)) + } + } else { + if p.ChannelDefinitionsContractAddress == (common.Address{}) { + merr = errors.Join(merr, errors.New("llo: ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified")) + } + } + + if len(p.ServerPubKey) != 32 { + merr = errors.Join(merr, errors.New("llo: ServerPubKey is required and must be a 32-byte hex string")) + } + + merr = errors.Join(merr, validateKeyBundleIDs(p.KeyBundleIDs)) + + return merr +} + +func validateKeyBundleIDs(keyBundleIDs map[string]string) error { + for k, v := range keyBundleIDs { + if k == "" { + return errors.New("llo: KeyBundleIDs: key must not be empty") + } + if v == "" { + return errors.New("llo: KeyBundleIDs: value must not be empty") + } + if _, err := llotypes.ReportFormatFromString(k); err != nil { + return fmt.Errorf("llo: KeyBundleIDs: key must be a recognized report format, got: %s (err: %w)", k, err) + } + if !chaintype.IsSupportedChainType(chaintype.ChainType(k)) { + return fmt.Errorf("llo: KeyBundleIDs: key must be a supported chain type, got: %s", k) + } + + } + return nil +} + +var schemeRegexp = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9+.-]*://`) +var wssRegexp = regexp.MustCompile(`^wss://`) + +func (p PluginConfig) ServerURL() string { + return wssRegexp.ReplaceAllString(p.RawServerURL, "") +} diff --git a/core/services/ocr2/plugins/llo/config/config_test.go b/core/services/ocr2/plugins/llo/config/config_test.go new file mode 100644 index 00000000000..136fac87a56 --- /dev/null +++ b/core/services/ocr2/plugins/llo/config/config_test.go @@ -0,0 +1,142 @@ +package config + +import ( + "fmt" + "testing" + + "github.com/pelletier/go-toml/v2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_Config(t *testing.T) { + t.Run("unmarshals from toml", func(t *testing.T) { + cdjson := `{ + "42": { + "reportFormat": 42, + "chainSelector": 142, + "streamIds": [1, 2] + }, + "43": { + "reportFormat": 42, + "chainSelector": 142, + "streamIds": [1, 3] + }, + "44": { + "reportFormat": 42, + "chainSelector": 143, + "streamIds": [1, 4] + } +}` + + t.Run("with all possible values set", func(t *testing.T) { + rawToml := fmt.Sprintf(` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + BenchmarkMode = true + ChannelDefinitionsContractAddress = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" + ChannelDefinitionsContractFromBlock = 1234 + ChannelDefinitions = """ +%s +"""`, cdjson) + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + assert.Equal(t, "example.com:80", mc.RawServerURL) + assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Equal(t, "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF", mc.ChannelDefinitionsContractAddress.Hex()) + assert.Equal(t, int64(1234), mc.ChannelDefinitionsContractFromBlock) + assert.JSONEq(t, cdjson, mc.ChannelDefinitions) + assert.True(t, mc.BenchmarkMode) + + err = mc.Validate() + require.Error(t, err) + + assert.Contains(t, err.Error(), "llo: ChannelDefinitionsContractAddress is not allowed if ChannelDefinitions is specified") + assert.Contains(t, err.Error(), "llo: ChannelDefinitionsContractFromBlock is not allowed if ChannelDefinitions is specified") + }) + + t.Run("with only channelDefinitions", func(t *testing.T) { + rawToml := fmt.Sprintf(` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + ChannelDefinitions = """ +%s +"""`, cdjson) + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + assert.Equal(t, "example.com:80", mc.RawServerURL) + assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.JSONEq(t, cdjson, mc.ChannelDefinitions) + assert.False(t, mc.BenchmarkMode) + + err = mc.Validate() + require.NoError(t, err) + }) + t.Run("with only channelDefinitions contract details", func(t *testing.T) { + rawToml := ` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + ChannelDefinitionsContractAddress = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"` + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + assert.Equal(t, "example.com:80", mc.RawServerURL) + assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Equal(t, "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF", mc.ChannelDefinitionsContractAddress.Hex()) + assert.False(t, mc.BenchmarkMode) + + err = mc.Validate() + require.NoError(t, err) + }) + t.Run("with missing ChannelDefinitionsContractAddress", func(t *testing.T) { + rawToml := ` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93"` + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + assert.Equal(t, "example.com:80", mc.RawServerURL) + assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.False(t, mc.BenchmarkMode) + + err = mc.Validate() + require.Error(t, err) + assert.EqualError(t, err, "llo: ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified") + }) + + t.Run("with invalid values", func(t *testing.T) { + rawToml := ` + ChannelDefinitionsContractFromBlock = "invalid" + ` + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.Error(t, err) + assert.EqualError(t, err, `toml: cannot decode TOML string into struct field config.PluginConfig.ChannelDefinitionsContractFromBlock of type int64`) + assert.False(t, mc.BenchmarkMode) + + rawToml = ` + ServerURL = "http://example.com" + ServerPubKey = "4242" + ` + + err = toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + err = mc.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), `invalid scheme specified for MercuryServer, got: "http://example.com" (scheme: "http") but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`) + assert.Contains(t, err.Error(), `ServerPubKey is required and must be a 32-byte hex string`) + }) + }) +} diff --git a/core/services/ocr2/plugins/llo/helpers_test.go b/core/services/ocr2/plugins/llo/helpers_test.go new file mode 100644 index 00000000000..ae9850134b9 --- /dev/null +++ b/core/services/ocr2/plugins/llo/helpers_test.go @@ -0,0 +1,356 @@ +package llo_test + +import ( + "context" + "crypto/ed25519" + "errors" + "fmt" + "io" + "math/big" + "net" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + + "github.com/smartcontractkit/wsrpc" + "github.com/smartcontractkit/wsrpc/credentials" + "github.com/smartcontractkit/wsrpc/peer" + + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" + "github.com/smartcontractkit/chainlink/v2/core/services/streams" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +var _ pb.MercuryServer = &mercuryServer{} + +type request struct { + pk credentials.StaticSizedPublicKey + req *pb.TransmitRequest +} + +func (r request) TransmitterID() ocr2types.Account { + return ocr2types.Account(fmt.Sprintf("%x", r.pk)) +} + +type mercuryServer struct { + privKey ed25519.PrivateKey + reqsCh chan request + t *testing.T + buildReport func() []byte +} + +func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request, buildReport func() []byte) *mercuryServer { + return &mercuryServer{privKey, reqsCh, t, buildReport} +} + +func (s *mercuryServer) Transmit(ctx context.Context, req *pb.TransmitRequest) (*pb.TransmitResponse, error) { + p, ok := peer.FromContext(ctx) + if !ok { + return nil, errors.New("could not extract public key") + } + r := request{p.PublicKey, req} + s.reqsCh <- r + + return &pb.TransmitResponse{ + Code: 1, + Error: "", + }, nil +} + +func (s *mercuryServer) LatestReport(ctx context.Context, lrr *pb.LatestReportRequest) (*pb.LatestReportResponse, error) { + p, ok := peer.FromContext(ctx) + if !ok { + return nil, errors.New("could not extract public key") + } + s.t.Logf("mercury server got latest report from %x for feed id 0x%x", p.PublicKey, lrr.FeedId) + + out := new(pb.LatestReportResponse) + out.Report = new(pb.Report) + out.Report.FeedId = lrr.FeedId + + report := s.buildReport() + payload, err := mercury.PayloadTypes.Pack(evmutil.RawReportContext(ocrtypes.ReportContext{}), report, [][32]byte{}, [][32]byte{}, [32]byte{}) + if err != nil { + require.NoError(s.t, err) + } + out.Report.Payload = payload + return out, nil +} + +func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.PublicKey) (serverURL string) { + // Set up the wsrpc server + lis, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("[MAIN] failed to listen: %v", err) + } + serverURL = lis.Addr().String() + s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys)) + + // Register mercury implementation with the wsrpc server + pb.RegisterMercuryServer(s, srv) + + // Start serving + go s.Serve(lis) + t.Cleanup(s.Stop) + + return +} + +type Node struct { + App chainlink.Application + ClientPubKey credentials.StaticSizedPublicKey + KeyBundle ocr2key.KeyBundle +} + +func (node *Node) AddStreamJob(t *testing.T, spec string) { + job, err := streams.ValidatedStreamSpec(spec) + require.NoError(t, err) + err = node.App.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) +} + +func (node *Node) AddLLOJob(t *testing.T, spec string) { + c := node.App.GetConfig() + job, err := validate.ValidatedOracleSpecToml(c.OCR2(), c.Insecure(), spec) + require.NoError(t, err) + err = node.App.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) +} + +func (node *Node) AddBootstrapJob(t *testing.T, spec string) { + job, err := ocrbootstrap.ValidatedBootstrapSpecToml(spec) + require.NoError(t, err) + err = node.App.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) +} + +func setupNode( + t *testing.T, + port int, + dbName string, + backend *backends.SimulatedBackend, + csaKey csakey.KeyV2, +) (app chainlink.Application, peerID string, clientPubKey credentials.StaticSizedPublicKey, ocr2kb ocr2key.KeyBundle, observedLogs *observer.ObservedLogs) { + k := big.NewInt(int64(port)) // keys unique to port + p2pKey := p2pkey.MustNewV2XXXTestingOnly(k) + rdr := keystest.NewRandReaderFromSeed(int64(port)) + ocr2kb = ocr2key.MustNewInsecure(rdr, chaintype.EVM) + + p2paddresses := []string{fmt.Sprintf("127.0.0.1:%d", port)} + + config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + // [JobPipeline] + c.JobPipeline.MaxSuccessfulRuns = ptr(uint64(0)) + + // [Feature] + c.Feature.UICSAKeys = ptr(true) + c.Feature.LogPoller = ptr(true) + c.Feature.FeedsManager = ptr(false) + + // [OCR] + c.OCR.Enabled = ptr(false) + + // [OCR2] + c.OCR2.Enabled = ptr(true) + c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(1 * time.Second) + + // [P2P] + c.P2P.PeerID = ptr(p2pKey.PeerID()) + c.P2P.TraceLogging = ptr(true) + + // [P2P.V2] + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.AnnounceAddresses = &p2paddresses + c.P2P.V2.ListenAddresses = &p2paddresses + c.P2P.V2.DeltaDial = commonconfig.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = commonconfig.MustNewDuration(5 * time.Second) + }) + + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) + app = cltest.NewApplicationWithConfigV2OnSimulatedBlockchain(t, config, backend, p2pKey, ocr2kb, csaKey, lggr.Named(dbName)) + err := app.Start(testutils.Context(t)) + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, app.Stop()) + }) + + return app, p2pKey.PeerID().Raw(), csaKey.StaticSizedPublicKey(), ocr2kb, observedLogs +} + +func ptr[T any](t T) *T { return &t } + +func addStreamJob( + t *testing.T, + node Node, + streamID uint32, + bridgeName string, +) { + node.AddStreamJob(t, fmt.Sprintf(` +type = "stream" +schemaVersion = 1 +name = "strm-spec-%d" +streamID = %d +observationSource = """ + // Benchmark Price + price1 [type=bridge name="%s" requestData="{\\"data\\":{\\"data\\":\\"foo\\"}}"]; + price1_parse [type=jsonparse path="result"]; + price1_multiply [type=multiply times=100000000 index=0]; + + price1 -> price1_parse -> price1_multiply; +""" + + `, + streamID, + streamID, + bridgeName, + )) +} +func addBootstrapJob(t *testing.T, bootstrapNode Node, chainID *big.Int, verifierAddress common.Address, name string) { + bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(` +type = "bootstrap" +relay = "evm" +schemaVersion = 1 +name = "boot-%s" +contractID = "%s" +contractConfigTrackerPollInterval = "1s" + +[relayConfig] +chainID = %s +providerType = "llo" + `, name, verifierAddress.Hex(), chainID.String())) +} + +func addLLOJob( + t *testing.T, + node Node, + verifierAddress, + configStoreAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int, + serverURL string, + serverPubKey, + clientPubKey ed25519.PublicKey, + jobName string, + chainID *big.Int, + fromBlock int, +) { + node.AddLLOJob(t, fmt.Sprintf(` +type = "offchainreporting2" +schemaVersion = 1 +name = "%[1]s" +forwardingAllowed = false +maxTaskDuration = "1s" +contractID = "%[2]s" +contractConfigTrackerPollInterval = "1s" +ocrKeyBundleID = "%[3]s" +p2pv2Bootstrappers = [ + "%[4]s" +] +relay = "evm" +pluginType = "llo" +transmitterID = "%[5]x" + +[pluginConfig] +serverURL = "%[6]s" +serverPubKey = "%[7]x" +channelDefinitionsContractFromBlock = %[8]d +channelDefinitionsContractAddress = "%[9]s" + +[relayConfig] +chainID = %[10]s +fromBlock = 1`, + jobName, + verifierAddress.Hex(), + node.KeyBundle.ID(), + fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), + clientPubKey, + serverURL, + serverPubKey, + fromBlock, + configStoreAddress.Hex(), + chainID.String(), + )) +} + +func addOCRJobs(t *testing.T, streams []Stream, serverPubKey ed25519.PublicKey, serverURL string, verifierAddress common.Address, bootstrapPeerID string, bootstrapNodePort int, nodes []Node, configStoreAddress common.Address, clientPubKeys []ed25519.PublicKey, chainID *big.Int, fromBlock int) { + createBridge := func(name string, i int, p *big.Int, borm bridges.ORM) (bridgeName string) { + bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + b, err := io.ReadAll(req.Body) + require.NoError(t, err) + require.Equal(t, `{"data":{"data":"foo"}}`, string(b)) + + res.WriteHeader(http.StatusOK) + val := decimal.NewFromBigInt(p, 0).Div(decimal.NewFromInt(multiplier)).Add(decimal.NewFromInt(int64(i)).Div(decimal.NewFromInt(100))).String() + resp := fmt.Sprintf(`{"result": %s}`, val) + _, err = res.Write([]byte(resp)) + require.NoError(t, err) + })) + t.Cleanup(bridge.Close) + u, _ := url.Parse(bridge.URL) + bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) + require.NoError(t, borm.CreateBridgeType(&bridges.BridgeType{ + Name: bridges.BridgeName(bridgeName), + URL: models.WebURL(*u), + })) + + return bridgeName + } + + // Add OCR jobs - one per feed on each node + for i, node := range nodes { + for j, strm := range streams { + bmBridge := createBridge(fmt.Sprintf("benchmarkprice-%d-%d", strm.id, j), i, strm.baseBenchmarkPrice, node.App.BridgeORM()) + addStreamJob( + t, + node, + strm.id, + bmBridge, + ) + } + addLLOJob( + t, + node, + verifierAddress, + configStoreAddress, + bootstrapPeerID, + bootstrapNodePort, + serverURL, + serverPubKey, + clientPubKeys[i], + "feed-1", + chainID, + fromBlock, + ) + } +} diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go new file mode 100644 index 00000000000..df77316e4dd --- /dev/null +++ b/core/services/ocr2/plugins/llo/integration_test.go @@ -0,0 +1,370 @@ +package llo_test + +import ( + "crypto/ed25519" + "encoding/hex" + "fmt" + "math/big" + "math/rand" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/hashicorp/consul/sdk/freeport" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils" + datastreamsllo "github.com/smartcontractkit/chainlink-data-streams/llo" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/llo" + lloevm "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" +) + +var ( + fNodes = uint8(1) + nNodes = 4 // number of nodes (not including bootstrap) + multiplier int64 = 100000000 +) + +func setupBlockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend, *channel_verifier.ChannelVerifier, common.Address, *channel_config_store.ChannelConfigStore, common.Address) { + steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner + genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + backend.Commit() + backend.Commit() // ensure starting block number at least 1 + + // Deploy contracts + verifierProxyAddr, _, _, err := verifier_proxy.DeployVerifierProxy(steve, backend, common.Address{}) // zero address for access controller disables access control + require.NoError(t, err) + + verifierAddress, _, verifierContract, err := channel_verifier.DeployChannelVerifier(steve, backend, verifierProxyAddr) + require.NoError(t, err) + configStoreAddress, _, configStoreContract, err := channel_config_store.DeployChannelConfigStore(steve, backend) + require.NoError(t, err) + + backend.Commit() + + return steve, backend, verifierContract, verifierAddress, configStoreContract, configStoreAddress +} + +type Stream struct { + id uint32 + baseBenchmarkPrice *big.Int +} + +func TestIntegration_LLO(t *testing.T) { + testStartTimeStamp := uint32(time.Now().Unix()) + + const fromBlock = 1 // cannot use zero, start from block 1 + + // streams + btcStream := Stream{ + id: 51, + baseBenchmarkPrice: big.NewInt(20_000 * multiplier), + } + ethStream := Stream{ + id: 52, + baseBenchmarkPrice: big.NewInt(1_568 * multiplier), + } + linkStream := Stream{ + id: 53, + baseBenchmarkPrice: big.NewInt(7150 * multiplier / 1000), + } + dogeStream := Stream{ + id: 54, + baseBenchmarkPrice: big.NewInt(2_020 * multiplier), + } + streams := []Stream{btcStream, ethStream, linkStream, dogeStream} + streamMap := make(map[uint32]Stream) + for _, strm := range streams { + streamMap[strm.id] = strm + } + + reqs := make(chan request) + serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) + serverPubKey := serverKey.PublicKey + srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs, nil) + + clientCSAKeys := make([]csakey.KeyV2, nNodes) + clientPubKeys := make([]ed25519.PublicKey, nNodes) + for i := 0; i < nNodes; i++ { + k := big.NewInt(int64(i)) + key := csakey.MustNewV2XXXTestingOnly(k) + clientCSAKeys[i] = key + clientPubKeys[i] = key.PublicKey + } + serverURL := startMercuryServer(t, srv, clientPubKeys) + chainID := testutils.SimulatedChainID + + steve, backend, verifierContract, verifierAddress, configStoreContract, configStoreAddress := setupBlockchain(t) + + // Setup bootstrap + bootstrapCSAKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) + bootstrapNodePort := freeport.GetOne(t) + appBootstrap, bootstrapPeerID, _, bootstrapKb, _ := setupNode(t, bootstrapNodePort, "bootstrap_mercury", backend, bootstrapCSAKey) + bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb} + + // Setup oracle nodes + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + ports := freeport.GetN(t, nNodes) + for i := 0; i < nNodes; i++ { + app, peerID, transmitter, kb, _ := setupNode(t, ports[i], fmt.Sprintf("oracle_streams_%d", i), backend, clientCSAKeys[i]) + + nodes = append(nodes, Node{ + app, transmitter, kb, + }) + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: ocr2types.Account(fmt.Sprintf("%x", transmitter[:])), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + } + + configDigest := setConfig(t, steve, backend, verifierContract, verifierAddress, nodes, oracles) + channelDefinitions := setChannelDefinitions(t, steve, backend, configStoreContract, streams) + + // Bury everything with finality depth + ch, err := nodes[0].App.GetRelayers().LegacyEVMChains().Get(testutils.SimulatedChainID.String()) + require.NoError(t, err) + finalityDepth := ch.Config().EVM().FinalityDepth() + for i := 0; i < int(finalityDepth); i++ { + backend.Commit() + } + + addBootstrapJob(t, bootstrapNode, chainID, verifierAddress, "job-1") + addOCRJobs(t, streams, serverPubKey, serverURL, verifierAddress, bootstrapPeerID, bootstrapNodePort, nodes, configStoreAddress, clientPubKeys, chainID, fromBlock) + + t.Run("receives at least one report per feed from each oracle when EAs are at 100% reliability", func(t *testing.T) { + // Expect at least one report per channel from each oracle (keyed by transmitter ID) + seen := make(map[ocr2types.Account]map[llotypes.ChannelID]struct{}) + + for channelID, defn := range channelDefinitions { + t.Logf("Expect report for channel ID %x (definition: %#v)", channelID, defn) + } + for _, o := range oracles { + t.Logf("Expect report from oracle %s", o.OracleIdentity.TransmitAccount) + seen[o.OracleIdentity.TransmitAccount] = make(map[llotypes.ChannelID]struct{}) + } + + for req := range reqs { + if _, exists := seen[req.TransmitterID()]; !exists { + // oracle already reported on all channels; discard + continue + } + + v := make(map[string]interface{}) + err := llo.PayloadTypes.UnpackIntoMap(v, req.req.Payload) + require.NoError(t, err) + report, exists := v["report"] + if !exists { + t.Fatalf("FAIL: expected payload %#v to contain 'report'", v) + } + + t.Logf("Got report from oracle %x with format: %d", req.pk, req.req.ReportFormat) + + var r datastreamsllo.Report + + switch req.req.ReportFormat { + case uint32(llotypes.ReportFormatJSON): + t.Logf("Got report (JSON) from oracle %x: %s", req.pk, string(report.([]byte))) + var err error + r, err = (datastreamsllo.JSONReportCodec{}).Decode(report.([]byte)) + require.NoError(t, err, "expected valid JSON") + case uint32(llotypes.ReportFormatEVM): + t.Logf("Got report (EVM) from oracle %x: 0x%x", req.pk, report.([]byte)) + var err error + r, err = (lloevm.ReportCodec{}).Decode(report.([]byte)) + require.NoError(t, err, "expected valid EVM encoding") + default: + t.Fatalf("FAIL: unexpected report format: %q", req.req.ReportFormat) + } + + assert.Equal(t, configDigest, r.ConfigDigest) + assert.Equal(t, uint64(0x2ee634951ef71b46), r.ChainSelector) + assert.GreaterOrEqual(t, r.SeqNr, uint64(1)) + assert.GreaterOrEqual(t, r.ValidAfterSeconds, testStartTimeStamp) + assert.Equal(t, r.ValidAfterSeconds+1, r.ValidUntilSeconds) + + // values + defn, exists := channelDefinitions[r.ChannelID] + require.True(t, exists, "expected channel ID to be in channelDefinitions") + + require.Equal(t, len(defn.StreamIDs), len(r.Values)) + + for i, strmID := range defn.StreamIDs { + strm, exists := streamMap[strmID] + require.True(t, exists, "invariant violation: expected stream ID to be present") + assert.InDelta(t, strm.baseBenchmarkPrice.Int64(), r.Values[i].Int64(), 5000000) + } + + assert.False(t, r.Specimen) + + seen[req.TransmitterID()][r.ChannelID] = struct{}{} + t.Logf("Got report from oracle %s with channel: %x)", req.TransmitterID(), r.ChannelID) + + if _, exists := seen[req.TransmitterID()]; exists && len(seen[req.TransmitterID()]) == len(channelDefinitions) { + t.Logf("All channels reported for oracle with transmitterID %s", req.TransmitterID()) + delete(seen, req.TransmitterID()) + } + if len(seen) == 0 { + break // saw all oracles; success! + } + + // bit of a hack here but shouldn't hurt anything, we wanna dump + // `seen` before the test ends to aid in debugging test failures + if d, ok := t.Deadline(); ok { + select { + case <-time.After(time.Until(d.Add(-100 * time.Millisecond))): + if len(seen) > 0 { + t.Fatalf("FAILED: ERROR: missing expected reports: %#v\n", seen) + } + default: + } + } + } + }) + + // TODO: test verification +} + +func setConfig(t *testing.T, steve *bind.TransactOpts, backend *backends.SimulatedBackend, verifierContract *channel_verifier.ChannelVerifier, verifierAddress common.Address, nodes []Node, oracles []confighelper.OracleIdentityExtra) ocr2types.ConfigDigest { + // Setup config on contract + rawOnchainConfig := datastreamsllo.OnchainConfig{} + onchainConfig, err := (&datastreamsllo.JSONOnchainConfigCodec{}).Encode(rawOnchainConfig) + require.NoError(t, err) + + rawReportingPluginConfig := datastreamsllo.OffchainConfig{} + reportingPluginConfig, err := rawReportingPluginConfig.Encode() + require.NoError(t, err) + + signers, _, _, _, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + 2*time.Second, // DeltaProgress + 20*time.Second, // DeltaResend + 400*time.Millisecond, // DeltaInitial + 1000*time.Millisecond, // DeltaRound + 500*time.Millisecond, // DeltaGrace + 300*time.Millisecond, // DeltaCertifiedCommitRequest + 1*time.Minute, // DeltaStage + 100, // rMax + []int{len(nodes)}, // S + oracles, + reportingPluginConfig, // reportingPluginConfig []byte, + 0, // maxDurationQuery + 250*time.Millisecond, // maxDurationObservation + 0, // maxDurationShouldAcceptAttestedReport + 0, // maxDurationShouldTransmitAcceptedReport + int(fNodes), // f + onchainConfig, + ) + + require.NoError(t, err) + signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) + require.NoError(t, err) + + offchainTransmitters := make([][32]byte, nNodes) + for i := 0; i < nNodes; i++ { + offchainTransmitters[i] = nodes[i].ClientPubKey + } + + _, err = verifierContract.SetConfig(steve, signerAddresses, offchainTransmitters, fNodes, offchainConfig, offchainConfigVersion, offchainConfig, nil) + require.NoError(t, err) + + backend.Commit() + + accounts := make([]ocr2types.Account, len(offchainTransmitters)) + for i := range offchainTransmitters { + accounts[i] = ocr2types.Account(fmt.Sprintf("%x", offchainTransmitters[i])) + } + + l, err := verifierContract.LatestConfigDigestAndEpoch(&bind.CallOpts{}) + require.NoError(t, err) + + return l.ConfigDigest +} + +func setChannelDefinitions(t *testing.T, steve *bind.TransactOpts, backend *backends.SimulatedBackend, configStoreContract *channel_config_store.ChannelConfigStore, streams []Stream) map[llotypes.ChannelID]channel_config_store.IChannelConfigStoreChannelDefinition { + channels := []llotypes.ChannelID{ + rand.Uint32(), + rand.Uint32(), + rand.Uint32(), + rand.Uint32(), + } + + chainSelector, err := chainselectors.SelectorFromChainId(testutils.SimulatedChainID.Uint64()) + require.NoError(t, err) + + streamIDs := make([]uint32, len(streams)) + for i := 0; i < len(streams); i++ { + streamIDs[i] = streams[i].id + } + + // First set contains [1,len(streams)] + channel0Def := channel_config_store.IChannelConfigStoreChannelDefinition{ + ReportFormat: uint32(llotypes.ReportFormatJSON), + ChainSelector: chainSelector, + StreamIDs: streamIDs[1:len(streams)], + } + channel1Def := channel_config_store.IChannelConfigStoreChannelDefinition{ + ReportFormat: uint32(llotypes.ReportFormatEVM), + ChainSelector: chainSelector, + StreamIDs: streamIDs[1:len(streams)], + } + + // Second set contains [0,len(streams)-1] + channel2Def := channel_config_store.IChannelConfigStoreChannelDefinition{ + ReportFormat: uint32(llotypes.ReportFormatJSON), + ChainSelector: chainSelector, + StreamIDs: streamIDs[0 : len(streams)-1], + } + channel3Def := channel_config_store.IChannelConfigStoreChannelDefinition{ + ReportFormat: uint32(llotypes.ReportFormatEVM), + ChainSelector: chainSelector, + StreamIDs: streamIDs[0 : len(streams)-1], + } + + require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channels[0], channel0Def))) + require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channels[1], channel1Def))) + require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channels[2], channel2Def))) + require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channels[3], channel3Def))) + + backend.Commit() + + channelDefinitions := make(map[llotypes.ChannelID]channel_config_store.IChannelConfigStoreChannelDefinition) + + channelDefinitions[channels[0]] = channel0Def + channelDefinitions[channels[1]] = channel1Def + channelDefinitions[channels[2]] = channel2Def + channelDefinitions[channels[3]] = channel3Def + + backend.Commit() + + return channelDefinitions +} diff --git a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go new file mode 100644 index 00000000000..a9ba09d96bb --- /dev/null +++ b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go @@ -0,0 +1,213 @@ +package llo_test + +import ( + "math/rand" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/ethconfig" + chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "github.com/test-go/testify/assert" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/llo" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +func Test_ChannelDefinitionCache_Integration(t *testing.T) { + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.InfoLevel) + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + orm := llo.NewORM(db, testutils.SimulatedChainID) + + steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner + genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + backend.Commit() // ensure starting block number at least 1 + + ethClient := client.NewSimulatedBackendClient(t, backend, testutils.SimulatedChainID) + + configStoreAddress, _, configStoreContract, err := channel_config_store.DeployChannelConfigStore(steve, backend) + require.NoError(t, err) + + channel1 := rand.Uint32() + channel2 := rand.Uint32() + channel3 := rand.Uint32() + + chainSelector, err := chainselectors.SelectorFromChainId(testutils.SimulatedChainID.Uint64()) + require.NoError(t, err) + + streamIDs := []uint32{1, 2, 3} + channel1Def := channel_config_store.IChannelConfigStoreChannelDefinition{ + ReportFormat: uint32(llotypes.ReportFormatSolana), + ChainSelector: chainSelector, + StreamIDs: streamIDs, + } + channel2Def := channel_config_store.IChannelConfigStoreChannelDefinition{ + ReportFormat: uint32(llotypes.ReportFormatEVM), + ChainSelector: chainSelector, + StreamIDs: streamIDs, + } + channel3Def := channel_config_store.IChannelConfigStoreChannelDefinition{ + ReportFormat: uint32(llotypes.ReportFormatEVM), + ChainSelector: chainSelector, + StreamIDs: append(streamIDs, 4), + } + + require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channel1, channel1Def))) + require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channel2, channel2Def))) + + h := backend.Commit() + channel2Block, err := backend.BlockByHash(ctx, h) + require.NoError(t, err) + + t.Run("with zero fromblock", func(t *testing.T) { + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000) + servicetest.Run(t, lp) + cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, 0) + + servicetest.Run(t, cdc) + + testutils.WaitForLogMessage(t, observedLogs, "Updated channel definitions") + + dfns := cdc.Definitions() + + require.Len(t, dfns, 2) + require.Contains(t, dfns, channel1) + require.Contains(t, dfns, channel2) + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatSolana, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3}, + }, dfns[channel1]) + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVM, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3}, + }, dfns[channel2]) + + // remove solana + require.NoError(t, utils.JustError(configStoreContract.RemoveChannel(steve, channel1))) + backend.Commit() + testutils.WaitForLogMessageCount(t, observedLogs, "Updated channel definitions", 2) + dfns = cdc.Definitions() + + require.Len(t, dfns, 1) + assert.NotContains(t, dfns, channel1) + require.Contains(t, dfns, channel2) + + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVM, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3}, + }, dfns[channel2]) + + // add channel3 with additional stream + require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channel3, channel3Def))) + backend.Commit() + testutils.WaitForLogMessageCount(t, observedLogs, "Updated channel definitions", 3) + dfns = cdc.Definitions() + + require.Len(t, dfns, 2) + require.Contains(t, dfns, channel2) + require.Contains(t, dfns, channel3) + + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVM, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3}, + }, dfns[channel2]) + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVM, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3, 4}, + }, dfns[channel3]) + }) + + t.Run("loads from ORM", func(t *testing.T) { + // Override logpoller to always return no logs + lp := &mockLogPoller{ + LogPoller: logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000), + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 0, nil + }, + LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + return []logpoller.Log{}, nil + }, + } + cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, 0) + + servicetest.Run(t, cdc) + + dfns := cdc.Definitions() + + require.Len(t, dfns, 2) + require.Contains(t, dfns, channel2) + require.Contains(t, dfns, channel3) + + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVM, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3}, + }, dfns[channel2]) + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVM, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3, 4}, + }, dfns[channel3]) + }) + + // clear out DB for next test + pgtest.MustExec(t, db, `DELETE FROM channel_definitions`) + + t.Run("with non-zero fromBlock", func(t *testing.T) { + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000) + servicetest.Run(t, lp) + cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, channel2Block.Number().Int64()+1) + + // should only detect events from AFTER channel 2 was added + servicetest.Run(t, cdc) + + testutils.WaitForLogMessageCount(t, observedLogs, "Updated channel definitions", 4) + + dfns := cdc.Definitions() + + require.Len(t, dfns, 1) + require.Contains(t, dfns, channel3) + + assert.Equal(t, llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVM, + ChainSelector: chainSelector, + StreamIDs: []uint32{1, 2, 3, 4}, + }, dfns[channel3]) + }) +} + +type mockLogPoller struct { + logpoller.LogPoller + LatestBlockFn func(qopts ...pg.QOpt) (int64, error) + LogsWithSigsFn func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) +} + +func (p *mockLogPoller) LogsWithSigs(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + return p.LogsWithSigsFn(start, end, eventSigs, address, qopts...) +} +func (p *mockLogPoller) LatestBlock(qopts ...pg.QOpt) (logpoller.LogPollerBlock, error) { + block, err := p.LatestBlockFn(qopts...) + return logpoller.LogPollerBlock{BlockNumber: block}, err +} diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 0ebc6a5e354..36189475898 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -38,7 +38,7 @@ import ( v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" - relaymercury "github.com/smartcontractkit/chainlink-data-streams/mercury" + datastreamsmercury "github.com/smartcontractkit/chainlink-data-streams/mercury" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -67,7 +67,7 @@ var ( Min: big.NewInt(0), Max: big.NewInt(math.MaxInt64), } - rawReportingPluginConfig = relaymercury.OffchainConfig{ + rawReportingPluginConfig = datastreamsmercury.OffchainConfig{ ExpirationWindow: 1, BaseUSDFee: decimal.NewFromInt(100), } @@ -273,7 +273,7 @@ func integration_MercuryV1(t *testing.T) { } // Setup config on contract - onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) + onchainConfig, err := (datastreamsmercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) require.NoError(t, err) reportingPluginConfig, err := json.Marshal(rawReportingPluginConfig) @@ -623,7 +623,7 @@ func integration_MercuryV2(t *testing.T) { } // Setup config on contract - onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) + onchainConfig, err := (datastreamsmercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) require.NoError(t, err) reportingPluginConfig, err := json.Marshal(rawReportingPluginConfig) @@ -707,7 +707,7 @@ func integration_MercuryV2(t *testing.T) { continue // already saw all oracles for this feed } - expectedFee := relaymercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFee) + expectedFee := datastreamsmercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFee) expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) @@ -907,7 +907,7 @@ func integration_MercuryV3(t *testing.T) { } // Setup config on contract - onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) + onchainConfig, err := (datastreamsmercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) require.NoError(t, err) reportingPluginConfig, err := json.Marshal(rawReportingPluginConfig) @@ -991,7 +991,7 @@ func integration_MercuryV3(t *testing.T) { continue // already saw all oracles for this feed } - expectedFee := relaymercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFee) + expectedFee := datastreamsmercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFee) expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 9fe779b244f..5846eaa032f 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/job" dkgconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/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" ocr2vrfconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" @@ -113,6 +114,8 @@ func validateSpec(tree *toml.Tree, spec job.Job) error { return nil case types.Mercury: return validateOCR2MercurySpec(spec.OCR2OracleSpec.PluginConfig, *spec.OCR2OracleSpec.FeedID) + case types.LLO: + return validateOCR2LLOSpec(spec.OCR2OracleSpec.PluginConfig) case types.GenericPlugin: return validateOCR2GenericPluginSpec(spec.OCR2OracleSpec.PluginConfig) case "": @@ -256,3 +259,12 @@ func validateOCR2MercurySpec(jsonConfig job.JSONConfig, feedId [32]byte) error { } return pkgerrors.Wrap(mercuryconfig.ValidatePluginConfig(pluginConfig, feedId), "Mercury PluginConfig is invalid") } + +func validateOCR2LLOSpec(jsonConfig job.JSONConfig) error { + var pluginConfig lloconfig.PluginConfig + err := json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) + if err != nil { + return pkgerrors.Wrap(err, "error while unmarshaling plugin config") + } + return pkgerrors.Wrap(pluginConfig.Validate(), "LLO PluginConfig is invalid") +} diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index 7912741802c..27ddd53bd52 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -39,8 +39,10 @@ type Delegate struct { isNewlyCreatedJob bool } -// Extra fields to enable router proxy contract support. Must match field names of functions' PluginConfig. -type relayConfigRouterContractFields struct { +type relayConfig struct { + // providerType used for determining which type of contract to track config on + ProviderType string `json:"providerType"` + // Extra fields to enable router proxy contract support. Must match field names of functions' PluginConfig. DONID string `json:"donID"` ContractVersion uint32 `json:"contractVersion"` ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"` @@ -109,14 +111,14 @@ func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err e } ctx := ctxVals.ContextWithValues(context.Background()) - var routerFields relayConfigRouterContractFields - if err = json.Unmarshal(spec.RelayConfig.Bytes(), &routerFields); err != nil { + var relayCfg relayConfig + if err = json.Unmarshal(spec.RelayConfig.Bytes(), &relayCfg); err != nil { return nil, err } var configProvider types.ConfigProvider - if routerFields.DONID != "" { - if routerFields.ContractVersion != 1 || routerFields.ContractUpdateCheckFrequencySec == 0 { + if relayCfg.DONID != "" { + if relayCfg.ContractVersion != 1 || relayCfg.ContractUpdateCheckFrequencySec == 0 { return nil, errors.New("invalid router contract config") } configProvider, err = relayer.NewPluginProvider( @@ -140,6 +142,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err e ContractID: spec.ContractID, New: d.isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: relayCfg.ProviderType, }) } diff --git a/core/services/pipeline/mocks/runner.go b/core/services/pipeline/mocks/runner.go index f6e5033eae9..1de72bbf4c0 100644 --- a/core/services/pipeline/mocks/runner.go +++ b/core/services/pipeline/mocks/runner.go @@ -132,6 +132,36 @@ func (_m *Runner) HealthReport() map[string]error { return r0 } +// InitializePipeline provides a mock function with given fields: spec +func (_m *Runner) InitializePipeline(spec pipeline.Spec) (*pipeline.Pipeline, error) { + ret := _m.Called(spec) + + if len(ret) == 0 { + panic("no return value specified for InitializePipeline") + } + + var r0 *pipeline.Pipeline + var r1 error + if rf, ok := ret.Get(0).(func(pipeline.Spec) (*pipeline.Pipeline, error)); ok { + return rf(spec) + } + if rf, ok := ret.Get(0).(func(pipeline.Spec) *pipeline.Pipeline); ok { + r0 = rf(spec) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*pipeline.Pipeline) + } + } + + if rf, ok := ret.Get(1).(func(pipeline.Spec) error); ok { + r1 = rf(spec) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // InsertFinishedRun provides a mock function with given fields: run, saveSuccessfulTaskRuns, qopts func (_m *Runner) InsertFinishedRun(run *pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error { _va := make([]interface{}, len(qopts)) diff --git a/core/services/pipeline/runner.go b/core/services/pipeline/runner.go index 30a35598c3e..cc6214abf5a 100644 --- a/core/services/pipeline/runner.go +++ b/core/services/pipeline/runner.go @@ -51,6 +51,7 @@ type Runner interface { ExecuteAndInsertFinishedRun(ctx context.Context, spec Spec, vars Vars, l logger.Logger, saveSuccessfulTaskRuns bool) (runID int64, finalResult FinalResult, err error) OnRunFinished(func(*Run)) + InitializePipeline(spec Spec) (*Pipeline, error) } type runner struct { diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 4de4e48bd90..dcccbb90c79 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -28,6 +28,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + "github.com/smartcontractkit/chainlink/v2/core/services/llo" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/bm" + 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/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pg" @@ -44,6 +47,7 @@ import ( var ( OCR2AggregatorTransmissionContractABI abi.ABI OCR2AggregatorLogDecoder LogDecoder + ChannelVerifierLogDecoder LogDecoder ) func init() { @@ -56,6 +60,10 @@ func init() { if err != nil { panic(err) } + ChannelVerifierLogDecoder, err = newChannelVerifierLogDecoder() + if err != nil { + panic(err) + } } var _ commontypes.Relayer = &Relayer{} //nolint:staticcheck @@ -69,6 +77,10 @@ type Relayer struct { pgCfg pg.QConfig chainReader commontypes.ChainReader codec commontypes.Codec + + // LLO/data streams + cdcFactory llo.ChannelDefinitionCacheFactory + orm llo.ORM } type CSAETHKeystore interface { @@ -107,6 +119,9 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R return nil, fmt.Errorf("cannot create evm relayer: %w", err) } lggr = lggr.Named("Relayer") + + orm := llo.NewORM(pg.NewQ(opts.DB, lggr, opts.QConfig), chain.ID()) + cdcFactory := llo.NewChannelDefinitionCacheFactory(lggr, orm, chain.LogPoller()) return &Relayer{ db: opts.DB, chain: chain, @@ -114,6 +129,8 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R ks: opts.CSAETHKeystore, mercuryPool: opts.MercuryPool, pgCfg: opts.QConfig, + cdcFactory: cdcFactory, + orm: orm, }, nil } @@ -226,7 +243,60 @@ func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commonty } func (r *Relayer) NewLLOProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.LLOProvider, error) { - return nil, errors.New("not implemented") + relayOpts := types.NewRelayOpts(rargs) + var relayConfig types.RelayConfig + { + var err error + relayConfig, err = relayOpts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + } + + var lloCfg lloconfig.PluginConfig + if err := json.Unmarshal(pargs.PluginConfig, &lloCfg); err != nil { + return nil, pkgerrors.WithStack(err) + } + if err := lloCfg.Validate(); err != nil { + return nil, err + } + + if relayConfig.ChainID.String() != r.chain.ID().String() { + return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), r.chain.ID().String()) + } + cp, err := newLLOConfigProvider(r.lggr, r.chain, relayOpts) + if err != nil { + return nil, pkgerrors.WithStack(err) + } + + if !relayConfig.EffectiveTransmitterID.Valid { + return nil, pkgerrors.New("EffectiveTransmitterID must be specified") + } + privKey, err := r.ks.CSA().Get(relayConfig.EffectiveTransmitterID.String) + if err != nil { + return nil, pkgerrors.Wrap(err, "failed to get CSA key for mercury connection") + } + + // FIXME: Remove after benchmarking is done + // https://smartcontract-it.atlassian.net/browse/MERC-3487 + var transmitter llo.Transmitter + if lloCfg.BenchmarkMode { + r.lggr.Info("Benchmark mode enabled, using dummy transmitter. NOTE: THIS WILL NOT TRANSMIT ANYTHING") + transmitter = bm.NewTransmitter(r.lggr, privKey.PublicKey) + } else { + var client wsrpc.Client + client, err = r.mercuryPool.Checkout(context.Background(), privKey, lloCfg.ServerPubKey, lloCfg.ServerURL()) + if err != nil { + return nil, err + } + transmitter = llo.NewTransmitter(r.lggr, client, privKey.PublicKey) + } + + cdc, err := r.cdcFactory.NewCache(lloCfg) + if err != nil { + return nil, err + } + return NewLLOProvider(cp, transmitter, r.lggr, cdc), nil } func (r *Relayer) NewFunctionsProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.FunctionsProvider, error) { @@ -263,9 +333,12 @@ func (r *Relayer) NewConfigProvider(args commontypes.RelayArgs) (configProvider configProvider, err = newStandardConfigProvider(lggr, r.chain, relayOpts) case "mercury": configProvider, err = newMercuryConfigProvider(lggr, r.chain, relayOpts) + case "llo": + configProvider, err = newLLOConfigProvider(lggr, r.chain, relayOpts) default: return nil, fmt.Errorf("unrecognized provider type: %q", args.ProviderType) } + if err != nil { // Never return (*configProvider)(nil) return nil, err @@ -471,6 +544,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp } reportCodec := evmreportcodec.ReportCodec{} + contractTransmitter, err := newOnChainContractTransmitter(lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) if err != nil { return nil, err diff --git a/core/services/relay/evm/llo_config_provider.go b/core/services/relay/evm/llo_config_provider.go new file mode 100644 index 00000000000..bd8dbac8460 --- /dev/null +++ b/core/services/relay/evm/llo_config_provider.go @@ -0,0 +1,21 @@ +package evm + +import ( + "github.com/ethereum/go-ethereum/common" + pkgerrors "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/llo" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +func newLLOConfigProvider(lggr logger.Logger, chain legacyevm.Chain, opts *types.RelayOpts) (*configWatcher, error) { + if !common.IsHexAddress(opts.ContractID) { + return nil, pkgerrors.Errorf("invalid contractID, expected hex address") + } + + aggregatorAddress := common.HexToAddress(opts.ContractID) + configDigester := llo.NewOffchainConfigDigester(chain.Config().EVM().ChainID(), aggregatorAddress) + return newContractConfigProvider(lggr, chain, opts, aggregatorAddress, ChannelVerifierLogDecoder, configDigester) +} diff --git a/core/services/relay/evm/llo_provider.go b/core/services/relay/evm/llo_provider.go new file mode 100644 index 00000000000..0ab0773a160 --- /dev/null +++ b/core/services/relay/evm/llo_provider.go @@ -0,0 +1,90 @@ +package evm + +import ( + "context" + "errors" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + relaytypes "github.com/smartcontractkit/chainlink-common/pkg/types" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + datastreamsllo "github.com/smartcontractkit/chainlink-data-streams/llo" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/llo" +) + +var _ commontypes.LLOProvider = (*lloProvider)(nil) + +type lloProvider struct { + cp commontypes.ConfigProvider + transmitter llo.Transmitter + logger logger.Logger + channelDefinitionCache llotypes.ChannelDefinitionCache + + ms services.MultiStart +} + +func NewLLOProvider( + cp commontypes.ConfigProvider, + transmitter llo.Transmitter, + lggr logger.Logger, + channelDefinitionCache llotypes.ChannelDefinitionCache, +) relaytypes.LLOProvider { + return &lloProvider{ + cp, + transmitter, + lggr.Named("LLOProvider"), + channelDefinitionCache, + services.MultiStart{}, + } +} + +func (p *lloProvider) Start(ctx context.Context) error { + err := p.ms.Start(ctx, p.cp, p.transmitter, p.channelDefinitionCache) + return err +} + +func (p *lloProvider) Close() error { + return p.ms.Close() +} + +func (p *lloProvider) Ready() error { + return errors.Join(p.cp.Ready(), p.transmitter.Ready(), p.channelDefinitionCache.Ready()) +} + +func (p *lloProvider) Name() string { + return p.logger.Name() +} + +func (p *lloProvider) HealthReport() map[string]error { + report := map[string]error{} + services.CopyHealth(report, p.cp.HealthReport()) + services.CopyHealth(report, p.transmitter.HealthReport()) + services.CopyHealth(report, p.channelDefinitionCache.HealthReport()) + return report +} + +func (p *lloProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { + return p.cp.ContractConfigTracker() +} + +func (p *lloProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { + return p.cp.OffchainConfigDigester() +} + +func (p *lloProvider) OnchainConfigCodec() datastreamsllo.OnchainConfigCodec { + // TODO: This should probably be moved to core since its chain-specific + // https://smartcontract-it.atlassian.net/browse/MERC-3661 + return &datastreamsllo.JSONOnchainConfigCodec{} +} + +func (p *lloProvider) ContractTransmitter() llotypes.Transmitter { + return p.transmitter +} + +func (p *lloProvider) ChannelDefinitionCache() llotypes.ChannelDefinitionCache { + return p.channelDefinitionCache +} diff --git a/core/services/relay/evm/llo_verifier_decoder.go b/core/services/relay/evm/llo_verifier_decoder.go new file mode 100644 index 00000000000..922b83bec0d --- /dev/null +++ b/core/services/relay/evm/llo_verifier_decoder.go @@ -0,0 +1,67 @@ +package evm + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_verifier" +) + +var _ LogDecoder = &channelVerifierLogDecoder{} + +type channelVerifierLogDecoder struct { + eventName string + eventSig common.Hash + abi *abi.ABI +} + +func newChannelVerifierLogDecoder() (*channelVerifierLogDecoder, error) { + const eventName = "ConfigSet" + abi, err := channel_verifier.ChannelVerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return &channelVerifierLogDecoder{ + eventName: eventName, + eventSig: abi.Events[eventName].ID, + abi: abi, + }, nil +} + +func (d *channelVerifierLogDecoder) Decode(rawLog []byte) (ocrtypes.ContractConfig, error) { + unpacked := new(channel_verifier.ChannelVerifierConfigSet) + err := d.abi.UnpackIntoInterface(unpacked, d.eventName, rawLog) + if err != nil { + return ocrtypes.ContractConfig{}, errors.Wrap(err, "failed to unpack log data") + } + + var transmitAccounts []ocrtypes.Account + for _, addr := range unpacked.OffchainTransmitters { + transmitAccounts = append(transmitAccounts, ocrtypes.Account(fmt.Sprintf("%x", addr))) + } + var signers []ocrtypes.OnchainPublicKey + for _, addr := range unpacked.Signers { + addr := addr + signers = append(signers, addr[:]) + } + + return ocrtypes.ContractConfig{ + ConfigDigest: unpacked.ConfigDigest, + ConfigCount: unpacked.ConfigCount, + Signers: signers, + Transmitters: transmitAccounts, + F: unpacked.F, + OnchainConfig: unpacked.OnchainConfig, + OffchainConfigVersion: unpacked.OffchainConfigVersion, + OffchainConfig: unpacked.OffchainConfig, + }, nil +} + +func (d *channelVerifierLogDecoder) EventSig() common.Hash { + return d.eventSig +} diff --git a/core/services/relay/evm/mercury/config_digest.go b/core/services/relay/evm/mercury/config_digest.go index b9431fe923f..291a723ee3a 100644 --- a/core/services/relay/evm/mercury/config_digest.go +++ b/core/services/relay/evm/mercury/config_digest.go @@ -61,7 +61,7 @@ func configDigest( panic("copy too little data") } binary.BigEndian.PutUint16(configDigest[:2], uint16(types.ConfigDigestPrefixMercuryV02)) - if !(configDigest[0] == 0 || configDigest[1] == 6) { + if !(configDigest[0] == 0 && configDigest[1] == 6) { // assertion panic("unexpected mismatch") } diff --git a/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go b/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go index ce4125bd579..ab4d2f68dad 100644 --- a/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go +++ b/core/services/relay/evm/mercury/wsrpc/pb/mercury.pb.go @@ -26,7 +26,7 @@ type TransmitRequest struct { unknownFields protoimpl.UnknownFields Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` - ReportFormat string `protobuf:"bytes,2,opt,name=reportFormat,proto3" json:"reportFormat,omitempty"` + ReportFormat uint32 `protobuf:"varint,2,opt,name=reportFormat,proto3" json:"reportFormat,omitempty"` } func (x *TransmitRequest) Reset() { @@ -68,11 +68,11 @@ func (x *TransmitRequest) GetPayload() []byte { return nil } -func (x *TransmitRequest) GetReportFormat() string { +func (x *TransmitRequest) GetReportFormat() uint32 { if x != nil { return x.ReportFormat } - return "" + return 0 } type TransmitResponse struct { @@ -454,7 +454,7 @@ var file_mercury_proto_rawDesc = []byte{ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3c, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, diff --git a/core/services/relay/evm/mercury/wsrpc/pb/mercury.proto b/core/services/relay/evm/mercury/wsrpc/pb/mercury.proto index 184b0572046..6b71404a6a6 100644 --- a/core/services/relay/evm/mercury/wsrpc/pb/mercury.proto +++ b/core/services/relay/evm/mercury/wsrpc/pb/mercury.proto @@ -11,7 +11,7 @@ service Mercury { message TransmitRequest { bytes payload = 1; - string reportFormat = 2; + uint32 reportFormat = 2; } message TransmitResponse { diff --git a/core/store/migrate/migrations/0224_create_channel_definition_caches.sql b/core/store/migrate/migrations/0224_create_channel_definition_caches.sql new file mode 100644 index 00000000000..9c46f1ceacf --- /dev/null +++ b/core/store/migrate/migrations/0224_create_channel_definition_caches.sql @@ -0,0 +1,12 @@ +-- +goose Up +CREATE TABLE channel_definitions ( + evm_chain_id NUMERIC(78) NOT NULL, + addr bytea CHECK (octet_length(addr) = 20), + definitions JSONB NOT NULL, + block_num BIGINT NOT NULL, + updated_at timestamp with time zone NOT NULL, + PRIMARY KEY (evm_chain_id, addr) +); + +-- +goose Down +DROP TABLE channel_definitions; diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8fff0e36cad..6647dcc1efd 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Gas bumping logic to the `SuggestedPriceEstimator`. The bumping mechanism for this estimator refetches the price from the RPC and adds a buffer on top using the greater of `BumpPercent` and `BumpMin`. +- Add preliminary support for "llo" job type (Data Streams V1) ### Fixed diff --git a/go.mod b/go.mod index c0ef2b819de..2291388def2 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 @@ -82,6 +82,7 @@ require ( github.com/smartcontractkit/wsrpc v0.7.2 github.com/spf13/cast v1.6.0 github.com/stretchr/testify v1.8.4 + github.com/test-go/testify v1.1.4 github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a github.com/tidwall/gjson v1.17.0 github.com/ugorji/go/codec v1.2.12 @@ -342,4 +343,5 @@ replace ( // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f + ) diff --git a/go.sum b/go.sum index 88ea058b06e..13d684fd34d 100644 --- a/go.sum +++ b/go.sum @@ -1172,8 +1172,8 @@ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ae2ac344c9b..955c0bbb1e5 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -370,7 +370,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index fe81cc3ac68..e5f34a3d982 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1511,8 +1511,8 @@ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 174ea743c23..de4360ea4e4 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -357,7 +357,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 1aaac86bd00..f85521c2f7f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1494,8 +1494,8 @@ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240221153538-1ea85cf3dc6c/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336 h1:j00D0/EqE9HRu+63v7KwUOe4ZxLc4AN5SOJFiinkkH0= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240214203158-47dae5de1336/go.mod h1:umLyYLRGqyIuFfGpEREZP3So6+O8iL35cCCqW+OxX5w= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 h1:1BcjXuviSAKttOX7BZoVHRZZGfxqoA2+AL8tykmkdoc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8/go.mod h1:vy1L7NybTy2F/Yv7BOh+oZBa1MACD6gzd1+DkcSkfp8= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= From 0b9dc18fc7e6a223758af0703dfc82d50a99e940 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 22 Feb 2024 12:55:25 -0500 Subject: [PATCH 77/98] Ignore .venv (#12145) --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ae69535d352..e56774fbefc 100644 --- a/.gitignore +++ b/.gitignore @@ -91,4 +91,7 @@ tools/flakeytests/coverage.txt **/testdata/fuzz/* # Runtime test configuration that might contain secrets -overrides.toml \ No newline at end of file +overrides.toml + +# Pythin venv +.venv/ From 85cc5909de2427f9eb61a2dae27713e0ff585263 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Thu, 22 Feb 2024 19:23:17 +0100 Subject: [PATCH 78/98] [FUN-877] make persisting allowlist compatible with older contract (#11907) * feat: make persisting allowlist compatible with older contract * feat: check tos contract version instead of a config feature flag * extract contract version comparison to helper function * fix: use semver to compare versions --- .../handlers/functions/allowlist/allowlist.go | 58 ++- .../functions/allowlist/allowlist_test.go | 390 ++++++++++++++---- .../handlers/functions/allowlist/mocks/orm.go | 24 ++ .../handlers/functions/allowlist/orm.go | 24 ++ .../handlers/functions/allowlist/orm_test.go | 65 +++ go.mod | 2 +- 6 files changed, 467 insertions(+), 96 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go index 20dc92ced70..020de2359c2 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "fmt" "math/big" + "regexp" "sync" "sync/atomic" "time" @@ -12,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + "golang.org/x/mod/semver" "github.com/smartcontractkit/chainlink-common/pkg/services" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -23,9 +25,10 @@ import ( ) const ( - defaultStoredAllowlistBatchSize = 1000 - defaultOnchainAllowlistBatchSize = 100 - defaultFetchingDelayInRangeSec = 1 + defaultStoredAllowlistBatchSize = 1000 + defaultOnchainAllowlistBatchSize = 100 + defaultFetchingDelayInRangeSec = 1 + tosContractMinBatchProcessingVersion = "v1.1.0" ) type OnchainAllowlistConfig struct { @@ -38,8 +41,6 @@ type OnchainAllowlistConfig struct { UpdateTimeoutSec uint `json:"updateTimeoutSec"` StoredAllowlistBatchSize uint `json:"storedAllowlistBatchSize"` OnchainAllowlistBatchSize uint `json:"onchainAllowlistBatchSize"` - // StoreAllowedSendersEnabled is a feature flag that enables storing in db a copy of the allowlist. - StoreAllowedSendersEnabled bool `json:"storeAllowedSendersEnabled"` // FetchingDelayInRangeSec prevents RPC client being rate limited when fetching the allowlist in ranges. FetchingDelayInRangeSec uint `json:"fetchingDelayInRangeSec"` } @@ -210,7 +211,31 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } var allowedSenderList []common.Address - if !a.config.StoreAllowedSendersEnabled { + typeAndVersion, err := tosContract.TypeAndVersion(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }) + if err != nil { + return errors.Wrap(err, "failed to fetch the tos contract type and version") + } + + currentVersion, err := ExtractContractVersion(typeAndVersion) + if err != nil { + return fmt.Errorf("failed to extract version: %w", err) + } + + if semver.Compare(tosContractMinBatchProcessingVersion, currentVersion) <= 0 { + err = a.syncBlockedSenders(ctx, tosContract, blockNum) + if err != nil { + return errors.Wrap(err, "failed to sync the stored allowed and blocked senders") + } + + allowedSenderList, err = a.getAllowedSendersBatched(ctx, tosContract, blockNum) + if err != nil { + return errors.Wrap(err, "failed to get allowed senders in rage") + } + } else { allowedSenderList, err = tosContract.GetAllAllowedSenders(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, @@ -219,15 +244,15 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b if err != nil { return errors.Wrap(err, "error calling GetAllAllowedSenders") } - } else { - err = a.syncBlockedSenders(ctx, tosContract, blockNum) + + err = a.orm.PurgeAllowedSenders() if err != nil { - return errors.Wrap(err, "failed to sync the stored allowed and blocked senders") + a.lggr.Errorf("failed to purge allowedSenderList: %w", err) } - allowedSenderList, err = a.getAllowedSendersBatched(ctx, tosContract, blockNum) + err = a.orm.CreateAllowedSenders(allowedSenderList) if err != nil { - return errors.Wrap(err, "failed to get allowed senders in rage") + a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) } } @@ -344,3 +369,14 @@ func (a *onchainAllowlist) loadStoredAllowedSenderList() { a.update(allowedList) } + +func ExtractContractVersion(str string) (string, error) { + pattern := `v(\d+).(\d+).(\d+)` + re := regexp.MustCompile(pattern) + + match := re.FindStringSubmatch(str) + if len(match) != 4 { + return "", fmt.Errorf("version not found in string: %s", str) + } + return fmt.Sprintf("v%s.%s.%s", match[1], match[2], match[3]), nil +} diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go index e8cbca80b94..735c0bff7dc 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go @@ -3,11 +3,14 @@ package allowlist_test import ( "context" "encoding/hex" + "fmt" "math/big" "testing" "time" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/onsi/gomega" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -18,55 +21,105 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" amocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) const ( - addr1 = "9ed925d8206a4f88a2f643b28b3035b315753cd6" - addr2 = "ea6721ac65bced841b8ec3fc5fedea6141a0ade4" - addr3 = "84689acc87ff22841b8ec378300da5e141a99911" + addr1 = "9ed925d8206a4f88a2f643b28b3035b315753cd6" + addr2 = "ea6721ac65bced841b8ec3fc5fedea6141a0ade4" + addr3 = "84689acc87ff22841b8ec378300da5e141a99911" + ToSContractV100 = "Functions Terms of Service Allow List v1.0.0" + ToSContractV110 = "Functions Terms of Service Allow List v1.1.0" ) -func sampleEncodedAllowlist(t *testing.T) []byte { - abiEncodedAddresses := - "0000000000000000000000000000000000000000000000000000000000000020" + - "0000000000000000000000000000000000000000000000000000000000000002" + - "000000000000000000000000" + addr1 + - "000000000000000000000000" + addr2 - rawData, err := hex.DecodeString(abiEncodedAddresses) - require.NoError(t, err) - return rawData -} - -func TestAllowlist_UpdateAndCheck(t *testing.T) { +func TestUpdateAndCheck(t *testing.T) { t.Parallel() - client := mocks.NewClient(t) - client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) - client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(sampleEncodedAllowlist(t), nil) - config := allowlist.OnchainAllowlistConfig{ - ContractVersion: 1, - ContractAddress: common.Address{}, - BlockConfirmations: 1, - } + t.Run("OK-with_ToS_V1.0.0", func(t *testing.T) { + client := mocks.NewClient(t) + client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) - orm := amocks.NewORM(t) - allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) - require.NoError(t, err) + addr := common.HexToAddress("0x0000000000000000000000000000000000000020") + typeAndVersionResponse, err := encodeTypeAndVersionResponse(ToSContractV100) + require.NoError(t, err) - err = allowlist.Start(testutils.Context(t)) - require.NoError(t, err) - t.Cleanup(func() { - assert.NoError(t, allowlist.Close()) + client.On("CallContract", mock.Anything, ethereum.CallMsg{ // typeAndVersion + To: &addr, + Data: hexutil.MustDecode("0x181f5a77"), + }, mock.Anything).Return(typeAndVersionResponse, nil) + + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(sampleEncodedAllowlist(t), nil) + + config := allowlist.OnchainAllowlistConfig{ + ContractVersion: 1, + ContractAddress: common.Address{}, + BlockConfirmations: 1, + } + + orm := amocks.NewORM(t) + orm.On("PurgeAllowedSenders").Times(1).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) + + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + require.NoError(t, err) + + err = allowlist.Start(testutils.Context(t)) + require.NoError(t, err) + t.Cleanup(func() { + assert.NoError(t, allowlist.Close()) + }) + + require.NoError(t, allowlist.UpdateFromContract(testutils.Context(t))) + require.False(t, allowlist.Allow(common.Address{})) + require.True(t, allowlist.Allow(common.HexToAddress(addr1))) + require.True(t, allowlist.Allow(common.HexToAddress(addr2))) + require.False(t, allowlist.Allow(common.HexToAddress(addr3))) }) - require.NoError(t, allowlist.UpdateFromContract(testutils.Context(t))) - require.False(t, allowlist.Allow(common.Address{})) - require.True(t, allowlist.Allow(common.HexToAddress(addr1))) - require.True(t, allowlist.Allow(common.HexToAddress(addr2))) - require.False(t, allowlist.Allow(common.HexToAddress(addr3))) + t.Run("OK-with_ToS_V1.1.0", func(t *testing.T) { + client := mocks.NewClient(t) + client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) + + typeAndVersionResponse, err := encodeTypeAndVersionResponse(ToSContractV110) + require.NoError(t, err) + + addr := common.HexToAddress("0x0000000000000000000000000000000000000020") + client.On("CallContract", mock.Anything, ethereum.CallMsg{ // typeAndVersion + To: &addr, + Data: hexutil.MustDecode("0x181f5a77"), + }, mock.Anything).Return(typeAndVersionResponse, nil) + + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(sampleEncodedAllowlist(t), nil) + + config := allowlist.OnchainAllowlistConfig{ + ContractVersion: 1, + ContractAddress: common.Address{}, + BlockConfirmations: 1, + } + + orm := amocks.NewORM(t) + orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) + + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + require.NoError(t, err) + + err = allowlist.Start(testutils.Context(t)) + require.NoError(t, err) + t.Cleanup(func() { + assert.NoError(t, allowlist.Close()) + }) + + require.NoError(t, allowlist.UpdateFromContract(testutils.Context(t))) + require.False(t, allowlist.Allow(common.Address{})) + require.True(t, allowlist.Allow(common.HexToAddress(addr1))) + require.True(t, allowlist.Allow(common.HexToAddress(addr2))) + require.False(t, allowlist.Allow(common.HexToAddress(addr3))) + }) } -func TestAllowlist_UnsupportedVersion(t *testing.T) { +func TestUnsupportedVersion(t *testing.T) { t.Parallel() client := mocks.NewClient(t) @@ -81,64 +134,132 @@ func TestAllowlist_UnsupportedVersion(t *testing.T) { require.Error(t, err) } -func TestAllowlist_UpdatePeriodically(t *testing.T) { +func TestUpdatePeriodically(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(testutils.Context(t)) - client := mocks.NewClient(t) - client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) - client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - cancel() - }).Return(sampleEncodedAllowlist(t), nil) - config := allowlist.OnchainAllowlistConfig{ - ContractAddress: common.Address{}, - ContractVersion: 1, - BlockConfirmations: 1, - UpdateFrequencySec: 2, - UpdateTimeoutSec: 1, - } + t.Run("OK-with_ToS_V1.0.0", func(t *testing.T) { + ctx, cancel := context.WithCancel(testutils.Context(t)) + client := mocks.NewClient(t) + client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) - orm := amocks.NewORM(t) - orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil) + addr := common.HexToAddress("0x0000000000000000000000000000000000000020") + typeAndVersionResponse, err := encodeTypeAndVersionResponse(ToSContractV100) + require.NoError(t, err) - allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) - require.NoError(t, err) + client.On("CallContract", mock.Anything, ethereum.CallMsg{ // typeAndVersion + To: &addr, + Data: hexutil.MustDecode("0x181f5a77"), + }, mock.Anything).Return(typeAndVersionResponse, nil) - err = allowlist.Start(ctx) - require.NoError(t, err) - t.Cleanup(func() { - assert.NoError(t, allowlist.Close()) + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + cancel() + }).Return(sampleEncodedAllowlist(t), nil) + config := allowlist.OnchainAllowlistConfig{ + ContractAddress: common.Address{}, + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 2, + UpdateTimeoutSec: 1, + } + + orm := amocks.NewORM(t) + orm.On("PurgeAllowedSenders").Times(1).Return(nil) + orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) + + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + require.NoError(t, err) + + err = allowlist.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { + assert.NoError(t, allowlist.Close()) + }) + + gomega.NewGomegaWithT(t).Eventually(func() bool { + return allowlist.Allow(common.HexToAddress(addr1)) && !allowlist.Allow(common.HexToAddress(addr3)) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) }) - gomega.NewGomegaWithT(t).Eventually(func() bool { - return allowlist.Allow(common.HexToAddress(addr1)) && !allowlist.Allow(common.HexToAddress(addr3)) - }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) + t.Run("OK-with_ToS_V1.1.0", func(t *testing.T) { + ctx, cancel := context.WithCancel(testutils.Context(t)) + client := mocks.NewClient(t) + client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) + + addr := common.HexToAddress("0x0000000000000000000000000000000000000020") + typeAndVersionResponse, err := encodeTypeAndVersionResponse(ToSContractV110) + require.NoError(t, err) + + client.On("CallContract", mock.Anything, ethereum.CallMsg{ // typeAndVersion + To: &addr, + Data: hexutil.MustDecode("0x181f5a77"), + }, mock.Anything).Return(typeAndVersionResponse, nil) + + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + cancel() + }).Return(sampleEncodedAllowlist(t), nil) + config := allowlist.OnchainAllowlistConfig{ + ContractAddress: common.Address{}, + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 2, + UpdateTimeoutSec: 1, + } + + orm := amocks.NewORM(t) + orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) + orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) + + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + require.NoError(t, err) + + err = allowlist.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { + assert.NoError(t, allowlist.Close()) + }) + + gomega.NewGomegaWithT(t).Eventually(func() bool { + return allowlist.Allow(common.HexToAddress(addr1)) && !allowlist.Allow(common.HexToAddress(addr3)) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) + }) } -func TestAllowlist_UpdateFromContract(t *testing.T) { + +func TestUpdateFromContract(t *testing.T) { t.Parallel() - t.Run("OK-iterate_over_list_of_allowed_senders", func(t *testing.T) { + t.Run("OK-fetch_complete_list_of_allowed_senders", func(t *testing.T) { ctx, cancel := context.WithCancel(testutils.Context(t)) client := mocks.NewClient(t) client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) + + addr := common.HexToAddress("0x0000000000000000000000000000000000000020") + typeAndVersionResponse, err := encodeTypeAndVersionResponse(ToSContractV100) + require.NoError(t, err) + + client.On("CallContract", mock.Anything, ethereum.CallMsg{ // typeAndVersion + To: &addr, + Data: hexutil.MustDecode("0x181f5a77"), + }, mock.Anything).Return(typeAndVersionResponse, nil) + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { cancel() }).Return(sampleEncodedAllowlist(t), nil) config := allowlist.OnchainAllowlistConfig{ - ContractAddress: common.HexToAddress(addr3), - ContractVersion: 1, - BlockConfirmations: 1, - UpdateFrequencySec: 2, - UpdateTimeoutSec: 1, - StoredAllowlistBatchSize: 2, - OnchainAllowlistBatchSize: 16, - StoreAllowedSendersEnabled: true, - FetchingDelayInRangeSec: 0, + ContractAddress: common.HexToAddress(addr3), + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 2, + UpdateTimeoutSec: 1, + StoredAllowlistBatchSize: 2, + OnchainAllowlistBatchSize: 16, + FetchingDelayInRangeSec: 0, } orm := amocks.NewORM(t) - orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil) - orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil) + orm.On("PurgeAllowedSenders").Times(1).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -151,26 +272,38 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) }) - t.Run("OK-fetch_complete_list_of_allowed_senders_without_storing", func(t *testing.T) { + t.Run("OK-iterate_over_list_of_allowed_senders", func(t *testing.T) { ctx, cancel := context.WithCancel(testutils.Context(t)) client := mocks.NewClient(t) client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) + + addr := common.HexToAddress("0x0000000000000000000000000000000000000020") + typeAndVersionResponse, err := encodeTypeAndVersionResponse(ToSContractV110) + require.NoError(t, err) + + client.On("CallContract", mock.Anything, ethereum.CallMsg{ // typeAndVersion + To: &addr, + Data: hexutil.MustDecode("0x181f5a77"), + }, mock.Anything).Return(typeAndVersionResponse, nil) + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { cancel() }).Return(sampleEncodedAllowlist(t), nil) config := allowlist.OnchainAllowlistConfig{ - ContractAddress: common.HexToAddress(addr3), - ContractVersion: 1, - BlockConfirmations: 1, - UpdateFrequencySec: 2, - UpdateTimeoutSec: 1, - StoredAllowlistBatchSize: 2, - OnchainAllowlistBatchSize: 16, - StoreAllowedSendersEnabled: false, - FetchingDelayInRangeSec: 0, + ContractAddress: common.HexToAddress(addr3), + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 2, + UpdateTimeoutSec: 1, + StoredAllowlistBatchSize: 2, + OnchainAllowlistBatchSize: 16, + FetchingDelayInRangeSec: 0, } orm := amocks.NewORM(t) + orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil) + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -181,4 +314,93 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { return allowlist.Allow(common.HexToAddress(addr1)) && !allowlist.Allow(common.HexToAddress(addr3)) }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) }) + +} + +func TestExtractContractVersion(t *testing.T) { + + type tc struct { + name string + versionStr string + expectedResult string + expectedError *string + } + + var errInvalidVersion = func(v string) *string { + ev := fmt.Sprintf("version not found in string: %s", v) + return &ev + } + + tcs := []tc{ + { + name: "OK-Tos_type_and_version", + versionStr: "Functions Terms of Service Allow List v1.1.0", + expectedResult: "v1.1.0", + expectedError: nil, + }, + { + name: "OK-double_digits_minor", + versionStr: "Functions Terms of Service Allow List v1.20.0", + expectedResult: "v1.20.0", + expectedError: nil, + }, + { + name: "NOK-invalid_version", + versionStr: "invalid_version", + expectedResult: "", + expectedError: errInvalidVersion("invalid_version"), + }, + { + name: "NOK-incomplete_version", + versionStr: "v2.0", + expectedResult: "", + expectedError: errInvalidVersion("v2.0"), + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + actualResult, actualError := allowlist.ExtractContractVersion(tc.versionStr) + require.Equal(t, tc.expectedResult, actualResult) + + if tc.expectedError != nil { + require.EqualError(t, actualError, *tc.expectedError) + } else { + require.NoError(t, actualError) + } + }) + } +} + +func encodeTypeAndVersionResponse(typeAndVersion string) ([]byte, error) { + codecName := "my_codec" + evmEncoderConfig := `[{"Name":"typeAndVersion","Type":"string"}]` + codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ + codecName: {TypeABI: evmEncoderConfig}, + }} + encoder, err := evm.NewCodec(codecConfig) + if err != nil { + return nil, err + } + + input := map[string]any{ + "typeAndVersion": typeAndVersion, + } + typeAndVersionResponse, err := encoder.Encode(context.Background(), input, codecName) + if err != nil { + return nil, err + } + + return typeAndVersionResponse, nil +} + +func sampleEncodedAllowlist(t *testing.T) []byte { + abiEncodedAddresses := + "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "000000000000000000000000" + addr1 + + "000000000000000000000000" + addr2 + rawData, err := hex.DecodeString(abiEncodedAddresses) + require.NoError(t, err) + return rawData } diff --git a/core/services/gateway/handlers/functions/allowlist/mocks/orm.go b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go index c2ba27c3a24..daff33d8902 100644 --- a/core/services/gateway/handlers/functions/allowlist/mocks/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go @@ -101,6 +101,30 @@ func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]c return r0, r1 } +// PurgeAllowedSenders provides a mock function with given fields: qopts +func (_m *ORM) PurgeAllowedSenders(qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for PurgeAllowedSenders") + } + + var r0 error + if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok { + r0 = rf(qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // NewORM creates a new instance of ORM. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewORM(t interface { diff --git a/core/services/gateway/handlers/functions/allowlist/orm.go b/core/services/gateway/handlers/functions/allowlist/orm.go index 07ee1ea3b3b..ccacec81a43 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/orm.go @@ -18,6 +18,7 @@ type ORM interface { GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error + PurgeAllowedSenders(qopts ...pg.QOpt) error } type orm struct { @@ -91,6 +92,8 @@ func (o *orm) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg. return nil } +// DeleteAllowedSenders is used to remove blocked senders from the functions_allowlist table. +// This is achieved by specifying a list of blockedSenders to remove. func (o *orm) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error { var valuesPlaceholder []string for i := 1; i <= len(blockedSenders); i++ { @@ -121,3 +124,24 @@ func (o *orm) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg. return nil } + +// PurgeAllowedSenders will remove all the allowed senders for the configured orm routerContractAddress +func (o *orm) PurgeAllowedSenders(qopts ...pg.QOpt) error { + stmt := fmt.Sprintf(` + DELETE FROM %s + WHERE router_contract_address = $1;`, tableName) + + res, err := o.q.WithOpts(qopts...).Exec(stmt, o.routerContractAddress) + if err != nil { + return err + } + + rowsAffected, err := res.RowsAffected() + if err != nil { + return err + } + + o.lggr.Debugf("Successfully purged allowed senders for routerContractAddress: %s. rowsAffected: %d", o.routerContractAddress, rowsAffected) + + return nil +} diff --git a/core/services/gateway/handlers/functions/allowlist/orm_test.go b/core/services/gateway/handlers/functions/allowlist/orm_test.go index 0f63e83cd5f..1d357616fab 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm_test.go +++ b/core/services/gateway/handlers/functions/allowlist/orm_test.go @@ -174,6 +174,71 @@ func TestORM_DeleteAllowedSenders(t *testing.T) { }) } +func TestORM_PurgeAllowedSenders(t *testing.T) { + t.Parallel() + + t.Run("OK-purge_allowed_list", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + add1 := testutils.NewAddress() + add2 := testutils.NewAddress() + add3 := testutils.NewAddress() + err = orm.CreateAllowedSenders([]common.Address{add1, add2, add3}) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 3, len(results), "incorrect results length") + require.Equal(t, add1, results[0]) + + err = orm.PurgeAllowedSenders() + require.NoError(t, err) + + results, err = orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 0, len(results), "incorrect results length") + }) + + t.Run("OK-purge_allowed_list_for_contract_address", func(t *testing.T) { + orm1, err := setupORM(t) + require.NoError(t, err) + add1 := testutils.NewAddress() + add2 := testutils.NewAddress() + err = orm1.CreateAllowedSenders([]common.Address{add1, add2}) + require.NoError(t, err) + + results, err := orm1.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, add1, results[0]) + + orm2, err := setupORM(t) + require.NoError(t, err) + add3 := testutils.NewAddress() + add4 := testutils.NewAddress() + err = orm2.CreateAllowedSenders([]common.Address{add3, add4}) + require.NoError(t, err) + + results, err = orm2.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, add3, results[0]) + + err = orm2.PurgeAllowedSenders() + require.NoError(t, err) + + results, err = orm2.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 0, len(results), "incorrect results length") + + results, err = orm1.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, add1, results[0]) + require.Equal(t, add2, results[1]) + }) +} + func Test_NewORM(t *testing.T) { t.Run("OK-create_ORM", func(t *testing.T) { _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress()) diff --git a/go.mod b/go.mod index 2291388def2..1e0c09b06bf 100644 --- a/go.mod +++ b/go.mod @@ -98,6 +98,7 @@ require ( go.uber.org/zap v1.26.0 golang.org/x/crypto v0.19.0 golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/mod v0.15.0 golang.org/x/sync v0.6.0 golang.org/x/term v0.17.0 golang.org/x/text v0.14.0 @@ -316,7 +317,6 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/mod v0.15.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect golang.org/x/sys v0.17.0 // indirect From 63c286d81d9c5032a334c629616e6fab0ca6597a Mon Sep 17 00:00:00 2001 From: Domino Valdano <2644901+reductionista@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:46:14 -0800 Subject: [PATCH 79/98] Add Topic1, Topic2, Topic3, LogsPerBlock fields to logpoller.Filter and log_poller_filters schema (#11949) * Add Topic1, Topic2, Topic3, LogsPerBlock fields to logpoller.Filter And update evm.log_poller_filters schema to match * Improve SQL QUERY logging []BYTEA was panicing for nil or empty array, which then gets trapped and ignored... making it very difficult to figure out which query the error is coming from. While fixing that bug, updated formating of []BYTEA and TEXT to be closer an actual SQL query you can run by cutting and pasting from the log * Add MaxLogsKept * Address PR comments - Add new index before removing old index to be safer - Change MaxLogsKept & LogsPerBlock from big.Int to uint64 * Update migration # after rebase --- core/chains/evm/logpoller/log_poller.go | 13 ++- .../evm/logpoller/log_poller_internal_test.go | 10 +- core/chains/evm/logpoller/log_poller_test.go | 74 +++++++++----- core/chains/evm/logpoller/orm.go | 37 +++++-- core/chains/evm/logpoller/orm_test.go | 96 +++++++++++++++++++ core/chains/evm/logpoller/query.go | 23 +++++ core/chains/evm/types/types.go | 14 ++- core/services/pg/q.go | 17 +++- core/services/pg/q_test.go | 12 +-- ...ller_filters_add_topics_logs_per_block.sql | 29 ++++++ 10 files changed, 271 insertions(+), 54 deletions(-) create mode 100644 core/store/migrate/migrations/0225_log_poller_filters_add_topics_logs_per_block.sql diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 7006c1762ef..a2c35bec59f 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -153,10 +153,15 @@ func NewLogPoller(orm ORM, ec Client, lggr logger.Logger, pollPeriod time.Durati } type Filter struct { - Name string // see FilterName(id, args) below - EventSigs evmtypes.HashArray - Addresses evmtypes.AddressArray - Retention time.Duration + Name string // see FilterName(id, args) below + Addresses evmtypes.AddressArray + EventSigs evmtypes.HashArray // list of possible values for eventsig (aka topic1) + Topic2 evmtypes.HashArray // list of possible values for topic2 + Topic3 evmtypes.HashArray // list of possible values for topic3 + Topic4 evmtypes.HashArray // list of possible values for topic4 + Retention time.Duration // maximum amount of time to retain logs + MaxLogsKept uint64 // maximum number of logs to retain ( 0 = unlimited ) + LogsPerBlock uint64 // rate limit ( maximum # of logs per block, 0 = unlimited ) } // FilterName is a suggested convenience function for clients to construct unique filter names diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go index 863ab0fddea..899efebe42c 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -71,31 +71,31 @@ func TestLogPoller_RegisterFilter(t *testing.T) { require.Equal(t, 1, len(f.Addresses)) assert.Equal(t, common.HexToAddress("0x0000000000000000000000000000000000000000"), f.Addresses[0]) - err := lp.RegisterFilter(Filter{"Emitter Log 1", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{a1}, 0}) + err := lp.RegisterFilter(Filter{Name: "Emitter Log 1", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, Addresses: []common.Address{a1}}) require.NoError(t, err) assert.Equal(t, []common.Address{a1}, lp.Filter(nil, nil, nil).Addresses) assert.Equal(t, [][]common.Hash{{EmitterABI.Events["Log1"].ID}}, lp.Filter(nil, nil, nil).Topics) validateFiltersTable(t, lp, orm) // Should de-dupe EventSigs - err = lp.RegisterFilter(Filter{"Emitter Log 1 + 2", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{a2}, 0}) + err = lp.RegisterFilter(Filter{Name: "Emitter Log 1 + 2", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, Addresses: []common.Address{a2}}) require.NoError(t, err) assert.Equal(t, []common.Address{a1, a2}, lp.Filter(nil, nil, nil).Addresses) assert.Equal(t, [][]common.Hash{{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}}, lp.Filter(nil, nil, nil).Topics) validateFiltersTable(t, lp, orm) // Should de-dupe Addresses - err = lp.RegisterFilter(Filter{"Emitter Log 1 + 2 dupe", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{a2}, 0}) + err = lp.RegisterFilter(Filter{Name: "Emitter Log 1 + 2 dupe", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, Addresses: []common.Address{a2}}) require.NoError(t, err) assert.Equal(t, []common.Address{a1, a2}, lp.Filter(nil, nil, nil).Addresses) assert.Equal(t, [][]common.Hash{{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}}, lp.Filter(nil, nil, nil).Topics) validateFiltersTable(t, lp, orm) // Address required. - err = lp.RegisterFilter(Filter{"no address", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{}, 0}) + err = lp.RegisterFilter(Filter{Name: "no address", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}}) require.Error(t, err) // Event required - err = lp.RegisterFilter(Filter{"No event", []common.Hash{}, []common.Address{a1}, 0}) + err = lp.RegisterFilter(Filter{Name: "No event", Addresses: []common.Address{a1}}) require.Error(t, err) validateFiltersTable(t, lp, orm) diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 2508e676e6c..ab02e783a28 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -150,7 +150,7 @@ func TestLogPoller_Integration(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) th.Client.Commit() // Block 2. Ensure we have finality number of blocks - require.NoError(t, th.LogPoller.RegisterFilter(logpoller.Filter{"Integration test", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{th.EmitterAddress1}, 0})) + require.NoError(t, th.LogPoller.RegisterFilter(logpoller.Filter{Name: "Integration test", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, Addresses: []common.Address{th.EmitterAddress1}})) require.Len(t, th.LogPoller.Filter(nil, nil, nil).Addresses, 1) require.Len(t, th.LogPoller.Filter(nil, nil, nil).Topics, 1) @@ -188,8 +188,9 @@ func TestLogPoller_Integration(t *testing.T) { // Now let's update the Filter and replay to get Log2 logs. err = th.LogPoller.RegisterFilter(logpoller.Filter{ - "Emitter - log2", []common.Hash{EmitterABI.Events["Log2"].ID}, - []common.Address{th.EmitterAddress1}, 0, + Name: "Emitter - log2", + EventSigs: []common.Hash{EmitterABI.Events["Log2"].ID}, + Addresses: []common.Address{th.EmitterAddress1}, }) require.NoError(t, err) // Replay an invalid block should error @@ -254,11 +255,13 @@ func Test_BackupLogPoller(t *testing.T) { ctx := testutils.Context(t) - filter1 := logpoller.Filter{"filter1", []common.Hash{ - EmitterABI.Events["Log1"].ID, - EmitterABI.Events["Log2"].ID}, - []common.Address{th.EmitterAddress1}, - 0} + filter1 := logpoller.Filter{ + Name: "filter1", + EventSigs: []common.Hash{ + EmitterABI.Events["Log1"].ID, + EmitterABI.Events["Log2"].ID}, + Addresses: []common.Address{th.EmitterAddress1}, + } err := th.LogPoller.RegisterFilter(filter1) require.NoError(t, err) @@ -268,9 +271,11 @@ func Test_BackupLogPoller(t *testing.T) { require.Equal(t, filter1, filters["filter1"]) err = th.LogPoller.RegisterFilter( - logpoller.Filter{"filter2", - []common.Hash{EmitterABI.Events["Log1"].ID}, - []common.Address{th.EmitterAddress2}, 0}) + logpoller.Filter{ + Name: "filter2", + EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, + Addresses: []common.Address{th.EmitterAddress2}, + }) require.NoError(t, err) defer func() { @@ -569,9 +574,9 @@ func TestLogPoller_BlockTimestamps(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) addresses := []common.Address{th.EmitterAddress1, th.EmitterAddress2} - topics := []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID} + events := []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID} - err := th.LogPoller.RegisterFilter(logpoller.Filter{"convertLogs", topics, addresses, 0}) + err := th.LogPoller.RegisterFilter(logpoller.Filter{Name: "convertLogs", EventSigs: events, Addresses: addresses}) require.NoError(t, err) blk, err := th.Client.BlockByNumber(ctx, nil) @@ -619,7 +624,7 @@ func TestLogPoller_BlockTimestamps(t *testing.T) { query := ethereum.FilterQuery{ FromBlock: big.NewInt(2), ToBlock: big.NewInt(5), - Topics: [][]common.Hash{topics}, + Topics: [][]common.Hash{events}, Addresses: []common.Address{th.EmitterAddress1, th.EmitterAddress2}} gethLogs, err := th.Client.FilterLogs(ctx, query) @@ -762,8 +767,9 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { // Set up a log poller listening for log emitter logs. err := th.LogPoller.RegisterFilter(logpoller.Filter{ - "Test Emitter 1 & 2", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, - []common.Address{th.EmitterAddress1, th.EmitterAddress2}, 0, + Name: "Test Emitter 1 & 2", + EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, + Addresses: []common.Address{th.EmitterAddress1, th.EmitterAddress2}, }) require.NoError(t, err) @@ -1068,12 +1074,22 @@ func TestLogPoller_LoadFilters(t *testing.T) { t.Parallel() th := SetupTH(t, false, 2, 3, 2, 1000) - filter1 := logpoller.Filter{"first Filter", []common.Hash{ - EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{th.EmitterAddress1, th.EmitterAddress2}, 0} - filter2 := logpoller.Filter{"second Filter", []common.Hash{ - EmitterABI.Events["Log2"].ID, EmitterABI.Events["Log3"].ID}, []common.Address{th.EmitterAddress2}, 0} - filter3 := logpoller.Filter{"third Filter", []common.Hash{ - EmitterABI.Events["Log1"].ID}, []common.Address{th.EmitterAddress1, th.EmitterAddress2}, 0} + filter1 := logpoller.Filter{ + Name: "first Filter", + EventSigs: []common.Hash{ + EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, + Addresses: []common.Address{th.EmitterAddress1, th.EmitterAddress2}, + } + filter2 := logpoller.Filter{ + Name: "second Filter", + EventSigs: []common.Hash{EmitterABI.Events["Log2"].ID, EmitterABI.Events["Log3"].ID}, + Addresses: []common.Address{th.EmitterAddress2}, + } + filter3 := logpoller.Filter{ + Name: "third Filter", + EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, + Addresses: []common.Address{th.EmitterAddress1, th.EmitterAddress2}, + } assert.True(t, filter1.Contains(nil)) assert.False(t, filter1.Contains(&filter2)) @@ -1119,9 +1135,11 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { t.Parallel() th := SetupTH(t, false, 2, 3, 2, 1000) - err := th.LogPoller.RegisterFilter(logpoller.Filter{"GetBlocks Test", []common.Hash{ - EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{th.EmitterAddress1, th.EmitterAddress2}, 0}, - ) + err := th.LogPoller.RegisterFilter(logpoller.Filter{ + Name: "GetBlocks Test", + EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, + Addresses: []common.Address{th.EmitterAddress1, th.EmitterAddress2}, + }) require.NoError(t, err) // LP retrieves 0 blocks @@ -1365,7 +1383,11 @@ func TestTooManyLogResults(t *testing.T) { }) addr := testutils.NewAddress() - err := lp.RegisterFilter(logpoller.Filter{"Integration test", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{addr}, 0}) + err := lp.RegisterFilter(logpoller.Filter{ + Name: "Integration test", + EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, + Addresses: []common.Address{addr}, + }) require.NoError(t, err) lp.PollAndSaveLogs(ctx, 5) block, err2 := o.SelectLatestBlock() diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 1db8271ccb6..fe814e8a43c 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -5,6 +5,7 @@ import ( "database/sql" "fmt" "math/big" + "strings" "time" "github.com/ethereum/go-ethereum/common" @@ -13,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) @@ -95,26 +97,42 @@ func (o *DbORM) InsertBlock(blockHash common.Hash, blockNumber int64, blockTimes // Each address/event pair must have a unique job id, so it may be removed when the job is deleted. // If a second job tries to overwrite the same pair, this should fail. func (o *DbORM) InsertFilter(filter Filter, qopts ...pg.QOpt) (err error) { + topicArrays := []types.HashArray{filter.Topic2, filter.Topic3, filter.Topic4} args, err := newQueryArgs(o.chainID). withCustomArg("name", filter.Name). - withCustomArg("retention", filter.Retention). + withRetention(filter.Retention). + withMaxLogsKept(filter.MaxLogsKept). + withLogsPerBlock(filter.LogsPerBlock). withAddressArray(filter.Addresses). withEventSigArray(filter.EventSigs). + withTopicArrays(filter.Topic2, filter.Topic3, filter.Topic4). toArgs() if err != nil { return err } // '::' has to be escaped in the query string // https://github.com/jmoiron/sqlx/issues/91, https://github.com/jmoiron/sqlx/issues/428 - return o.q.WithOpts(qopts...).ExecQNamed(` + var topicsColumns, topicsSql strings.Builder + for n, topicValues := range topicArrays { + if len(topicValues) != 0 { + topicCol := fmt.Sprintf("topic%d", n+2) + fmt.Fprintf(&topicsColumns, ", %s", topicCol) + fmt.Fprintf(&topicsSql, ",\n(SELECT unnest(:%s ::::BYTEA[]) %s) t%d", topicCol, topicCol, n+2) + } + } + query := fmt.Sprintf(` INSERT INTO evm.log_poller_filters - (name, evm_chain_id, retention, created_at, address, event) + (name, evm_chain_id, retention, max_logs_kept, logs_per_block, created_at, address, event %s) SELECT * FROM - (SELECT :name, :evm_chain_id ::::NUMERIC, :retention ::::BIGINT, NOW()) x, + (SELECT :name, :evm_chain_id ::::NUMERIC, :retention ::::BIGINT, :max_logs_kept ::::NUMERIC, :logs_per_block ::::NUMERIC, NOW()) x, (SELECT unnest(:address_array ::::BYTEA[]) addr) a, (SELECT unnest(:event_sig_array ::::BYTEA[]) ev) e - ON CONFLICT (name, evm_chain_id, address, event) - DO UPDATE SET retention=:retention ::::BIGINT`, args) + %s + ON CONFLICT (hash_record_extended((name, evm_chain_id, address, event, topic2, topic3, topic4), 0)) + DO UPDATE SET retention=:retention ::::BIGINT, max_logs_kept=:max_logs_kept ::::NUMERIC, logs_per_block=:logs_per_block ::::NUMERIC`, + topicsColumns.String(), + topicsSql.String()) + return o.q.WithOpts(qopts...).ExecQNamed(query, args) } // DeleteFilter removes all events,address pairs associated with the Filter @@ -130,7 +148,12 @@ func (o *DbORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) { err := q.Select(&rows, `SELECT name, ARRAY_AGG(DISTINCT address)::BYTEA[] AS addresses, ARRAY_AGG(DISTINCT event)::BYTEA[] AS event_sigs, - MAX(retention) AS retention + ARRAY_AGG(DISTINCT topic2 ORDER BY topic2) FILTER(WHERE topic2 IS NOT NULL) AS topic2, + ARRAY_AGG(DISTINCT topic3 ORDER BY topic3) FILTER(WHERE topic3 IS NOT NULL) AS topic3, + ARRAY_AGG(DISTINCT topic4 ORDER BY topic4) FILTER(WHERE topic4 IS NOT NULL) AS topic4, + MAX(logs_per_block) AS logs_per_block, + MAX(retention) AS retention, + MAX(max_logs_kept) AS max_logs_kept FROM evm.log_poller_filters WHERE evm_chain_id = $1 GROUP BY name`, ubig.New(o.chainID)) filters := make(map[string]Filter) diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index bcaa6f72fa0..9824d0e9426 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -2,6 +2,7 @@ package logpoller_test import ( "bytes" + "context" "database/sql" "fmt" "math" @@ -10,6 +11,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/jackc/pgx/v4" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -448,6 +450,100 @@ func TestORM(t *testing.T) { require.Zero(t, len(logs)) } +type PgxLogger struct { + lggr logger.Logger +} + +func NewPgxLogger(lggr logger.Logger) PgxLogger { + return PgxLogger{lggr} +} + +func (l PgxLogger) Log(ctx context.Context, log pgx.LogLevel, msg string, data map[string]interface{}) { + +} + +func TestLogPollerFilters(t *testing.T) { + lggr := logger.Test(t) + chainID := testutils.NewRandomEVMChainID() + + dbx := pgtest.NewSqlxDB(t) + orm := logpoller.NewORM(chainID, dbx, lggr, pgtest.NewQConfig(true)) + + event1 := EmitterABI.Events["Log1"].ID + event2 := EmitterABI.Events["Log2"].ID + address := common.HexToAddress("0x1234") + topicA := common.HexToHash("0x1111") + topicB := common.HexToHash("0x2222") + topicC := common.HexToHash("0x3333") + topicD := common.HexToHash("0x4444") + + filters := []logpoller.Filter{{ + Name: "filter by topic2", + EventSigs: types.HashArray{event1, event2}, + Addresses: types.AddressArray{address}, + Topic2: types.HashArray{topicA, topicB}, + }, { + Name: "filter by topic3", + Addresses: types.AddressArray{address}, + EventSigs: types.HashArray{event1}, + Topic3: types.HashArray{topicB, topicC, topicD}, + }, { + Name: "filter by topic4", + Addresses: types.AddressArray{address}, + EventSigs: types.HashArray{event1}, + Topic4: types.HashArray{topicC}, + }, { + Name: "filter by topics 2 and 4", + Addresses: types.AddressArray{address}, + EventSigs: types.HashArray{event2}, + Topic2: types.HashArray{topicA}, + Topic4: types.HashArray{topicC, topicD}, + }, { + Name: "10 lpb rate limit, 1M max logs", + Addresses: types.AddressArray{address}, + EventSigs: types.HashArray{event1}, + MaxLogsKept: 1000000, + LogsPerBlock: 10, + }, { // ensure that the UNIQUE CONSTRAINT isn't too strict (should only error if all fields are identical) + Name: "duplicate of filter by topic4", + Addresses: types.AddressArray{address}, + EventSigs: types.HashArray{event1}, + Topic3: types.HashArray{topicC}, + }} + + for _, filter := range filters { + t.Run("Save filter: "+filter.Name, func(t *testing.T) { + var count int + err := orm.InsertFilter(filter) + require.NoError(t, err) + err = dbx.Get(&count, `SELECT COUNT(*) FROM evm.log_poller_filters WHERE evm_chain_id = $1 AND name = $2`, ubig.New(chainID), filter.Name) + require.NoError(t, err) + expectedCount := len(filter.Addresses) * len(filter.EventSigs) + if len(filter.Topic2) > 0 { + expectedCount *= len(filter.Topic2) + } + if len(filter.Topic3) > 0 { + expectedCount *= len(filter.Topic3) + } + if len(filter.Topic4) > 0 { + expectedCount *= len(filter.Topic4) + } + assert.Equal(t, count, expectedCount) + }) + } + + // Make sure they all come back the same when we reload them + t.Run("Load filters", func(t *testing.T) { + loadedFilters, err := orm.LoadFilters() + require.NoError(t, err) + for _, filter := range filters { + loadedFilter, ok := loadedFilters[filter.Name] + require.True(t, ok, `Failed to reload filter "%s"`, filter.Name) + assert.Equal(t, filter, loadedFilter) + } + }) +} + func insertLogsTopicValueRange(t *testing.T, chainID *big.Int, o *logpoller.DbORM, addr common.Address, blockNumber int, eventSig common.Hash, start, stop int) { var lgs []logpoller.Log for i := start; i <= stop; i++ { diff --git a/core/chains/evm/logpoller/query.go b/core/chains/evm/logpoller/query.go index a37b15b2b2d..d8112459743 100644 --- a/core/chains/evm/logpoller/query.go +++ b/core/chains/evm/logpoller/query.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" ) @@ -54,6 +55,16 @@ func (q *queryArgs) withEventSigArray(eventSigs []common.Hash) *queryArgs { return q.withCustomArg("event_sig_array", concatBytes(eventSigs)) } +func (q *queryArgs) withTopicArray(topicValues types.HashArray, topicNum uint64) *queryArgs { + return q.withCustomArg(fmt.Sprintf("topic%d", topicNum), concatBytes(topicValues)) +} + +func (q *queryArgs) withTopicArrays(topic2Vals types.HashArray, topic3Vals types.HashArray, topic4Vals types.HashArray) *queryArgs { + return q.withTopicArray(topic2Vals, 2). + withTopicArray(topic3Vals, 3). + withTopicArray(topic4Vals, 4) +} + func (q *queryArgs) withAddress(address common.Address) *queryArgs { return q.withCustomArg("address", address) } @@ -127,6 +138,18 @@ func (q *queryArgs) withTxHash(hash common.Hash) *queryArgs { return q.withCustomHashArg("tx_hash", hash) } +func (q *queryArgs) withRetention(retention time.Duration) *queryArgs { + return q.withCustomArg("retention", retention) +} + +func (q *queryArgs) withLogsPerBlock(logsPerBlock uint64) *queryArgs { + return q.withCustomArg("logs_per_block", logsPerBlock) +} + +func (q *queryArgs) withMaxLogsKept(maxLogsKept uint64) *queryArgs { + return q.withCustomArg("max_logs_kept", maxLogsKept) +} + func (q *queryArgs) withCustomHashArg(name string, arg common.Hash) *queryArgs { return q.withCustomArg(name, arg.Bytes()) } diff --git a/core/chains/evm/types/types.go b/core/chains/evm/types/types.go index 987fd987d3f..c3ad584ebbd 100644 --- a/core/chains/evm/types/types.go +++ b/core/chains/evm/types/types.go @@ -332,7 +332,11 @@ func (a *AddressArray) Scan(src interface{}) error { if err != nil { return errors.Wrap(err, "Expected BYTEA[] column for AddressArray") } - if baArray.Status != pgtype.Present || len(baArray.Dimensions) > 1 { + if baArray.Status != pgtype.Present { + *a = nil + return nil + } + if len(baArray.Dimensions) > 1 { return errors.Errorf("Expected AddressArray to be 1-dimensional. Dimensions = %v", baArray.Dimensions) } @@ -359,14 +363,18 @@ func (h *HashArray) Scan(src interface{}) error { if err != nil { return errors.Wrap(err, "Expected BYTEA[] column for HashArray") } - if baArray.Status != pgtype.Present || len(baArray.Dimensions) > 1 { + if baArray.Status != pgtype.Present { + *h = nil + return nil + } + if len(baArray.Dimensions) > 1 { return errors.Errorf("Expected HashArray to be 1-dimensional. Dimensions = %v", baArray.Dimensions) } for i, ba := range baArray.Elements { hash := common.Hash{} if ba.Status != pgtype.Present { - return errors.Errorf("Expected all addresses in HashArray to be non-NULL. Got HashArray[%d] = NULL", i) + return errors.Errorf("Expected all hashes in HashArray to be non-NULL. Got HashArray[%d] = NULL", i) } err = hash.Scan(ba.Bytes) if err != nil { diff --git a/core/services/pg/q.go b/core/services/pg/q.go index ba2627fa745..49a18817de9 100644 --- a/core/services/pg/q.go +++ b/core/services/pg/q.go @@ -296,14 +296,25 @@ func sprintQ(query string, args []interface{}) string { case common.Hash: pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("'\\x%x'", v.Bytes())) case pq.ByteaArray: + pairs = append(pairs, fmt.Sprintf("$%d", i+1)) + if v == nil { + pairs = append(pairs, "NULL") + continue + } + if len(v) == 0 { + pairs = append(pairs, "ARRAY[]") + continue + } var s strings.Builder - fmt.Fprintf(&s, "('\\x%x'", v[0]) + fmt.Fprintf(&s, "ARRAY['\\x%x'", v[0]) for j := 1; j < len(v); j++ { fmt.Fprintf(&s, ",'\\x%x'", v[j]) } - pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("%s)", s.String())) + pairs = append(pairs, fmt.Sprintf("%s]", s.String())) + case string: + pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("'%s'", v)) default: - pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("%v", arg)) + pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("%v", v)) } } replacer := strings.NewReplacer(pairs...) diff --git a/core/services/pg/q_test.go b/core/services/pg/q_test.go index 7692fb792bd..6e59e499887 100644 --- a/core/services/pg/q_test.go +++ b/core/services/pg/q_test.go @@ -21,27 +21,27 @@ func Test_sprintQ(t *testing.T) { {"one", "SELECT $1 FROM table;", []interface{}{"foo"}, - "SELECT foo FROM table;"}, + "SELECT 'foo' FROM table;"}, {"two", "SELECT $1 FROM table WHERE bar = $2;", []interface{}{"foo", 1}, - "SELECT foo FROM table WHERE bar = 1;"}, + "SELECT 'foo' FROM table WHERE bar = 1;"}, {"limit", "SELECT $1 FROM table LIMIT $2;", []interface{}{"foo", Limit(10)}, - "SELECT foo FROM table LIMIT 10;"}, + "SELECT 'foo' FROM table LIMIT 10;"}, {"limit-all", "SELECT $1 FROM table LIMIT $2;", []interface{}{"foo", Limit(-1)}, - "SELECT foo FROM table LIMIT NULL;"}, + "SELECT 'foo' FROM table LIMIT NULL;"}, {"bytea", "SELECT $1 FROM table WHERE b = $2;", []interface{}{"foo", []byte{0x0a}}, - "SELECT foo FROM table WHERE b = '\\x0a';"}, + "SELECT 'foo' FROM table WHERE b = '\\x0a';"}, {"bytea[]", "SELECT $1 FROM table WHERE b = $2;", []interface{}{"foo", pq.ByteaArray([][]byte{{0xa}, {0xb}})}, - "SELECT foo FROM table WHERE b = ('\\x0a','\\x0b');"}, + "SELECT 'foo' FROM table WHERE b = ARRAY['\\x0a','\\x0b'];"}, } { t.Run(tt.name, func(t *testing.T) { got := sprintQ(tt.query, tt.args) diff --git a/core/store/migrate/migrations/0225_log_poller_filters_add_topics_logs_per_block.sql b/core/store/migrate/migrations/0225_log_poller_filters_add_topics_logs_per_block.sql new file mode 100644 index 00000000000..77e3d5fbd51 --- /dev/null +++ b/core/store/migrate/migrations/0225_log_poller_filters_add_topics_logs_per_block.sql @@ -0,0 +1,29 @@ +-- +goose Up + +ALTER TABLE evm.log_poller_filters + ADD COLUMN topic2 BYTEA CHECK (octet_length(topic2) = 32), + ADD COLUMN topic3 BYTEA CHECK (octet_length(topic3) = 32), + ADD COLUMN topic4 BYTEA CHECK (octet_length(topic4) = 32), + ADD COLUMN max_logs_kept BIGINT, + ADD COLUMN logs_per_block BIGINT; + +-- Ordinary UNIQUE CONSTRAINT can't work for topics because they can be NULL. Any row with any column being NULL automatically satisfies the unique constraint (NULL != NULL) +-- Using a hash of all the columns treats NULL's as the same as any other field. If we ever get to a point where we can require postgresql >= 15 then this can +-- be fixed by using UNIQUE CONSTRAINT NULLS NOT DISTINCT which treats NULL's as if they were ordinary values (NULL == NULL) +CREATE UNIQUE INDEX evm_log_poller_filters_name_chain_address_event_topics_key ON evm.log_poller_filters (hash_record_extended((name, evm_chain_id, address, event, topic2, topic3, topic4), 0)); + +ALTER TABLE evm.log_poller_filters + DROP CONSTRAINT evm_log_poller_filters_name_evm_chain_id_address_event_key; + +-- +goose Down + +ALTER TABLE evm.log_poller_filters + ADD CONSTRAINT evm_log_poller_filters_name_evm_chain_id_address_event_key UNIQUE (name, evm_chain_id, address, event); +DROP INDEX IF EXISTS evm_log_poller_filters_name_chain_address_event_topics_key; + +ALTER TABLE evm.log_poller_filters + DROP COLUMN topic2, + DROP COLUMN topic3, + DROP COLUMN topic4, + DROP COLUMN max_logs_kept, + DROP COLUMN logs_per_block; From 18a004c55738198c8eb5fa828fd4fcacf86a4411 Mon Sep 17 00:00:00 2001 From: Jim W Date: Thu, 22 Feb 2024 15:42:31 -0500 Subject: [PATCH 80/98] change method signature so that it returns a transaction rather than replacing inplace (#12124) --- common/txmgr/broadcaster.go | 4 +-- common/txmgr/types/mocks/tx_store.go | 28 +++++++++++++++------ common/txmgr/types/tx_store.go | 2 +- core/chains/evm/txmgr/evm_tx_store.go | 9 +++++-- core/chains/evm/txmgr/evm_tx_store_test.go | 8 +++--- core/chains/evm/txmgr/mocks/evm_tx_store.go | 28 +++++++++++++++------ 6 files changed, 54 insertions(+), 25 deletions(-) diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index 9f2204f37e2..4c59a950ac1 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -707,8 +707,8 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) nextUnstartedTransactionWithSequence(fromAddress ADDR) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { ctx, cancel := eb.chStop.NewCtx() defer cancel() - etx := &txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{} - if err := eb.txStore.FindNextUnstartedTransactionFromAddress(ctx, etx, fromAddress, eb.chainID); err != nil { + etx, err := eb.txStore.FindNextUnstartedTransactionFromAddress(ctx, fromAddress, eb.chainID) + if err != nil { if errors.Is(err, sql.ErrNoRows) { // Finish. No more transactions left to process. Hoorah! return nil, nil diff --git a/common/txmgr/types/mocks/tx_store.go b/common/txmgr/types/mocks/tx_store.go index 353f398316d..814207d3986 100644 --- a/common/txmgr/types/mocks/tx_store.go +++ b/common/txmgr/types/mocks/tx_store.go @@ -280,22 +280,34 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindLatestS return r0, r1 } -// FindNextUnstartedTransactionFromAddress provides a mock function with given fields: ctx, etx, fromAddress, chainID -func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindNextUnstartedTransactionFromAddress(ctx context.Context, etx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fromAddress ADDR, chainID CHAIN_ID) error { - ret := _m.Called(ctx, etx, fromAddress, chainID) +// FindNextUnstartedTransactionFromAddress provides a mock function with given fields: ctx, fromAddress, chainID +func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindNextUnstartedTransactionFromAddress(ctx context.Context, fromAddress ADDR, chainID CHAIN_ID) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { + ret := _m.Called(ctx, fromAddress, chainID) if len(ret) == 0 { panic("no return value specified for FindNextUnstartedTransactionFromAddress") } - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], ADDR, CHAIN_ID) error); ok { - r0 = rf(ctx, etx, fromAddress, chainID) + var r0 *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ADDR, CHAIN_ID) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok { + return rf(ctx, fromAddress, chainID) + } + if rf, ok := ret.Get(0).(func(context.Context, ADDR, CHAIN_ID) *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { + r0 = rf(ctx, fromAddress, chainID) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) + } } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, ADDR, CHAIN_ID) error); ok { + r1 = rf(ctx, fromAddress, chainID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // FindTransactionsConfirmedInBlockRange provides a mock function with given fields: ctx, highBlockNumber, lowBlockNumber, chainID diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go index 742a1740033..f061f0ea628 100644 --- a/common/txmgr/types/tx_store.go +++ b/common/txmgr/types/tx_store.go @@ -79,7 +79,7 @@ type TransactionStore[ FindTxWithIdempotencyKey(ctx context.Context, idempotencyKey string, chainID CHAIN_ID) (tx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) // Search for Tx using the fromAddress and sequence FindTxWithSequence(ctx context.Context, fromAddress ADDR, seq SEQ) (etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) - FindNextUnstartedTransactionFromAddress(ctx context.Context, etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fromAddress ADDR, chainID CHAIN_ID) error + FindNextUnstartedTransactionFromAddress(ctx context.Context, fromAddress ADDR, chainID CHAIN_ID) (*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) FindTransactionsConfirmedInBlockRange(ctx context.Context, highBlockNumber, lowBlockNumber int64, chainID CHAIN_ID) (etxs []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) FindEarliestUnconfirmedBroadcastTime(ctx context.Context, chainID CHAIN_ID) (null.Time, error) FindEarliestUnconfirmedTxAttemptBlock(ctx context.Context, chainID CHAIN_ID) (null.Int, error) diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index ae986acee27..364ee3f04d1 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -1545,15 +1545,20 @@ func (o *evmTxStore) SaveReplacementInProgressAttempt(ctx context.Context, oldAt } // Finds earliest saved transaction that has yet to be broadcast from the given address -func (o *evmTxStore) FindNextUnstartedTransactionFromAddress(ctx context.Context, etx *Tx, fromAddress common.Address, chainID *big.Int) error { +func (o *evmTxStore) FindNextUnstartedTransactionFromAddress(ctx context.Context, fromAddress common.Address, chainID *big.Int) (*Tx, error) { var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() qq := o.q.WithOpts(pg.WithParentCtx(ctx)) var dbEtx DbEthTx + etx := new(Tx) err := qq.Get(&dbEtx, `SELECT * FROM evm.txes WHERE from_address = $1 AND state = 'unstarted' AND evm_chain_id = $2 ORDER BY value ASC, created_at ASC, id ASC`, fromAddress, chainID.String()) dbEtx.ToTx(etx) - return pkgerrors.Wrap(err, "failed to FindNextUnstartedTransactionFromAddress") + if err != nil { + return nil, pkgerrors.Wrap(err, "failed to FindNextUnstartedTransactionFromAddress") + } + + return etx, nil } func (o *evmTxStore) UpdateTxFatalError(ctx context.Context, etx *Tx) error { diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index 35d684727d1..1e478e09b58 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -1261,16 +1261,16 @@ func TestORM_FindNextUnstartedTransactionFromAddress(t *testing.T) { t.Run("cannot find unstarted tx", func(t *testing.T) { mustInsertInProgressEthTxWithAttempt(t, txStore, 13, fromAddress) - resultEtx := new(txmgr.Tx) - err := txStore.FindNextUnstartedTransactionFromAddress(testutils.Context(t), resultEtx, fromAddress, ethClient.ConfiguredChainID()) + resultEtx, err := txStore.FindNextUnstartedTransactionFromAddress(testutils.Context(t), fromAddress, ethClient.ConfiguredChainID()) assert.ErrorIs(t, err, sql.ErrNoRows) + assert.Nil(t, resultEtx) }) t.Run("finds unstarted tx", func(t *testing.T) { mustCreateUnstartedGeneratedTx(t, txStore, fromAddress, &cltest.FixtureChainID) - resultEtx := new(txmgr.Tx) - err := txStore.FindNextUnstartedTransactionFromAddress(testutils.Context(t), resultEtx, fromAddress, ethClient.ConfiguredChainID()) + resultEtx, err := txStore.FindNextUnstartedTransactionFromAddress(testutils.Context(t), fromAddress, ethClient.ConfiguredChainID()) require.NoError(t, err) + assert.NotNil(t, resultEtx) }) } diff --git a/core/chains/evm/txmgr/mocks/evm_tx_store.go b/core/chains/evm/txmgr/mocks/evm_tx_store.go index 9690bf9728d..9f1af016fea 100644 --- a/core/chains/evm/txmgr/mocks/evm_tx_store.go +++ b/core/chains/evm/txmgr/mocks/evm_tx_store.go @@ -283,22 +283,34 @@ func (_m *EvmTxStore) FindLatestSequence(ctx context.Context, fromAddress common return r0, r1 } -// FindNextUnstartedTransactionFromAddress provides a mock function with given fields: ctx, etx, fromAddress, chainID -func (_m *EvmTxStore) FindNextUnstartedTransactionFromAddress(ctx context.Context, etx *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], fromAddress common.Address, chainID *big.Int) error { - ret := _m.Called(ctx, etx, fromAddress, chainID) +// FindNextUnstartedTransactionFromAddress provides a mock function with given fields: ctx, fromAddress, chainID +func (_m *EvmTxStore) FindNextUnstartedTransactionFromAddress(ctx context.Context, fromAddress common.Address, chainID *big.Int) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) { + ret := _m.Called(ctx, fromAddress, chainID) if len(ret) == 0 { panic("no return value specified for FindNextUnstartedTransactionFromAddress") } - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], common.Address, *big.Int) error); ok { - r0 = rf(ctx, etx, fromAddress, chainID) + var r0 *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok { + return rf(ctx, fromAddress, chainID) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok { + r0 = rf(ctx, fromAddress, chainID) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]) + } } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok { + r1 = rf(ctx, fromAddress, chainID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // FindTransactionsConfirmedInBlockRange provides a mock function with given fields: ctx, highBlockNumber, lowBlockNumber, chainID From 16f1b785ca6dfa81ddacfb871e92a1dfa9823040 Mon Sep 17 00:00:00 2001 From: Chris Cushman <104409744+vreff@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:24:50 -0500 Subject: [PATCH 81/98] [VRF-887] Add NativePayment() to VRFCoordinator_2x_Interface and integ tests (#12133) --- core/services/vrf/v2/coordinator_v2x_interface.go | 1 + core/services/vrf/v2/integration_v2_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/core/services/vrf/v2/coordinator_v2x_interface.go b/core/services/vrf/v2/coordinator_v2x_interface.go index 05a9e5d8918..c99576d7558 100644 --- a/core/services/vrf/v2/coordinator_v2x_interface.go +++ b/core/services/vrf/v2/coordinator_v2x_interface.go @@ -656,6 +656,7 @@ type RandomWordsFulfilled interface { SubID() *big.Int Payment() *big.Int Raw() types.Log + NativePayment() bool } func NewV2RandomWordsFulfilled(event *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled) RandomWordsFulfilled { diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 39acc3da3e5..5114015c008 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -751,6 +751,7 @@ func assertRandomWordsFulfilled( for filter.Next() { require.Equal(t, expectedSuccess, filter.Event().Success(), "fulfillment event success not correct, expected: %+v, actual: %+v", expectedSuccess, filter.Event().Success()) require.Equal(t, requestID, filter.Event().RequestID()) + require.Equal(t, nativePayment, filter.Event().NativePayment()) found = true rwfe = filter.Event() } From 5f212bbc8485fc1fb20076ef5df7842f7bbfc6c1 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Fri, 23 Feb 2024 08:22:18 +0100 Subject: [PATCH 82/98] CCIP-1496 Moving pruning to a separate loop and respecting paging there (#12060) * Moving pruning to a separate loop and respecting paging there * Separate parameter to configure paging during logs pruning * Fixing specs * Config fixes * Post review fixes * Post review fixes * Tests * Switching to index instead of primary key, because of the performance difference * Minor performance improvement to blocks deletion * Minor fix * Minor fix --- core/chains/evm/config/chain_scoped.go | 4 ++ core/chains/evm/config/config.go | 2 + core/chains/evm/config/toml/config.go | 1 + core/chains/evm/config/toml/defaults.go | 4 ++ .../evm/config/toml/defaults/fallback.toml | 1 + .../evm/forwarders/forwarder_manager_test.go | 4 +- core/chains/evm/logpoller/helper_test.go | 3 +- core/chains/evm/logpoller/log_poller.go | 64 ++++++++++++++---- .../evm/logpoller/log_poller_internal_test.go | 16 ++--- core/chains/evm/logpoller/log_poller_test.go | 13 ++-- core/chains/evm/logpoller/observability.go | 28 ++++++-- core/chains/evm/logpoller/orm.go | 52 +++++++++++--- core/chains/evm/logpoller/orm_test.go | 67 +++++++++++++++++-- core/chains/evm/txmgr/txmgr_test.go | 2 +- core/chains/legacyevm/chain.go | 3 +- core/config/docs/chains-evm.toml | 3 + core/services/chainlink/config_test.go | 2 + .../chainlink/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + ...annel_definition_cache_integration_test.go | 6 +- .../v21/logprovider/integration_test.go | 2 +- core/services/pg/q.go | 10 +++ core/services/pg/q_test.go | 30 +++++++++ .../promreporter/prom_reporter_test.go | 2 +- core/services/relay/evm/chain_reader_test.go | 2 +- core/services/relay/evm/config_poller_test.go | 3 +- .../relay/evm/functions/config_poller_test.go | 2 +- .../relay/evm/mercury/helpers_test.go | 2 +- .../vrf/v2/listener_v2_log_listener_test.go | 2 +- core/web/resolver/chain_test.go | 3 + core/web/resolver/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + docs/CHANGELOG.md | 1 + docs/CONFIG.md | 58 ++++++++++++++++ .../disk-based-logging-disabled.txtar | 1 + .../validate/disk-based-logging-no-dir.txtar | 1 + .../node/validate/disk-based-logging.txtar | 1 + testdata/scripts/node/validate/invalid.txtar | 1 + testdata/scripts/node/validate/valid.txtar | 1 + 39 files changed, 345 insertions(+), 60 deletions(-) diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go index c579da86c8c..69cc4c0a6ad 100644 --- a/core/chains/evm/config/chain_scoped.go +++ b/core/chains/evm/config/chain_scoped.go @@ -193,3 +193,7 @@ func (e *evmConfig) OperatorFactoryAddress() string { } return e.c.OperatorFactoryAddress.String() } + +func (e *evmConfig) LogPrunePageSize() uint32 { + return *e.c.LogPrunePageSize +} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 5b397ddd574..2cfc497f462 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -7,6 +7,7 @@ import ( gethcommon "github.com/ethereum/go-ethereum/common" commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" + commonconfig "github.com/smartcontractkit/chainlink/v2/common/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/config" @@ -36,6 +37,7 @@ type EVM interface { LogBackfillBatchSize() uint32 LogKeepBlocksDepth() uint32 LogPollInterval() time.Duration + LogPrunePageSize() uint32 MinContractPayment() *commonassets.Link MinIncomingConfirmations() uint32 NonceAutoSync() bool diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 6ebf3ed0a94..0ffe3549613 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -352,6 +352,7 @@ type Chain struct { LogBackfillBatchSize *uint32 LogPollInterval *commonconfig.Duration LogKeepBlocksDepth *uint32 + LogPrunePageSize *uint32 MinIncomingConfirmations *uint32 MinContractPayment *commonassets.Link NonceAutoSync *bool diff --git a/core/chains/evm/config/toml/defaults.go b/core/chains/evm/config/toml/defaults.go index adb91b3a1bc..242373fd4af 100644 --- a/core/chains/evm/config/toml/defaults.go +++ b/core/chains/evm/config/toml/defaults.go @@ -9,6 +9,7 @@ import ( "strings" cconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/common/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" ) @@ -136,6 +137,9 @@ func (c *Chain) SetFrom(f *Chain) { if v := f.LogKeepBlocksDepth; v != nil { c.LogKeepBlocksDepth = v } + if v := f.LogPrunePageSize; v != nil { + c.LogPrunePageSize = v + } if v := f.MinIncomingConfirmations; v != nil { c.MinIncomingConfirmations = v } diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index 94fb83849bf..7b369142133 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -6,6 +6,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinContractPayment = '.00001 link' MinIncomingConfirmations = 3 NonceAutoSync = true diff --git a/core/chains/evm/forwarders/forwarder_manager_test.go b/core/chains/evm/forwarders/forwarder_manager_test.go index 5ef150aa5c3..4480e533525 100644 --- a/core/chains/evm/forwarders/forwarder_manager_test.go +++ b/core/chains/evm/forwarders/forwarder_manager_test.go @@ -60,7 +60,7 @@ func TestFwdMgr_MaybeForwardTransaction(t *testing.T) { t.Log(authorized) evmClient := client.NewSimulatedBackendClient(t, ec, testutils.FixtureChainID) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000, 0) fwdMgr := forwarders.NewFwdMgr(db, evmClient, lp, lggr, evmcfg.EVM(), evmcfg.Database()) fwdMgr.ORM = forwarders.NewORM(db, logger.Test(t), cfg.Database()) @@ -113,7 +113,7 @@ func TestFwdMgr_AccountUnauthorizedToForward_SkipsForwarding(t *testing.T) { ec.Commit() evmClient := client.NewSimulatedBackendClient(t, ec, testutils.FixtureChainID) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000, 0) fwdMgr := forwarders.NewFwdMgr(db, evmClient, lp, lggr, evmcfg.EVM(), evmcfg.Database()) fwdMgr.ORM = forwarders.NewORM(db, logger.Test(t), cfg.Database()) diff --git a/core/chains/evm/logpoller/helper_test.go b/core/chains/evm/logpoller/helper_test.go index 9e48690a249..cb0fbd247fc 100644 --- a/core/chains/evm/logpoller/helper_test.go +++ b/core/chains/evm/logpoller/helper_test.go @@ -20,6 +20,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_emitter" @@ -66,7 +67,7 @@ func SetupTH(t testing.TB, useFinalityTag bool, finalityDepth, backfillBatchSize // Mark genesis block as finalized to avoid any nulls in the tests head := esc.Backend().Blockchain().CurrentHeader() esc.Backend().Blockchain().SetFinalized(head) - lp := logpoller.NewLogPoller(o, esc, lggr, 1*time.Hour, useFinalityTag, finalityDepth, backfillBatchSize, rpcBatchSize, keepFinalizedBlocksDepth) + lp := logpoller.NewLogPoller(o, esc, lggr, 1*time.Hour, useFinalityTag, finalityDepth, backfillBatchSize, rpcBatchSize, keepFinalizedBlocksDepth, 0) emitterAddress1, _, emitter1, err := log_emitter.DeployLogEmitter(owner, ec) require.NoError(t, err) emitterAddress2, _, emitter2, err := log_emitter.DeployLogEmitter(owner, ec) diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index a2c35bec59f..ba617a2178b 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -76,7 +76,7 @@ type LogPollerTest interface { BackupPollAndSaveLogs(ctx context.Context, backupPollerBlockDelay int64) Filter(from, to *big.Int, bh *common.Hash) ethereum.FilterQuery GetReplayFromBlock(ctx context.Context, requested int64) (int64, error) - PruneOldBlocks(ctx context.Context) error + PruneOldBlocks(ctx context.Context) (bool, error) } type Client interface { @@ -106,6 +106,7 @@ type logPoller struct { backfillBatchSize int64 // batch size to use when backfilling finalized logs rpcBatchSize int64 // batch size to use for fallback RPC calls made in GetBlocks backupPollerNextBlock int64 + logPrunePageSize int64 filterMu sync.RWMutex filters map[string]Filter @@ -130,8 +131,7 @@ type logPoller struct { // // How fast that can be done depends largely on network speed and DB, but even for the fastest // support chain, polygon, which has 2s block times, we need RPCs roughly with <= 500ms latency -func NewLogPoller(orm ORM, ec Client, lggr logger.Logger, pollPeriod time.Duration, - useFinalityTag bool, finalityDepth int64, backfillBatchSize int64, rpcBatchSize int64, keepFinalizedBlocksDepth int64) *logPoller { +func NewLogPoller(orm ORM, ec Client, lggr logger.Logger, pollPeriod time.Duration, useFinalityTag bool, finalityDepth int64, backfillBatchSize int64, rpcBatchSize int64, keepFinalizedBlocksDepth int64, logsPrunePageSize int64) *logPoller { ctx, cancel := context.WithCancel(context.Background()) return &logPoller{ ctx: ctx, @@ -147,6 +147,7 @@ func NewLogPoller(orm ORM, ec Client, lggr logger.Logger, pollPeriod time.Durati backfillBatchSize: backfillBatchSize, rpcBatchSize: rpcBatchSize, keepFinalizedBlocksDepth: keepFinalizedBlocksDepth, + logPrunePageSize: logsPrunePageSize, filters: make(map[string]Filter), filterDirty: true, // Always build Filter on first call to cache an empty filter if nothing registered yet. } @@ -392,8 +393,9 @@ func (lp *logPoller) ReplayAsync(fromBlock int64) { func (lp *logPoller) Start(context.Context) error { return lp.StartOnce("LogPoller", func() error { - lp.wg.Add(1) + lp.wg.Add(2) go lp.run() + go lp.backgroundWorkerRun() return nil }) } @@ -439,8 +441,6 @@ func (lp *logPoller) run() { logPollTick := time.After(0) // stagger these somewhat, so they don't all run back-to-back backupLogPollTick := time.After(100 * time.Millisecond) - blockPruneTick := time.After(3 * time.Second) - logPruneTick := time.After(5 * time.Second) filtersLoaded := false loadFilters := func() error { @@ -545,15 +545,38 @@ func (lp *logPoller) run() { continue } lp.BackupPollAndSaveLogs(lp.ctx, backupPollerBlockDelay) + } + } +} + +func (lp *logPoller) backgroundWorkerRun() { + defer lp.wg.Done() + + // Avoid putting too much pressure on the database by staggering the pruning of old blocks and logs. + // Usually, node after restart will have some work to boot the plugins and other services. + // Deferring first prune by minutes reduces risk of putting too much pressure on the database. + blockPruneTick := time.After(5 * time.Minute) + logPruneTick := time.After(10 * time.Minute) + + for { + select { + case <-lp.ctx.Done(): + return case <-blockPruneTick: blockPruneTick = time.After(utils.WithJitter(lp.pollPeriod * 1000)) - if err := lp.PruneOldBlocks(lp.ctx); err != nil { + if allRemoved, err := lp.PruneOldBlocks(lp.ctx); err != nil { lp.lggr.Errorw("Unable to prune old blocks", "err", err) + } else if !allRemoved { + // Tick faster when cleanup can't keep up with the pace of new blocks + blockPruneTick = time.After(utils.WithJitter(lp.pollPeriod * 100)) } case <-logPruneTick: logPruneTick = time.After(utils.WithJitter(lp.pollPeriod * 2401)) // = 7^5 avoids common factors with 1000 - if err := lp.orm.DeleteExpiredLogs(pg.WithParentCtx(lp.ctx)); err != nil { - lp.lggr.Error(err) + if allRemoved, err := lp.PruneExpiredLogs(lp.ctx); err != nil { + lp.lggr.Errorw("Unable to prune expired logs", "err", err) + } else if !allRemoved { + // Tick faster when cleanup can't keep up with the pace of new logs + logPruneTick = time.After(utils.WithJitter(lp.pollPeriod * 241)) } } } @@ -933,22 +956,35 @@ func (lp *logPoller) findBlockAfterLCA(ctx context.Context, current *evmtypes.He } // PruneOldBlocks removes blocks that are > lp.keepFinalizedBlocksDepth behind the latest finalized block. -func (lp *logPoller) PruneOldBlocks(ctx context.Context) error { +// Returns whether all blocks eligible for pruning were removed. If logPrunePageSize is set to 0, it will always return true. +func (lp *logPoller) PruneOldBlocks(ctx context.Context) (bool, error) { latestBlock, err := lp.orm.SelectLatestBlock(pg.WithParentCtx(ctx)) if err != nil { - return err + return false, err } if latestBlock == nil { // No blocks saved yet. - return nil + return true, nil } if latestBlock.FinalizedBlockNumber <= lp.keepFinalizedBlocksDepth { // No-op, keep all blocks - return nil + return true, nil } // 1-2-3-4-5(finalized)-6-7(latest), keepFinalizedBlocksDepth=3 // Remove <= 2 - return lp.orm.DeleteBlocksBefore(latestBlock.FinalizedBlockNumber-lp.keepFinalizedBlocksDepth, pg.WithParentCtx(ctx)) + rowsRemoved, err := lp.orm.DeleteBlocksBefore( + latestBlock.FinalizedBlockNumber-lp.keepFinalizedBlocksDepth, + lp.logPrunePageSize, + pg.WithParentCtx(ctx), + ) + return lp.logPrunePageSize == 0 || rowsRemoved < lp.logPrunePageSize, err +} + +// PruneExpiredLogs logs that are older than their retention period defined in Filter. +// Returns whether all logs eligible for pruning were removed. If logPrunePageSize is set to 0, it will always return true. +func (lp *logPoller) PruneExpiredLogs(ctx context.Context) (bool, error) { + rowsRemoved, err := lp.orm.DeleteExpiredLogs(lp.logPrunePageSize, pg.WithParentCtx(ctx)) + return lp.logPrunePageSize == 0 || rowsRemoved < lp.logPrunePageSize, err } // Logs returns logs matching topics and address (exactly) in the given block range, diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go index 899efebe42c..124c16d26f3 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -64,7 +64,7 @@ func TestLogPoller_RegisterFilter(t *testing.T) { orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) // Set up a test chain with a log emitting contract deployed. - lp := NewLogPoller(orm, nil, lggr, time.Hour, false, 1, 1, 2, 1000) + lp := NewLogPoller(orm, nil, lggr, time.Hour, false, 1, 1, 2, 1000, 0) // We expect a zero Filter if nothing registered yet. f := lp.Filter(nil, nil, nil) @@ -218,7 +218,7 @@ func TestLogPoller_BackupPollerStartup(t *testing.T) { ctx := testutils.Context(t) - lp := NewLogPoller(orm, ec, lggr, 1*time.Hour, false, 2, 3, 2, 1000) + lp := NewLogPoller(orm, ec, lggr, 1*time.Hour, false, 2, 3, 2, 1000, 0) lp.BackupPollAndSaveLogs(ctx, 100) assert.Equal(t, int64(0), lp.backupPollerNextBlock) assert.Equal(t, 1, observedLogs.FilterMessageSnippet("ran before first successful log poller run").Len()) @@ -258,7 +258,7 @@ func TestLogPoller_Replay(t *testing.T) { ec.On("HeadByNumber", mock.Anything, mock.Anything).Return(&head, nil) ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Once() ec.On("ConfiguredChainID").Return(chainID, nil) - lp := NewLogPoller(orm, ec, lggr, time.Hour, false, 3, 3, 3, 20) + lp := NewLogPoller(orm, ec, lggr, time.Hour, false, 3, 3, 3, 20, 0) // process 1 log in block 3 lp.PollAndSaveLogs(testutils.Context(t), 4) @@ -446,7 +446,7 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { ec := evmclimocks.NewClient(t) ec.On("HeadByNumber", mock.Anything, mock.Anything).Return(&head, nil) - lp := NewLogPoller(orm, ec, lggr, time.Hour, false, finalityDepth, 3, 3, 20) + lp := NewLogPoller(orm, ec, lggr, time.Hour, false, finalityDepth, 3, 3, 20, 0) latestBlock, lastFinalizedBlockNumber, err := lp.latestBlocks(testutils.Context(t)) require.NoError(t, err) require.Equal(t, latestBlock.Number, head.Number) @@ -470,7 +470,7 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { *(elems[1].Result.(*evmtypes.Head)) = evmtypes.Head{Number: expectedLastFinalizedBlockNumber, Hash: utils.RandomBytes32()} }) - lp := NewLogPoller(orm, ec, lggr, time.Hour, true, 3, 3, 3, 20) + lp := NewLogPoller(orm, ec, lggr, time.Hour, true, 3, 3, 3, 20, 0) latestBlock, lastFinalizedBlockNumber, err := lp.latestBlocks(testutils.Context(t)) require.NoError(t, err) @@ -488,7 +488,7 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { elems[1].Error = fmt.Errorf("some error") }) - lp := NewLogPoller(orm, ec, lggr, time.Hour, true, 3, 3, 3, 20) + lp := NewLogPoller(orm, ec, lggr, time.Hour, true, 3, 3, 3, 20, 0) _, _, err := lp.latestBlocks(testutils.Context(t)) require.Error(t, err) }) @@ -497,7 +497,7 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { ec := evmclimocks.NewClient(t) ec.On("BatchCallContext", mock.Anything, mock.Anything).Return(fmt.Errorf("some error")) - lp := NewLogPoller(orm, ec, lggr, time.Hour, true, 3, 3, 3, 20) + lp := NewLogPoller(orm, ec, lggr, time.Hour, true, 3, 3, 3, 20, 0) _, _, err := lp.latestBlocks(testutils.Context(t)) require.Error(t, err) }) @@ -506,7 +506,7 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { func benchmarkFilter(b *testing.B, nFilters, nAddresses, nEvents int) { lggr := logger.Test(b) - lp := NewLogPoller(nil, nil, lggr, 1*time.Hour, false, 2, 3, 2, 1000) + lp := NewLogPoller(nil, nil, lggr, 1*time.Hour, false, 2, 3, 2, 1000, 0) for i := 0; i < nFilters; i++ { var addresses []common.Address var events []common.Hash diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index ab02e783a28..5b894b8a19a 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -676,7 +676,7 @@ func TestLogPoller_SynchronizedWithGeth(t *testing.T) { }, 10e6) _, _, emitter1, err := log_emitter.DeployLogEmitter(owner, ec) require.NoError(t, err) - lp := logpoller.NewLogPoller(orm, client.NewSimulatedBackendClient(t, ec, chainID), lggr, 15*time.Second, false, int64(finalityDepth), 3, 2, 1000) + lp := logpoller.NewLogPoller(orm, client.NewSimulatedBackendClient(t, ec, chainID), lggr, 15*time.Second, false, int64(finalityDepth), 3, 2, 1000, 0) for i := 0; i < finalityDepth; i++ { // Have enough blocks that we could reorg the full finalityDepth-1. ec.Commit() } @@ -1306,7 +1306,7 @@ func TestLogPoller_DBErrorHandling(t *testing.T) { ec.Commit() ec.Commit() - lp := logpoller.NewLogPoller(o, client.NewSimulatedBackendClient(t, ec, chainID2), lggr, 1*time.Hour, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(o, client.NewSimulatedBackendClient(t, ec, chainID2), lggr, 1*time.Hour, false, 2, 3, 2, 1000, 0) err = lp.Replay(ctx, 5) // block number too high require.ErrorContains(t, err, "Invalid replay block number") @@ -1354,7 +1354,7 @@ func TestTooManyLogResults(t *testing.T) { chainID := testutils.NewRandomEVMChainID() db := pgtest.NewSqlxDB(t) o := logpoller.NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) - lp := logpoller.NewLogPoller(o, ec, lggr, 1*time.Hour, false, 2, 20, 10, 1000) + lp := logpoller.NewLogPoller(o, ec, lggr, 1*time.Hour, false, 2, 20, 10, 1000, 0) expected := []int64{10, 5, 2, 1} clientErr := client.JsonError{ @@ -1671,11 +1671,14 @@ func Test_PruneOldBlocks(t *testing.T) { } if tt.wantErr { - require.Error(t, th.LogPoller.PruneOldBlocks(ctx)) + _, err := th.LogPoller.PruneOldBlocks(ctx) + require.Error(t, err) return } - require.NoError(t, th.LogPoller.PruneOldBlocks(ctx)) + allDeleted, err := th.LogPoller.PruneOldBlocks(ctx) + require.NoError(t, err) + assert.True(t, allDeleted) blocks, err := th.ORM.GetBlocksRange(0, math.MaxInt64, pg.WithParentCtx(ctx)) require.NoError(t, err) assert.Len(t, blocks, tt.blocksLeft) diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index a7a0d3c03d5..abb3246585b 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -122,9 +122,9 @@ func (o *ObservedORM) DeleteFilter(name string, qopts ...pg.QOpt) error { }) } -func (o *ObservedORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { - return withObservedExec(o, "DeleteBlocksBefore", del, func() error { - return o.ORM.DeleteBlocksBefore(end, qopts...) +func (o *ObservedORM) DeleteBlocksBefore(end int64, limit int64, qopts ...pg.QOpt) (int64, error) { + return withObservedExecAndRowsAffected(o, "DeleteBlocksBefore", del, func() (int64, error) { + return o.ORM.DeleteBlocksBefore(end, limit, qopts...) }) } @@ -134,9 +134,9 @@ func (o *ObservedORM) DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) er }) } -func (o *ObservedORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { - return withObservedExec(o, "DeleteExpiredLogs", del, func() error { - return o.ORM.DeleteExpiredLogs(qopts...) +func (o *ObservedORM) DeleteExpiredLogs(limit int64, qopts ...pg.QOpt) (int64, error) { + return withObservedExecAndRowsAffected(o, "DeleteExpiredLogs", del, func() (int64, error) { + return o.ORM.DeleteExpiredLogs(limit, qopts...) }) } @@ -264,6 +264,22 @@ func withObservedQueryAndResults[T any](o *ObservedORM, queryName string, query return results, err } +func withObservedExecAndRowsAffected(o *ObservedORM, queryName string, queryType queryType, exec func() (int64, error)) (int64, error) { + queryStarted := time.Now() + rowsAffected, err := exec() + o.queryDuration. + WithLabelValues(o.chainId, queryName, string(queryType)). + Observe(float64(time.Since(queryStarted))) + + if err != nil { + o.datasetSize. + WithLabelValues(o.chainId, queryName, string(queryType)). + Set(float64(rowsAffected)) + } + + return rowsAffected, err +} + func withObservedQuery[T any](o *ObservedORM, queryName string, query func() (T, error)) (T, error) { queryStarted := time.Now() defer func() { diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index fe814e8a43c..c0e870870e6 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -30,9 +30,9 @@ type ORM interface { LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) DeleteFilter(name string, qopts ...pg.QOpt) error - DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error + DeleteBlocksBefore(end int64, limit int64, qopts ...pg.QOpt) (int64, error) DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) error - DeleteExpiredLogs(qopts ...pg.QOpt) error + DeleteExpiredLogs(limit int64, qopts ...pg.QOpt) (int64, error) GetBlocksRange(start int64, end int64, qopts ...pg.QOpt) ([]LogPollerBlock, error) SelectBlockByNumber(blockNumber int64, qopts ...pg.QOpt) (*LogPollerBlock, error) @@ -212,11 +212,28 @@ func (o *DbORM) SelectLatestLogByEventSigWithConfs(eventSig common.Hash, address return &l, nil } -// DeleteBlocksBefore delete all blocks before and including end. -func (o *DbORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { +// DeleteBlocksBefore delete blocks before and including end. When limit is set, it will delete at most limit blocks. +// Otherwise, it will delete all blocks at once. +func (o *DbORM) DeleteBlocksBefore(end int64, limit int64, qopts ...pg.QOpt) (int64, error) { q := o.q.WithOpts(qopts...) - _, err := q.Exec(`DELETE FROM evm.log_poller_blocks WHERE block_number <= $1 AND evm_chain_id = $2`, end, ubig.New(o.chainID)) - return err + if limit > 0 { + return q.ExecQWithRowsAffected( + `DELETE FROM evm.log_poller_blocks + WHERE block_number IN ( + SELECT block_number FROM evm.log_poller_blocks + WHERE block_number <= $1 + AND evm_chain_id = $2 + LIMIT $3 + ) + AND evm_chain_id = $2`, + end, ubig.New(o.chainID), limit, + ) + } + return q.ExecQWithRowsAffected( + `DELETE FROM evm.log_poller_blocks + WHERE block_number <= $1 AND evm_chain_id = $2`, + end, ubig.New(o.chainID), + ) } func (o *DbORM) DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) error { @@ -263,11 +280,30 @@ type Exp struct { ShouldDelete bool } -func (o *DbORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { +func (o *DbORM) DeleteExpiredLogs(limit int64, qopts ...pg.QOpt) (int64, error) { qopts = append(qopts, pg.WithLongQueryTimeout()) q := o.q.WithOpts(qopts...) - return q.ExecQ(`WITH r AS + if limit > 0 { + return q.ExecQWithRowsAffected(` + DELETE FROM evm.logs + WHERE (evm_chain_id, address, event_sig, block_number) IN ( + SELECT l.evm_chain_id, l.address, l.event_sig, l.block_number + FROM evm.logs l + INNER JOIN ( + SELECT address, event, MAX(retention) AS retention + FROM evm.log_poller_filters + WHERE evm_chain_id = $1 + GROUP BY evm_chain_id, address, event + HAVING NOT 0 = ANY(ARRAY_AGG(retention)) + ) r ON l.evm_chain_id = $1 AND l.address = r.address AND l.event_sig = r.event + AND l.block_timestamp <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second') + LIMIT $2 + )`, + ubig.New(o.chainID), limit) + } + + return q.ExecQWithRowsAffected(`WITH r AS ( SELECT address, event, MAX(retention) AS retention FROM evm.log_poller_filters WHERE evm_chain_id=$1 GROUP BY evm_chain_id,address, event HAVING NOT 0 = ANY(ARRAY_AGG(retention)) diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 9824d0e9426..8f89a237fd4 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -433,8 +433,9 @@ func TestORM(t *testing.T) { // Delete expired logs time.Sleep(2 * time.Millisecond) // just in case we haven't reached the end of the 1ms retention period - err = o1.DeleteExpiredLogs(pg.WithParentCtx(testutils.Context(t))) + deleted, err := o1.DeleteExpiredLogs(0, pg.WithParentCtx(testutils.Context(t))) require.NoError(t, err) + assert.Equal(t, int64(1), deleted) logs, err = o1.SelectLogsByBlockRange(1, latest.BlockNumber) require.NoError(t, err) // The only log which should be deleted is the one which matches filter1 (ret=1ms) but not filter12 (ret=1 hour) @@ -851,9 +852,11 @@ func TestORM_DeleteBlocksBefore(t *testing.T) { o1 := th.ORM require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 1, time.Now(), 0)) require.NoError(t, o1.InsertBlock(common.HexToHash("0x1235"), 2, time.Now(), 0)) - require.NoError(t, o1.DeleteBlocksBefore(1)) + deleted, err := o1.DeleteBlocksBefore(1, 0) + require.NoError(t, err) + assert.Equal(t, int64(1), deleted) // 1 should be gone. - _, err := o1.SelectBlockByNumber(1) + _, err = o1.SelectBlockByNumber(1) require.Equal(t, err, sql.ErrNoRows) b, err := o1.SelectBlockByNumber(2) require.NoError(t, err) @@ -861,7 +864,9 @@ func TestORM_DeleteBlocksBefore(t *testing.T) { // Clear multiple require.NoError(t, o1.InsertBlock(common.HexToHash("0x1236"), 3, time.Now(), 0)) require.NoError(t, o1.InsertBlock(common.HexToHash("0x1237"), 4, time.Now(), 0)) - require.NoError(t, o1.DeleteBlocksBefore(3)) + deleted, err = o1.DeleteBlocksBefore(3, 0) + require.NoError(t, err) + assert.Equal(t, int64(2), deleted) _, err = o1.SelectBlockByNumber(2) require.Equal(t, err, sql.ErrNoRows) _, err = o1.SelectBlockByNumber(3) @@ -1661,3 +1666,57 @@ func Benchmark_LogsDataWordBetween(b *testing.B) { assert.Len(b, logs, 1) } } + +func Benchmark_DeleteExpiredLogs(b *testing.B) { + chainId := big.NewInt(137) + _, db := heavyweight.FullTestDBV2(b, nil) + o := logpoller.NewORM(chainId, db, logger.Test(b), pgtest.NewQConfig(false)) + + numberOfReports := 200_000 + commitStoreAddress := utils.RandomAddress() + commitReportAccepted := utils.RandomBytes32() + + past := time.Now().Add(-1 * time.Hour) + + err := o.InsertFilter(logpoller.Filter{ + Name: "test filter", + EventSigs: []common.Hash{commitReportAccepted}, + Addresses: []common.Address{commitStoreAddress}, + Retention: 1 * time.Millisecond, + }) + require.NoError(b, err) + + for j := 0; j < 5; j++ { + var dbLogs []logpoller.Log + for i := 0; i < numberOfReports; i++ { + + dbLogs = append(dbLogs, logpoller.Log{ + EvmChainId: ubig.New(chainId), + LogIndex: int64(i + 1), + BlockHash: utils.RandomBytes32(), + BlockNumber: int64(i + 1), + BlockTimestamp: past, + EventSig: commitReportAccepted, + Topics: [][]byte{}, + Address: commitStoreAddress, + TxHash: utils.RandomHash(), + Data: []byte{}, + CreatedAt: past, + }) + } + require.NoError(b, o.InsertLogs(dbLogs)) + } + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + tx, err1 := db.Beginx() + assert.NoError(b, err1) + + _, err1 = o.DeleteExpiredLogs(0, pg.WithQueryer(tx)) + assert.NoError(b, err1) + + err1 = tx.Rollback() + assert.NoError(b, err1) + } +} diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 0e28f2948ee..85e37571b5a 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -50,7 +50,7 @@ import ( func makeTestEvmTxm( t *testing.T, db *sqlx.DB, ethClient evmclient.Client, estimator gas.EvmFeeEstimator, ccfg txmgr.ChainConfig, fcfg txmgr.FeeConfig, txConfig evmconfig.Transactions, dbConfig txmgr.DatabaseConfig, listenerConfig txmgr.ListenerConfig, keyStore keystore.Eth) (txmgr.TxManager, error) { lggr := logger.Test(t) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000, 0) // logic for building components (from evm/evm_txm.go) ------- lggr.Infow("Initializing EVM transaction manager", diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 92936299cdb..66907b8352f 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -251,7 +251,8 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod int64(cfg.EVM().FinalityDepth()), int64(cfg.EVM().LogBackfillBatchSize()), int64(cfg.EVM().RPCDefaultBatchSize()), - int64(cfg.EVM().LogKeepBlocksDepth())) + int64(cfg.EVM().LogKeepBlocksDepth()), + int64(cfg.EVM().LogPrunePageSize())) } } diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 6f2322fd6db..eec580a8e69 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -54,6 +54,9 @@ LogPollInterval = '15s' # Default # **ADVANCED** # LogKeepBlocksDepth works in conjunction with Feature.LogPoller. Controls how many blocks the poller will keep, must be greater than FinalityDepth+1. LogKeepBlocksDepth = 100000 # Default +# **ADVANCED** +# LogPrunePageSize defines size of the page for pruning logs. Controls how many logs/blocks (at most) are deleted in a single prune tick. Default value 0 means no paging, delete everything at once. +LogPrunePageSize = 0 # Default # MinContractPayment is the minimum payment in LINK required to execute a direct request job. This can be overridden on a per-job basis. MinContractPayment = '10000000000000 juels' # Default # MinIncomingConfirmations is the minimum required confirmations before a log event will be consumed. diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 552a91d6e2f..13e18145e73 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -529,6 +529,7 @@ func TestConfig_Marshal(t *testing.T) { LogBackfillBatchSize: ptr[uint32](17), LogPollInterval: &minute, LogKeepBlocksDepth: ptr[uint32](100000), + LogPrunePageSize: ptr[uint32](0), MinContractPayment: commonassets.NewLinkFromJuels(math.MaxInt64), MinIncomingConfirmations: ptr[uint32](13), NonceAutoSync: ptr(true), @@ -923,6 +924,7 @@ LinkContractAddress = '0x538aAaB4ea120b2bC2fe5D296852D948F07D849e' LogBackfillBatchSize = 17 LogPollInterval = '1m0s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 13 MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index bc1b124ccb6..fc47602ef3b 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -253,6 +253,7 @@ LinkContractAddress = '0x538aAaB4ea120b2bC2fe5D296852D948F07D849e' LogBackfillBatchSize = 17 LogPollInterval = '1m0s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 13 MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 03990b02a50..2ad6bf30c50 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -240,6 +240,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -327,6 +328,7 @@ LinkContractAddress = '0xa36085F69e2889c224210F603D836748e7dC0088' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -409,6 +411,7 @@ LinkContractAddress = '0xb0897686c545045aFc77CF20eC7A532E3120E0F1' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true diff --git a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go index a9ba09d96bb..427dd6b32c2 100644 --- a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go +++ b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go @@ -77,7 +77,7 @@ func Test_ChannelDefinitionCache_Integration(t *testing.T) { require.NoError(t, err) t.Run("with zero fromblock", func(t *testing.T) { - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000, 0) servicetest.Run(t, lp) cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, 0) @@ -142,7 +142,7 @@ func Test_ChannelDefinitionCache_Integration(t *testing.T) { t.Run("loads from ORM", func(t *testing.T) { // Override logpoller to always return no logs lp := &mockLogPoller{ - LogPoller: logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000), + LogPoller: logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000, 0), LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { return 0, nil }, @@ -176,7 +176,7 @@ func Test_ChannelDefinitionCache_Integration(t *testing.T) { pgtest.MustExec(t, db, `DELETE FROM channel_definitions`) t.Run("with non-zero fromBlock", func(t *testing.T) { - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 1, 3, 2, 1000, 0) servicetest.Run(t, lp) cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, channel2Block.Number().Int64()+1) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go index 5ef06f1bd08..ba89c52c2ef 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go @@ -661,7 +661,7 @@ func setupDependencies(t *testing.T, db *sqlx.DB, backend *backends.SimulatedBac pollerLggr := logger.TestLogger(t) pollerLggr.SetLogLevel(zapcore.WarnLevel) lorm := logpoller.NewORM(big.NewInt(1337), db, pollerLggr, pgtest.NewQConfig(false)) - lp := logpoller.NewLogPoller(lorm, ethClient, pollerLggr, 100*time.Millisecond, false, 1, 2, 2, 1000) + lp := logpoller.NewLogPoller(lorm, ethClient, pollerLggr, 100*time.Millisecond, false, 1, 2, 2, 1000, 0) return lp, ethClient } diff --git a/core/services/pg/q.go b/core/services/pg/q.go index 49a18817de9..52225ac6168 100644 --- a/core/services/pg/q.go +++ b/core/services/pg/q.go @@ -199,6 +199,16 @@ func (q Q) ExecQIter(query string, args ...interface{}) (sql.Result, context.Can res, err := q.Queryer.ExecContext(ctx, query, args...) return res, cancel, ql.withLogError(err) } +func (q Q) ExecQWithRowsAffected(query string, args ...interface{}) (int64, error) { + res, cancel, err := q.ExecQIter(query, args...) + defer cancel() + if err != nil { + return 0, err + } + + rowsDeleted, err := res.RowsAffected() + return rowsDeleted, err +} func (q Q) ExecQ(query string, args ...interface{}) error { ctx, cancel := q.Context() defer cancel() diff --git a/core/services/pg/q_test.go b/core/services/pg/q_test.go index 6e59e499887..66258fabff5 100644 --- a/core/services/pg/q_test.go +++ b/core/services/pg/q_test.go @@ -3,8 +3,14 @@ package pg import ( "testing" + "github.com/google/uuid" + "github.com/jmoiron/sqlx" "github.com/lib/pq" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) func Test_sprintQ(t *testing.T) { @@ -51,3 +57,27 @@ func Test_sprintQ(t *testing.T) { }) } } + +func Test_ExecQWithRowsAffected(t *testing.T) { + db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) + require.NoError(t, err) + q := NewQ(db, logger.NullLogger, NewQConfig(false)) + + require.NoError(t, q.ExecQ("CREATE TABLE testtable (a TEXT, b TEXT)")) + + rows, err := q.ExecQWithRowsAffected("INSERT INTO testtable (a, b) VALUES ($1, $2)", "foo", "bar") + require.NoError(t, err) + assert.Equal(t, int64(1), rows) + + rows, err = q.ExecQWithRowsAffected("INSERT INTO testtable (a, b) VALUES ($1, $1), ($2, $2), ($1, $2)", "foo", "bar") + require.NoError(t, err) + assert.Equal(t, int64(3), rows) + + rows, err = q.ExecQWithRowsAffected("delete from testtable") + require.NoError(t, err) + assert.Equal(t, int64(4), rows) + + rows, err = q.ExecQWithRowsAffected("delete from testtable") + require.NoError(t, err) + assert.Equal(t, int64(0), rows) +} diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/promreporter/prom_reporter_test.go index 60d6d9388fa..d283cb8f873 100644 --- a/core/services/promreporter/prom_reporter_test.go +++ b/core/services/promreporter/prom_reporter_test.go @@ -38,7 +38,7 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon ethClient := evmtest.NewEthClientMockWithDefaultChain(t) estimator := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) lggr := logger.TestLogger(t) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000, 0) txm, err := txmgr.NewTxm( db, diff --git a/core/services/relay/evm/chain_reader_test.go b/core/services/relay/evm/chain_reader_test.go index c5fe0a16ed4..64d9f9f1cac 100644 --- a/core/services/relay/evm/chain_reader_test.go +++ b/core/services/relay/evm/chain_reader_test.go @@ -263,7 +263,7 @@ func (it *chainReaderInterfaceTester) GetChainReader(t *testing.T) clcommontypes lggr := logger.NullLogger db := pgtest.NewSqlxDB(t) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), it.chain.Client(), lggr, time.Millisecond, false, 0, 1, 1, 10000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), it.chain.Client(), lggr, time.Millisecond, false, 0, 1, 1, 10000, 0) require.NoError(t, lp.Start(ctx)) it.chain.On("LogPoller").Return(lp) cr, err := evm.NewChainReaderService(lggr, lp, it.chain, it.chainConfig) diff --git a/core/services/relay/evm/config_poller_test.go b/core/services/relay/evm/config_poller_test.go index cd66e5479bf..089db6decd5 100644 --- a/core/services/relay/evm/config_poller_test.go +++ b/core/services/relay/evm/config_poller_test.go @@ -28,6 +28,7 @@ import ( ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmClientMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" @@ -89,7 +90,7 @@ func TestConfigPoller(t *testing.T) { cfg := pgtest.NewQConfig(false) ethClient = evmclient.NewSimulatedBackendClient(t, b, testutils.SimulatedChainID) lorm := logpoller.NewORM(testutils.SimulatedChainID, db, lggr, cfg) - lp = logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000) + lp = logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000, 0) servicetest.Run(t, lp) } diff --git a/core/services/relay/evm/functions/config_poller_test.go b/core/services/relay/evm/functions/config_poller_test.go index 2cf373d2e86..6a8c682a81b 100644 --- a/core/services/relay/evm/functions/config_poller_test.go +++ b/core/services/relay/evm/functions/config_poller_test.go @@ -81,7 +81,7 @@ func runTest(t *testing.T, pluginType functions.FunctionsPluginType, expectedDig defer ethClient.Close() lggr := logger.TestLogger(t) lorm := logpoller.NewORM(big.NewInt(1337), db, lggr, cfg) - lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000) + lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000, 0) servicetest.Run(t, lp) configPoller, err := functions.NewFunctionsConfigPoller(pluginType, lp, lggr) require.NoError(t, err) diff --git a/core/services/relay/evm/mercury/helpers_test.go b/core/services/relay/evm/mercury/helpers_test.go index f1686ee00c8..8283e80916e 100644 --- a/core/services/relay/evm/mercury/helpers_test.go +++ b/core/services/relay/evm/mercury/helpers_test.go @@ -167,7 +167,7 @@ func SetupTH(t *testing.T, feedID common.Hash) TestHarness { ethClient := evmclient.NewSimulatedBackendClient(t, b, big.NewInt(1337)) lggr := logger.TestLogger(t) lorm := logpoller.NewORM(big.NewInt(1337), db, lggr, cfg) - lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000) + lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000, 0) servicetest.Run(t, lp) configPoller, err := NewConfigPoller(lggr, lp, verifierAddress, feedID) diff --git a/core/services/vrf/v2/listener_v2_log_listener_test.go b/core/services/vrf/v2/listener_v2_log_listener_test.go index 6f5177c230a..c92795f55a6 100644 --- a/core/services/vrf/v2/listener_v2_log_listener_test.go +++ b/core/services/vrf/v2/listener_v2_log_listener_test.go @@ -92,7 +92,7 @@ func setupVRFLogPollerListenerTH(t *testing.T, // Poll period doesn't matter, we intend to call poll and save logs directly in the test. // Set it to some insanely high value to not interfere with any tests. - lp := logpoller.NewLogPoller(o, esc, lggr, 1*time.Hour, useFinalityTag, finalityDepth, backfillBatchSize, rpcBatchSize, keepFinalizedBlocksDepth) + lp := logpoller.NewLogPoller(o, esc, lggr, 1*time.Hour, useFinalityTag, finalityDepth, backfillBatchSize, rpcBatchSize, keepFinalizedBlocksDepth, 0) emitterAddress1, _, emitter1, err := log_emitter.DeployLogEmitter(owner, ec) require.NoError(t, err) diff --git a/core/web/resolver/chain_test.go b/core/web/resolver/chain_test.go index b7a4b7c8386..e2663af561f 100644 --- a/core/web/resolver/chain_test.go +++ b/core/web/resolver/chain_test.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + evmtoml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" @@ -44,6 +45,7 @@ LinkContractAddress = '0x538aAaB4ea120b2bC2fe5D296852D948F07D849e' LogBackfillBatchSize = 17 LogPollInterval = '1m0s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 13 MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true @@ -161,6 +163,7 @@ LinkContractAddress = '0x538aAaB4ea120b2bC2fe5D296852D948F07D849e' LogBackfillBatchSize = 17 LogPollInterval = '1m0s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 13 MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 67ddbb33efd..2c84024cde6 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -253,6 +253,7 @@ LinkContractAddress = '0x538aAaB4ea120b2bC2fe5D296852D948F07D849e' LogBackfillBatchSize = 17 LogPollInterval = '1m0s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 13 MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 03990b02a50..2ad6bf30c50 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -240,6 +240,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -327,6 +328,7 @@ LinkContractAddress = '0xa36085F69e2889c224210F603D836748e7dC0088' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -409,6 +411,7 @@ LinkContractAddress = '0xb0897686c545045aFc77CF20eC7A532E3120E0F1' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6647dcc1efd..7ef27305809 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Gas bumping logic to the `SuggestedPriceEstimator`. The bumping mechanism for this estimator refetches the price from the RPC and adds a buffer on top using the greater of `BumpPercent` and `BumpMin`. - Add preliminary support for "llo" job type (Data Streams V1) +- Add `LogPrunePageSize` parameter to the EVM configuration. This parameter controls the number of logs removed during prune phase in LogPoller. Default value is 0, which deletes all logs at once - exactly how it used to work, so it doesn't require any changes on the product's side. ### Fixed diff --git a/docs/CONFIG.md b/docs/CONFIG.md index cb1653c1020..baafab0d347 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1603,6 +1603,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -1685,6 +1686,7 @@ LinkContractAddress = '0x20fE562d797A42Dcb3399062AE9546cd06f63280' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -1766,6 +1768,7 @@ LinkContractAddress = '0x01BE23585060835E02B77ef475b0Cc51aA1e0709' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -1847,6 +1850,7 @@ LinkContractAddress = '0x326C977E6efc84E512bB9C30f76E30c160eD06FB' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -1929,6 +1933,7 @@ LinkContractAddress = '0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6' LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2010,6 +2015,7 @@ LinkContractAddress = '0x14AdaE34beF7ca957Ce2dDe5ADD97ea050123827' LogBackfillBatchSize = 1000 LogPollInterval = '30s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.001 link' NonceAutoSync = true @@ -2091,6 +2097,7 @@ LinkContractAddress = '0x8bBbd80981FE76d44854D8DF305e8985c19f0e78' LogBackfillBatchSize = 1000 LogPollInterval = '30s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.001 link' NonceAutoSync = true @@ -2172,6 +2179,7 @@ LinkContractAddress = '0xa36085F69e2889c224210F603D836748e7dC0088' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -2254,6 +2262,7 @@ LinkContractAddress = '0x404460C6A5EdE2D891e8297795264fDe62ADBB75' LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2334,6 +2343,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2414,6 +2424,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2495,6 +2506,7 @@ LinkContractAddress = '0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06' LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2577,6 +2589,7 @@ LinkContractAddress = '0xE2e73A1c69ecF83F464EFCE6A5be353a37cA09b2' LogBackfillBatchSize = 1000 LogPollInterval = '5s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2658,6 +2671,7 @@ LinkContractAddress = '0x404460C6A5EdE2D891e8297795264fDe62ADBB75' LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2739,6 +2753,7 @@ LinkContractAddress = '0xb0897686c545045aFc77CF20eC7A532E3120E0F1' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2820,6 +2835,7 @@ LinkContractAddress = '0x6F43FF82CCA38001B6699a8AC47A2d0E66939407' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2901,6 +2917,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -2982,6 +2999,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '5s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3063,6 +3081,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '5s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3145,6 +3164,7 @@ LinkContractAddress = '0xdc2CC710e42857672E7907CF474a69B63B93089f' LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3226,6 +3246,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3306,6 +3327,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3387,6 +3409,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3467,6 +3490,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '30s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3548,6 +3572,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3629,6 +3654,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3709,6 +3735,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '100' NonceAutoSync = true @@ -3789,6 +3816,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '30s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3870,6 +3898,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -3951,6 +3980,7 @@ LinkContractAddress = '0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4031,6 +4061,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4112,6 +4143,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4193,6 +4225,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '5s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4275,6 +4308,7 @@ LinkContractAddress = '0xf97f4df75117a78c1A5a0DBb814Af92458539FB4' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4356,6 +4390,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '5s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4437,6 +4472,7 @@ LinkContractAddress = '0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846' LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4518,6 +4554,7 @@ LinkContractAddress = '0x5947BB275c521040051D82396192181b413227A3' LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4599,6 +4636,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '5s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4679,6 +4717,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4759,6 +4798,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4840,6 +4880,7 @@ LinkContractAddress = '0x326C977E6efc84E512bB9C30f76E30c160eD06FB' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -4921,6 +4962,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5002,6 +5044,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5084,6 +5127,7 @@ LinkContractAddress = '0x615fBe6372676474d9e6933d310469c9b68e9726' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5166,6 +5210,7 @@ LinkContractAddress = '0xd14838A68E8AFBAdE5efb411d5871ea0011AFd28' LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5247,6 +5292,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '1s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5328,6 +5374,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5409,6 +5456,7 @@ FinalityTagEnabled = false LogBackfillBatchSize = 1000 LogPollInterval = '3s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5490,6 +5538,7 @@ LinkContractAddress = '0x779877A7B0D9E8603169DdbD7836e478b4624789' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true @@ -5571,6 +5620,7 @@ LinkContractAddress = '0x218532a12a389a4a92fC0C5Fb22901D1c19198aA' LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5652,6 +5702,7 @@ LinkContractAddress = '0x8b12Ac23BFe11cAb03a634C1F117D64a7f2cFD3e' LogBackfillBatchSize = 1000 LogPollInterval = '2s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true @@ -5826,6 +5877,13 @@ LogKeepBlocksDepth = 100000 # Default ``` LogKeepBlocksDepth works in conjunction with Feature.LogPoller. Controls how many blocks the poller will keep, must be greater than FinalityDepth+1. +### LogPrunePageSize +:warning: **_ADVANCED_**: _Do not change this setting unless you know what you are doing._ +```toml +LogPrunePageSize = 0 # Default +``` +LogPrunePageSize defines size of the page for pruning logs. Controls how many logs/blocks (at most) are deleted in a single prune tick. Default value 0 means no paging, delete everything at once. + ### MinContractPayment ```toml MinContractPayment = '10000000000000 juels' # Default diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 648c94ed2a1..be61aef4898 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -296,6 +296,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index dc7f87375a0..bf39b7d8394 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -296,6 +296,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 25cba748c78..0ef1c6a7132 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -296,6 +296,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 036d9544e74..e4eccf9895a 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -286,6 +286,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 6a95692d295..9c1026d7f4c 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -293,6 +293,7 @@ LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' LogBackfillBatchSize = 1000 LogPollInterval = '15s' LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true From 1e7e5b73966143e76c0076f0e70217db96c6ee39 Mon Sep 17 00:00:00 2001 From: chris-de-leon-cll <147140544+chris-de-leon-cll@users.noreply.github.com> Date: Fri, 23 Feb 2024 03:32:02 -0800 Subject: [PATCH 83/98] adds scroll l2ep fixes (#12103) --- contracts/gas-snapshots/l2ep.gas-snapshot | 8 +- .../v0.8/l2ep/dev/scroll/ScrollValidator.sol | 23 +++++- .../mocks/scroll/MockScrollL1MessageQueue.sol | 77 +++++++++++++++++++ .../test/v1_0_0/scroll/ScrollValidator.t.sol | 4 + .../test/v0.8/dev/ScrollValidator.test.ts | 9 +++ 5 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol diff --git a/contracts/gas-snapshots/l2ep.gas-snapshot b/contracts/gas-snapshots/l2ep.gas-snapshot index 1f229f7d1d9..fdc9ec9b22c 100644 --- a/contracts/gas-snapshots/l2ep.gas-snapshot +++ b/contracts/gas-snapshots/l2ep.gas-snapshot @@ -140,7 +140,7 @@ ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAdd ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 71618) ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 92018) ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 92078) -ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 15503) -ScrollValidator_Validate:test_PostSequencerOffline() (gas: 75094) -ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 75156) -ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15563) \ No newline at end of file +ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 15637) +ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78367) +ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78423) +ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15569) \ No newline at end of file diff --git a/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol b/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol index 31a5f0764ef..968b891b54a 100644 --- a/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol +++ b/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol @@ -7,6 +7,7 @@ import {ScrollSequencerUptimeFeedInterface} from "../interfaces/ScrollSequencerU import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol"; +import {IL1MessageQueue} from "@scroll-tech/contracts/L1/rollup/IL1MessageQueue.sol"; import {IL1ScrollMessenger} from "@scroll-tech/contracts/L1/IL1ScrollMessenger.sol"; /// @title ScrollValidator - makes cross chain call to update the Sequencer Uptime Feed on L2 @@ -15,6 +16,8 @@ contract ScrollValidator is TypeAndVersionInterface, AggregatorValidatorInterfac address public immutable L1_CROSS_DOMAIN_MESSENGER_ADDRESS; // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i address public immutable L2_UPTIME_FEED_ADDR; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i + address public immutable L1_MSG_QUEUE_ADDR; // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "ScrollValidator 1.0.0"; @@ -28,13 +31,21 @@ contract ScrollValidator is TypeAndVersionInterface, AggregatorValidatorInterfac /// @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address /// @param l2UptimeFeedAddr the address of the ScrollSequencerUptimeFeed contract address /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 - constructor(address l1CrossDomainMessengerAddress, address l2UptimeFeedAddr, uint32 gasLimit) { + constructor( + address l1CrossDomainMessengerAddress, + address l2UptimeFeedAddr, + address l1MessageQueueAddr, + uint32 gasLimit + ) { // solhint-disable-next-line custom-errors require(l1CrossDomainMessengerAddress != address(0), "Invalid xDomain Messenger address"); // solhint-disable-next-line custom-errors + require(l1MessageQueueAddr != address(0), "Invalid L1 message queue address"); + // solhint-disable-next-line custom-errors require(l2UptimeFeedAddr != address(0), "Invalid ScrollSequencerUptimeFeed contract address"); L1_CROSS_DOMAIN_MESSENGER_ADDRESS = l1CrossDomainMessengerAddress; L2_UPTIME_FEED_ADDR = l2UptimeFeedAddr; + L1_MSG_QUEUE_ADDR = l1MessageQueueAddr; s_gasLimit = gasLimit; } @@ -50,6 +61,12 @@ contract ScrollValidator is TypeAndVersionInterface, AggregatorValidatorInterfac return s_gasLimit; } + /// @notice makes this contract payable + /// @dev receives funds: + /// - to use them (if configured) to pay for L2 execution on L1 + /// - when withdrawing funds from L2 xDomain alias address (pay for L2 execution on L2) + receive() external payable {} + /// @notice validate method sends an xDomain L2 tx to update Uptime Feed contract on L2. /// @dev A message is sent using the L1CrossDomainMessenger. This method is accessed controlled. /// @param currentAnswer new aggregator answer - value of 1 considers the sequencer offline. @@ -60,7 +77,9 @@ contract ScrollValidator is TypeAndVersionInterface, AggregatorValidatorInterfac int256 currentAnswer ) external override checkAccess returns (bool) { // Make the xDomain call - IL1ScrollMessenger(L1_CROSS_DOMAIN_MESSENGER_ADDRESS).sendMessage( + IL1ScrollMessenger(L1_CROSS_DOMAIN_MESSENGER_ADDRESS).sendMessage{ + value: IL1MessageQueue(L1_MSG_QUEUE_ADDR).estimateCrossDomainMessageFee(s_gasLimit) + }( L2_UPTIME_FEED_ADDR, 0, abi.encodeWithSelector( diff --git a/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol new file mode 100644 index 00000000000..1700bcbe168 --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IL1MessageQueue} from "@scroll-tech/contracts/L1/rollup/IL1MessageQueue.sol"; + +contract MockScrollL1MessageQueue is IL1MessageQueue { + /// @notice The start index of all pending inclusion messages. + function pendingQueueIndex() external pure returns (uint256) { + return 0; + } + + /// @notice Return the index of next appended message. + function nextCrossDomainMessageIndex() external pure returns (uint256) { + return 0; + } + + /// @notice Return the message of in `queueIndex`. + function getCrossDomainMessage(uint256 /* queueIndex */) external pure returns (bytes32) { + return ""; + } + + /// @notice Return the amount of ETH should pay for cross domain message. + function estimateCrossDomainMessageFee(uint256 /* gasLimit */) external pure returns (uint256) { + return 0; + } + + /// @notice Return the amount of intrinsic gas fee should pay for cross domain message. + function calculateIntrinsicGasFee(bytes memory /* _calldata */) external pure returns (uint256) { + return 0; + } + + /// @notice Return the hash of a L1 message. + function computeTransactionHash( + address /* sender */, + uint256 /* queueIndex */, + uint256 /* value */, + address /* target */, + uint256 /* gasLimit */, + bytes calldata /* data */ + ) external pure returns (bytes32) { + return 0; + } + + /// @notice Append a L1 to L2 message into this contract. + /// @param target The address of target contract to call in L2. + /// @param gasLimit The maximum gas should be used for relay this message in L2. + /// @param data The calldata passed to target contract. + function appendCrossDomainMessage(address target, uint256 gasLimit, bytes calldata data) external {} + + /// @notice Append an enforced transaction to this contract. + /// @dev The address of sender should be an EOA. + /// @param sender The address of sender who will initiate this transaction in L2. + /// @param target The address of target contract to call in L2. + /// @param value The value passed + /// @param gasLimit The maximum gas should be used for this transaction in L2. + /// @param data The calldata passed to target contract. + function appendEnforcedTransaction( + address sender, + address target, + uint256 value, + uint256 gasLimit, + bytes calldata data + ) external {} + + /// @notice Pop finalized messages from queue. + /// + /// @dev We can pop at most 256 messages each time. And if the message is not skipped, + /// the corresponding entry will be cleared. + /// + /// @param startIndex The start index to pop. + /// @param count The number of messages to pop. + /// @param skippedBitmap A bitmap indicates whether a message is skipped. + function popCrossDomainMessage(uint256 startIndex, uint256 count, uint256 skippedBitmap) external {} + + /// @notice Drop a skipped message from the queue. + function dropCrossDomainMessage(uint256 index) external {} +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol index 969c78c72ef..f425ca1c6e5 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.19; import {MockScrollL1CrossDomainMessenger} from "../../mocks/scroll/MockScrollL1CrossDomainMessenger.sol"; import {MockScrollL2CrossDomainMessenger} from "../../mocks/scroll/MockScrollL2CrossDomainMessenger.sol"; +import {MockScrollL1MessageQueue} from "../../mocks/scroll/MockScrollL1MessageQueue.sol"; import {ScrollSequencerUptimeFeed} from "../../../dev/scroll/ScrollSequencerUptimeFeed.sol"; import {ScrollValidator} from "../../../dev/scroll/ScrollValidator.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; @@ -15,6 +16,7 @@ contract ScrollValidatorTest is L2EPTest { /// L2EP contracts MockScrollL1CrossDomainMessenger internal s_mockScrollL1CrossDomainMessenger; MockScrollL2CrossDomainMessenger internal s_mockScrollL2CrossDomainMessenger; + MockScrollL1MessageQueue internal s_mockScrollL1MessageQueue; ScrollSequencerUptimeFeed internal s_scrollSequencerUptimeFeed; ScrollValidator internal s_scrollValidator; @@ -32,6 +34,7 @@ contract ScrollValidatorTest is L2EPTest { function setUp() public { s_mockScrollL1CrossDomainMessenger = new MockScrollL1CrossDomainMessenger(); s_mockScrollL2CrossDomainMessenger = new MockScrollL2CrossDomainMessenger(); + s_mockScrollL1MessageQueue = new MockScrollL1MessageQueue(); s_scrollSequencerUptimeFeed = new ScrollSequencerUptimeFeed( address(s_mockScrollL1CrossDomainMessenger), @@ -42,6 +45,7 @@ contract ScrollValidatorTest is L2EPTest { s_scrollValidator = new ScrollValidator( address(s_mockScrollL1CrossDomainMessenger), address(s_scrollSequencerUptimeFeed), + address(s_mockScrollL1MessageQueue), INIT_GAS_LIMIT ); } diff --git a/contracts/test/v0.8/dev/ScrollValidator.test.ts b/contracts/test/v0.8/dev/ScrollValidator.test.ts index c5ec59c5c99..94205a03112 100644 --- a/contracts/test/v0.8/dev/ScrollValidator.test.ts +++ b/contracts/test/v0.8/dev/ScrollValidator.test.ts @@ -9,6 +9,7 @@ describe('ScrollValidator', () => { const L2_SEQ_STATUS_RECORDER_ADDRESS = '0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b' let scrollValidator: Contract + let l1MessageQueue: Contract let scrollUptimeFeedFactory: ContractFactory let mockScrollL1CrossDomainMessenger: Contract let deployer: SignerWithAddress @@ -35,6 +36,13 @@ describe('ScrollValidator', () => { mockScrollL1CrossDomainMessenger = await mockScrollL1CrossDomainMessengerFactory.deploy() + // Scroll Message Queue contract on L1 + const l1MessageQueueFactory = await ethers.getContractFactory( + 'src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol:MockScrollL1MessageQueue', + deployer, + ) + l1MessageQueue = await l1MessageQueueFactory.deploy() + // Contract under test const scrollValidatorFactory = await ethers.getContractFactory( 'src/v0.8/l2ep/dev/scroll/ScrollValidator.sol:ScrollValidator', @@ -44,6 +52,7 @@ describe('ScrollValidator', () => { scrollValidator = await scrollValidatorFactory.deploy( mockScrollL1CrossDomainMessenger.address, L2_SEQ_STATUS_RECORDER_ADDRESS, + l1MessageQueue.address, GAS_LIMIT, ) }) From 4415ddb4b3f31b519239ab87d9c01e1c4191aa6f Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 23 Feb 2024 08:57:03 -0500 Subject: [PATCH 84/98] Required version of postgres is now >= 12 (#12155) * Required version of postgres is now >= 12 11 has been EOL'd in November 2023. See: https://www.postgresql.org/support/versioning/ * Enforce minimum required Postgres version - We should not allow Chainlink to run on EOL'd postgres * Remove panic, update docker client version --- README.md | 5 +-- core/services/pg/connection.go | 46 ++++++++++++++++++++++++ core/services/pg/connection_test.go | 54 ++++++++++++++++++++++++++++- docs/CHANGELOG.md | 4 +++ 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index eff798d46b8..099712061d5 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,9 @@ regarding Chainlink social accounts, news, and networking. - Example Path for macOS `export PATH=$GOPATH/bin:$PATH` & `export GOPATH=/Users/$USER/go` 2. Install [NodeJS v16](https://nodejs.org/en/download/package-manager/) & [pnpm via npm](https://pnpm.io/installation#using-npm). - It might be easier long term to use [nvm](https://nodejs.org/en/download/package-manager/#nvm) to switch between node versions for different projects. For example, assuming $NODE_VERSION was set to a valid version of NodeJS, you could run: `nvm install $NODE_VERSION && nvm use $NODE_VERSION` -3. Install [Postgres (>= 11.x and <= 15.x)](https://wiki.postgresql.org/wiki/Detailed_installation_guides). - - You should [configure Postgres](https://www.postgresql.org/docs/12/ssl-tcp.html) to use SSL connection (or for testing you can set `?sslmode=disable` in your Postgres query string). +3. Install [Postgres (>= 12.x)](https://wiki.postgresql.org/wiki/Detailed_installation_guides). It is recommended to run the latest major version of postgres. + - Note if you are running the official Chainlink docker image, the highest supported Postgres version is 15.x due to the bundled client. + - You should [configure Postgres](https://www.postgresql.org/docs/current/ssl-tcp.html) to use SSL connection (or for testing you can set `?sslmode=disable` in your Postgres query string). 4. Ensure you have Python 3 installed (this is required by [solc-select](https://github.com/crytic/solc-select) which is needed to compile solidity contracts) 5. Download Chainlink: `git clone https://github.com/smartcontractkit/chainlink && cd chainlink` 6. Build and install Chainlink: `make install` diff --git a/core/services/pg/connection.go b/core/services/pg/connection.go index 7848c0ed5e1..3fcfd3f4ad4 100644 --- a/core/services/pg/connection.go +++ b/core/services/pg/connection.go @@ -2,6 +2,8 @@ package pg import ( "fmt" + "log" + "os" "time" "github.com/google/uuid" @@ -16,6 +18,24 @@ import ( "github.com/XSAM/otelsql" ) +var MinRequiredPGVersion = 110000 + +func init() { + // from: https://www.postgresql.org/support/versioning/ + now := time.Now() + if now.Year() > 2023 { + MinRequiredPGVersion = 120000 + } else if now.Year() > 2024 { + MinRequiredPGVersion = 130000 + } else if now.Year() > 2025 { + MinRequiredPGVersion = 140000 + } else if now.Year() > 2026 { + MinRequiredPGVersion = 150000 + } else if now.Year() > 2027 { + MinRequiredPGVersion = 160000 + } +} + type ConnectionConfig interface { DefaultIdleInTxSessionTimeout() time.Duration DefaultLockTimeout() time.Duration @@ -65,9 +85,35 @@ func NewConnection(uri string, dialect dialects.DialectName, config ConnectionCo db.SetMaxOpenConns(config.MaxOpenConns()) db.SetMaxIdleConns(config.MaxIdleConns()) + if os.Getenv("SKIP_PG_VERSION_CHECK") != "true" { + if err := checkVersion(db, MinRequiredPGVersion); err != nil { + return nil, err + } + } + return db, disallowReplica(db) } +type Getter interface { + Get(dest interface{}, query string, args ...interface{}) error +} + +func checkVersion(db Getter, minVersion int) error { + var version int + if err := db.Get(&version, "SHOW server_version_num"); err != nil { + log.Printf("Error getting server version, skipping Postgres version check: %s", err.Error()) + return nil + } + if version < 10000 { + log.Printf("Unexpectedly small version, skipping Postgres version check (you are running: %d)", version) + return nil + } + if version < minVersion { + return fmt.Errorf("The minimum required Postgres server version is %d, you are running: %d, which is EOL (see: https://www.postgresql.org/support/versioning/). It is recommended to upgrade your Postgres server. To forcibly override this check, set SKIP_PG_VERSION_CHECK=true", minVersion/10000, version/10000) + } + return nil +} + func disallowReplica(db *sqlx.DB) error { var val string err := db.Get(&val, "SHOW session_replication_role") diff --git a/core/services/pg/connection_test.go b/core/services/pg/connection_test.go index 651bf9d2d9b..b10625a82c9 100644 --- a/core/services/pg/connection_test.go +++ b/core/services/pg/connection_test.go @@ -2,18 +2,70 @@ package pg import ( "testing" + "time" "github.com/google/uuid" _ "github.com/jackc/pgx/v4/stdlib" "github.com/jmoiron/sqlx" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) -func Test_disallowReplica(t *testing.T) { +var _ Getter = &mockGetter{} + +type mockGetter struct { + version int + err error +} + +func (m *mockGetter) Get(dest interface{}, query string, args ...interface{}) error { + if m.err != nil { + return m.err + } + *(dest.(*int)) = m.version + return nil +} + +func Test_checkVersion(t *testing.T) { + if time.Now().Year() > 2027 { + t.Fatal("Postgres version numbers only registered until 2028, please update the postgres version check using: https://www.postgresql.org/support/versioning/ then fix this test") + } + t.Run("when the version is too low", func(t *testing.T) { + m := &mockGetter{version: 100000} + err := checkVersion(m, 110000) + require.Error(t, err) + assert.Contains(t, err.Error(), "The minimum required Postgres server version is 11, you are running: 10") + }) + t.Run("when the version is at minimum", func(t *testing.T) { + m := &mockGetter{version: 110000} + err := checkVersion(m, 110000) + require.NoError(t, err) + }) + t.Run("when the version is above minimum", func(t *testing.T) { + m := &mockGetter{version: 110001} + err := checkVersion(m, 110000) + require.NoError(t, err) + m = &mockGetter{version: 120000} + err = checkVersion(m, 110001) + require.NoError(t, err) + }) + t.Run("ignores wildly small versions, 0 etc", func(t *testing.T) { + m := &mockGetter{version: 9000} + err := checkVersion(m, 110001) + require.NoError(t, err) + }) + t.Run("ignores errors", func(t *testing.T) { + m := &mockGetter{err: errors.New("some error")} + err := checkVersion(m, 110001) + require.NoError(t, err) + }) +} +func Test_disallowReplica(t *testing.T) { testutils.SkipShortDB(t) db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) require.NoError(t, err) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 7ef27305809..b7c37ecb348 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `P2P.V2` is required in configuration when either `OCR` or `OCR2` are enabled. The node will fail to boot if `P2P.V2` is not enabled. +### Changed + +- Minimum required version of Postgres is now >= 12. Postgres 11 was EOL'd in November 2023. Added a new version check that will prevent Chainlink from running on EOL'd Postgres. If you are running Postgres <= 11 you should upgrade to the latest version. The check can be forcibly overridden by setting SKIP_PG_VERSION_CHECK=true. + ## 2.9.0 - UNRELEASED ### Added From ec28bb9bbb37408403d80fb7bb00af90d770175c Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 23 Feb 2024 09:12:35 -0500 Subject: [PATCH 85/98] Make the test a bit more reliable (#12129) --- core/services/ocr2/plugins/mercury/integration_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 36189475898..a12052e0b74 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -283,8 +283,8 @@ func integration_MercuryV1(t *testing.T) { 2*time.Second, // DeltaProgress 20*time.Second, // DeltaResend 400*time.Millisecond, // DeltaInitial - 100*time.Millisecond, // DeltaRound - 0, // DeltaGrace + 200*time.Millisecond, // DeltaRound + 100*time.Millisecond, // DeltaGrace 300*time.Millisecond, // DeltaCertifiedCommitRequest 1*time.Minute, // DeltaStage 100, // rMax From d10b4710d5710860f9e69a28c6a98eaba54b2caf Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Fri, 23 Feb 2024 08:52:10 -0600 Subject: [PATCH 86/98] Fix losing batch call errors for individual requests (#12127) * Fixed losing batch call errors for individual requests * Fixed linting * Added comments * Fixed linting * Improved error check in test --- common/client/mock_rpc_test.go | 70 +- common/client/multi_node.go | 94 +- common/client/multi_node_test.go | 12 +- common/client/types.go | 6 +- core/chains/evm/client/chain_client.go | 17 +- core/chains/evm/client/chain_client_test.go | 70 ++ core/chains/evm/client/chain_id_sub_test.go | 26 +- core/chains/evm/client/helpers_test.go | 42 + core/chains/evm/client/mocks/rpc_client.go | 1028 +++++++++++++++++ core/chains/evm/client/rpc_client.go | 11 +- core/chains/evm/client/send_only_node_test.go | 17 +- 11 files changed, 1258 insertions(+), 135 deletions(-) create mode 100644 core/chains/evm/client/chain_client_test.go create mode 100644 core/chains/evm/client/mocks/rpc_client.go diff --git a/common/client/mock_rpc_test.go b/common/client/mock_rpc_test.go index 72c6eb19029..465445b8092 100644 --- a/common/client/mock_rpc_test.go +++ b/common/client/mock_rpc_test.go @@ -17,12 +17,12 @@ import ( ) // mockRPC is an autogenerated mock type for the RPC type -type mockRPC[CHAIN_ID types.ID, SEQ types.Sequence, ADDR types.Hashable, BLOCK_HASH types.Hashable, TX interface{}, TX_HASH types.Hashable, EVENT interface{}, EVENT_OPS interface{}, TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH]] struct { +type mockRPC[CHAIN_ID types.ID, SEQ types.Sequence, ADDR types.Hashable, BLOCK_HASH types.Hashable, TX interface{}, TX_HASH types.Hashable, EVENT interface{}, EVENT_OPS interface{}, TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], BATCH_ELEM interface{}] struct { mock.Mock } // BalanceAt provides a mock function with given fields: ctx, accountAddress, blockNumber -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) BalanceAt(ctx context.Context, accountAddress ADDR, blockNumber *big.Int) (*big.Int, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) BalanceAt(ctx context.Context, accountAddress ADDR, blockNumber *big.Int) (*big.Int, error) { ret := _m.Called(ctx, accountAddress, blockNumber) if len(ret) == 0 { @@ -52,7 +52,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // BatchCallContext provides a mock function with given fields: ctx, b -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) BatchCallContext(ctx context.Context, b []interface{}) error { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) BatchCallContext(ctx context.Context, b []BATCH_ELEM) error { ret := _m.Called(ctx, b) if len(ret) == 0 { @@ -60,7 +60,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []interface{}) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, []BATCH_ELEM) error); ok { r0 = rf(ctx, b) } else { r0 = ret.Error(0) @@ -70,7 +70,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // BlockByHash provides a mock function with given fields: ctx, hash -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) BlockByHash(ctx context.Context, hash BLOCK_HASH) (HEAD, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) BlockByHash(ctx context.Context, hash BLOCK_HASH) (HEAD, error) { ret := _m.Called(ctx, hash) if len(ret) == 0 { @@ -98,7 +98,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // BlockByNumber provides a mock function with given fields: ctx, number -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) BlockByNumber(ctx context.Context, number *big.Int) (HEAD, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) BlockByNumber(ctx context.Context, number *big.Int) (HEAD, error) { ret := _m.Called(ctx, number) if len(ret) == 0 { @@ -126,7 +126,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // CallContext provides a mock function with given fields: ctx, result, method, args -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { var _ca []interface{} _ca = append(_ca, ctx, result, method) _ca = append(_ca, args...) @@ -147,7 +147,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // CallContract provides a mock function with given fields: ctx, msg, blockNumber -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) CallContract(ctx context.Context, msg interface{}, blockNumber *big.Int) ([]byte, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) CallContract(ctx context.Context, msg interface{}, blockNumber *big.Int) ([]byte, error) { ret := _m.Called(ctx, msg, blockNumber) if len(ret) == 0 { @@ -177,7 +177,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // ChainID provides a mock function with given fields: ctx -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) ChainID(ctx context.Context) (CHAIN_ID, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) ChainID(ctx context.Context) (CHAIN_ID, error) { ret := _m.Called(ctx) if len(ret) == 0 { @@ -205,7 +205,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // ClientVersion provides a mock function with given fields: _a0 -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) ClientVersion(_a0 context.Context) (string, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) ClientVersion(_a0 context.Context) (string, error) { ret := _m.Called(_a0) if len(ret) == 0 { @@ -233,12 +233,12 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // Close provides a mock function with given fields: -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) Close() { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Close() { _m.Called() } // CodeAt provides a mock function with given fields: ctx, account, blockNumber -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) CodeAt(ctx context.Context, account ADDR, blockNumber *big.Int) ([]byte, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) CodeAt(ctx context.Context, account ADDR, blockNumber *big.Int) ([]byte, error) { ret := _m.Called(ctx, account, blockNumber) if len(ret) == 0 { @@ -268,7 +268,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // Dial provides a mock function with given fields: ctx -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) Dial(ctx context.Context) error { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Dial(ctx context.Context) error { ret := _m.Called(ctx) if len(ret) == 0 { @@ -286,7 +286,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // DialHTTP provides a mock function with given fields: -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) DialHTTP() error { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) DialHTTP() error { ret := _m.Called() if len(ret) == 0 { @@ -304,12 +304,12 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // DisconnectAll provides a mock function with given fields: -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) DisconnectAll() { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) DisconnectAll() { _m.Called() } // EstimateGas provides a mock function with given fields: ctx, call -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) EstimateGas(ctx context.Context, call interface{}) (uint64, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) EstimateGas(ctx context.Context, call interface{}) (uint64, error) { ret := _m.Called(ctx, call) if len(ret) == 0 { @@ -337,7 +337,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // FilterEvents provides a mock function with given fields: ctx, query -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) FilterEvents(ctx context.Context, query EVENT_OPS) ([]EVENT, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) FilterEvents(ctx context.Context, query EVENT_OPS) ([]EVENT, error) { ret := _m.Called(ctx, query) if len(ret) == 0 { @@ -367,7 +367,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // LINKBalance provides a mock function with given fields: ctx, accountAddress, linkAddress -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) LINKBalance(ctx context.Context, accountAddress ADDR, linkAddress ADDR) (*assets.Link, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) LINKBalance(ctx context.Context, accountAddress ADDR, linkAddress ADDR) (*assets.Link, error) { ret := _m.Called(ctx, accountAddress, linkAddress) if len(ret) == 0 { @@ -397,7 +397,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // LatestBlockHeight provides a mock function with given fields: _a0 -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) LatestBlockHeight(_a0 context.Context) (*big.Int, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) LatestBlockHeight(_a0 context.Context) (*big.Int, error) { ret := _m.Called(_a0) if len(ret) == 0 { @@ -427,7 +427,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // PendingCallContract provides a mock function with given fields: ctx, msg -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) PendingCallContract(ctx context.Context, msg interface{}) ([]byte, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) PendingCallContract(ctx context.Context, msg interface{}) ([]byte, error) { ret := _m.Called(ctx, msg) if len(ret) == 0 { @@ -457,7 +457,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // PendingSequenceAt provides a mock function with given fields: ctx, addr -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) PendingSequenceAt(ctx context.Context, addr ADDR) (SEQ, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) PendingSequenceAt(ctx context.Context, addr ADDR) (SEQ, error) { ret := _m.Called(ctx, addr) if len(ret) == 0 { @@ -485,7 +485,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // SendEmptyTransaction provides a mock function with given fields: ctx, newTxAttempt, seq, gasLimit, fee, fromAddress -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) SendEmptyTransaction(ctx context.Context, newTxAttempt func(SEQ, uint32, FEE, ADDR) (interface{}, error), seq SEQ, gasLimit uint32, fee FEE, fromAddress ADDR) (string, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SendEmptyTransaction(ctx context.Context, newTxAttempt func(SEQ, uint32, FEE, ADDR) (interface{}, error), seq SEQ, gasLimit uint32, fee FEE, fromAddress ADDR) (string, error) { ret := _m.Called(ctx, newTxAttempt, seq, gasLimit, fee, fromAddress) if len(ret) == 0 { @@ -513,7 +513,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // SendTransaction provides a mock function with given fields: ctx, tx -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) SendTransaction(ctx context.Context, tx TX) error { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SendTransaction(ctx context.Context, tx TX) error { ret := _m.Called(ctx, tx) if len(ret) == 0 { @@ -531,7 +531,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // SequenceAt provides a mock function with given fields: ctx, accountAddress, blockNumber -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) SequenceAt(ctx context.Context, accountAddress ADDR, blockNumber *big.Int) (SEQ, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SequenceAt(ctx context.Context, accountAddress ADDR, blockNumber *big.Int) (SEQ, error) { ret := _m.Called(ctx, accountAddress, blockNumber) if len(ret) == 0 { @@ -559,12 +559,12 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // SetAliveLoopSub provides a mock function with given fields: _a0 -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) SetAliveLoopSub(_a0 types.Subscription) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SetAliveLoopSub(_a0 types.Subscription) { _m.Called(_a0) } // SimulateTransaction provides a mock function with given fields: ctx, tx -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) SimulateTransaction(ctx context.Context, tx TX) error { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SimulateTransaction(ctx context.Context, tx TX) error { ret := _m.Called(ctx, tx) if len(ret) == 0 { @@ -582,7 +582,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // Subscribe provides a mock function with given fields: ctx, channel, args -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) Subscribe(ctx context.Context, channel chan<- HEAD, args ...interface{}) (types.Subscription, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Subscribe(ctx context.Context, channel chan<- HEAD, args ...interface{}) (types.Subscription, error) { var _ca []interface{} _ca = append(_ca, ctx, channel) _ca = append(_ca, args...) @@ -615,7 +615,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // SubscribersCount provides a mock function with given fields: -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) SubscribersCount() int32 { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SubscribersCount() int32 { ret := _m.Called() if len(ret) == 0 { @@ -633,7 +633,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // TokenBalance provides a mock function with given fields: ctx, accountAddress, tokenAddress -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) TokenBalance(ctx context.Context, accountAddress ADDR, tokenAddress ADDR) (*big.Int, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) TokenBalance(ctx context.Context, accountAddress ADDR, tokenAddress ADDR) (*big.Int, error) { ret := _m.Called(ctx, accountAddress, tokenAddress) if len(ret) == 0 { @@ -663,7 +663,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // TransactionByHash provides a mock function with given fields: ctx, txHash -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) TransactionByHash(ctx context.Context, txHash TX_HASH) (TX, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) TransactionByHash(ctx context.Context, txHash TX_HASH) (TX, error) { ret := _m.Called(ctx, txHash) if len(ret) == 0 { @@ -691,7 +691,7 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // TransactionReceipt provides a mock function with given fields: ctx, txHash -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) TransactionReceipt(ctx context.Context, txHash TX_HASH) (TX_RECEIPT, error) { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) TransactionReceipt(ctx context.Context, txHash TX_HASH) (TX_RECEIPT, error) { ret := _m.Called(ctx, txHash) if len(ret) == 0 { @@ -719,17 +719,17 @@ func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS } // UnsubscribeAllExceptAliveLoop provides a mock function with given fields: -func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]) UnsubscribeAllExceptAliveLoop() { +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) UnsubscribeAllExceptAliveLoop() { _m.Called() } // newMockRPC creates a new instance of mockRPC. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. -func newMockRPC[CHAIN_ID types.ID, SEQ types.Sequence, ADDR types.Hashable, BLOCK_HASH types.Hashable, TX interface{}, TX_HASH types.Hashable, EVENT interface{}, EVENT_OPS interface{}, TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH]](t interface { +func newMockRPC[CHAIN_ID types.ID, SEQ types.Sequence, ADDR types.Hashable, BLOCK_HASH types.Hashable, TX interface{}, TX_HASH types.Hashable, EVENT interface{}, EVENT_OPS interface{}, TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], BATCH_ELEM interface{}](t interface { mock.TestingT Cleanup(func()) -}) *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD] { - mock := &mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD]{} +}) *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + mock := &mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]{} mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/common/client/multi_node.go b/common/client/multi_node.go index ae9b3afd0d4..e86a7631982 100644 --- a/common/client/multi_node.go +++ b/common/client/multi_node.go @@ -50,7 +50,8 @@ type MultiNode[ TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], - RPC_CLIENT RPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD], + RPC_CLIENT RPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM], + BATCH_ELEM any, ] interface { clientAPI[ CHAIN_ID, @@ -64,12 +65,13 @@ type MultiNode[ TX_RECEIPT, FEE, HEAD, + BATCH_ELEM, ] Close() error NodeStates() map[string]string SelectNodeRPC() (RPC_CLIENT, error) - BatchCallContextAll(ctx context.Context, b []any) error + BatchCallContextAll(ctx context.Context, b []BATCH_ELEM) error ConfiguredChainID() CHAIN_ID IsL2() bool } @@ -86,7 +88,8 @@ type multiNode[ TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], - RPC_CLIENT RPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD], + RPC_CLIENT RPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM], + BATCH_ELEM any, ] struct { services.StateMachine nodes []Node[CHAIN_ID, HEAD, RPC_CLIENT] @@ -124,7 +127,8 @@ func NewMultiNode[ TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], - RPC_CLIENT RPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD], + RPC_CLIENT RPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM], + BATCH_ELEM any, ]( lggr logger.Logger, selectionMode string, @@ -137,7 +141,7 @@ func NewMultiNode[ chainFamily string, classifySendTxError func(tx TX, err error) SendTxReturnCode, sendTxSoftTimeout time.Duration, -) MultiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT] { +) MultiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM] { nodeSelector := newNodeSelector(selectionMode, nodes) // Prometheus' default interval is 15s, set this to under 7.5s to avoid // aliasing (see: https://en.wikipedia.org/wiki/Nyquist_frequency) @@ -145,7 +149,7 @@ func NewMultiNode[ if sendTxSoftTimeout == 0 { sendTxSoftTimeout = QueryTimeout / 2 } - c := &multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]{ + c := &multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]{ nodes: nodes, sendonlys: sendonlys, chainID: chainID, @@ -171,7 +175,7 @@ func NewMultiNode[ // // Nodes handle their own redialing and runloops, so this function does not // return any error if the nodes aren't available -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) Dial(ctx context.Context) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) Dial(ctx context.Context) error { return c.StartOnce("MultiNode", func() (merr error) { if len(c.nodes) == 0 { return fmt.Errorf("no available nodes for chain %s", c.chainID.String()) @@ -218,7 +222,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } // Close tears down the MultiNode and closes all nodes -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) Close() error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) Close() error { return c.StopOnce("MultiNode", func() error { close(c.chStop) c.wg.Wait() @@ -229,7 +233,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP // SelectNodeRPC returns an RPC of an active node. If there are no active nodes it returns an error. // Call this method from your chain-specific client implementation to access any chain-specific rpc calls. -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SelectNodeRPC() (rpc RPC_CLIENT, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) SelectNodeRPC() (rpc RPC_CLIENT, err error) { n, err := c.selectNode() if err != nil { return rpc, err @@ -239,7 +243,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } // selectNode returns the active Node, if it is still nodeStateAlive, otherwise it selects a new one from the NodeSelector. -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) selectNode() (node Node[CHAIN_ID, HEAD, RPC_CLIENT], err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) selectNode() (node Node[CHAIN_ID, HEAD, RPC_CLIENT], err error) { c.activeMu.RLock() node = c.activeNode c.activeMu.RUnlock() @@ -269,7 +273,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP // nLiveNodes returns the number of currently alive nodes, as well as the highest block number and greatest total difficulty. // totalDifficulty will be 0 if all nodes return nil. -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) nLiveNodes() (nLiveNodes int, blockNumber int64, totalDifficulty *big.Int) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) nLiveNodes() (nLiveNodes int, blockNumber int64, totalDifficulty *big.Int) { totalDifficulty = big.NewInt(0) for _, n := range c.nodes { if s, num, td := n.StateAndLatest(); s == nodeStateAlive { @@ -285,7 +289,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) checkLease() { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) checkLease() { bestNode := c.nodeSelector.Select() for _, n := range c.nodes { // Terminate client subscriptions. Services are responsible for reconnecting, which will be routed to the new @@ -303,7 +307,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP c.activeMu.Unlock() } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) checkLeaseLoop() { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) checkLeaseLoop() { defer c.wg.Done() c.leaseTicker = time.NewTicker(c.leaseDuration) defer c.leaseTicker.Stop() @@ -318,7 +322,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) runLoop() { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) runLoop() { defer c.wg.Done() c.report() @@ -336,7 +340,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) report() { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) report() { type nodeWithState struct { Node string State string @@ -371,7 +375,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } // ClientAPI methods -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) BalanceAt(ctx context.Context, account ADDR, blockNumber *big.Int) (*big.Int, error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) BalanceAt(ctx context.Context, account ADDR, blockNumber *big.Int) (*big.Int, error) { n, err := c.selectNode() if err != nil { return nil, err @@ -379,7 +383,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().BalanceAt(ctx, account, blockNumber) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) BatchCallContext(ctx context.Context, b []any) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) BatchCallContext(ctx context.Context, b []BATCH_ELEM) error { n, err := c.selectNode() if err != nil { return err @@ -391,7 +395,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP // sendonlys. // CAUTION: This should only be used for mass re-transmitting transactions, it // might have unexpected effects to use it for anything else. -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) BatchCallContextAll(ctx context.Context, b []any) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) BatchCallContextAll(ctx context.Context, b []BATCH_ELEM) error { var wg sync.WaitGroup defer wg.Wait() @@ -429,7 +433,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return main.RPC().BatchCallContext(ctx, b) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) BlockByHash(ctx context.Context, hash BLOCK_HASH) (h HEAD, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) BlockByHash(ctx context.Context, hash BLOCK_HASH) (h HEAD, err error) { n, err := c.selectNode() if err != nil { return h, err @@ -437,7 +441,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().BlockByHash(ctx, hash) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) BlockByNumber(ctx context.Context, number *big.Int) (h HEAD, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) BlockByNumber(ctx context.Context, number *big.Int) (h HEAD, err error) { n, err := c.selectNode() if err != nil { return h, err @@ -445,7 +449,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().BlockByNumber(ctx, number) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { n, err := c.selectNode() if err != nil { return err @@ -453,7 +457,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().CallContext(ctx, result, method, args...) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) CallContract( +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) CallContract( ctx context.Context, attempt interface{}, blockNumber *big.Int, @@ -465,7 +469,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().CallContract(ctx, attempt, blockNumber) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) PendingCallContract( +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) PendingCallContract( ctx context.Context, attempt interface{}, ) (rpcErr []byte, extractErr error) { @@ -478,7 +482,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP // ChainID makes a direct RPC call. In most cases it should be better to use the configured chain id instead by // calling ConfiguredChainID. -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) ChainID(ctx context.Context) (id CHAIN_ID, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) ChainID(ctx context.Context) (id CHAIN_ID, err error) { n, err := c.selectNode() if err != nil { return id, err @@ -486,11 +490,11 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().ChainID(ctx) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) ChainType() config.ChainType { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) ChainType() config.ChainType { return c.chainType } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) CodeAt(ctx context.Context, account ADDR, blockNumber *big.Int) (code []byte, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) CodeAt(ctx context.Context, account ADDR, blockNumber *big.Int) (code []byte, err error) { n, err := c.selectNode() if err != nil { return code, err @@ -498,11 +502,11 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().CodeAt(ctx, account, blockNumber) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) ConfiguredChainID() CHAIN_ID { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) ConfiguredChainID() CHAIN_ID { return c.chainID } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) EstimateGas(ctx context.Context, call any) (gas uint64, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) EstimateGas(ctx context.Context, call any) (gas uint64, err error) { n, err := c.selectNode() if err != nil { return gas, err @@ -510,7 +514,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().EstimateGas(ctx, call) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) FilterEvents(ctx context.Context, query EVENT_OPS) (e []EVENT, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) FilterEvents(ctx context.Context, query EVENT_OPS) (e []EVENT, err error) { n, err := c.selectNode() if err != nil { return e, err @@ -518,11 +522,11 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().FilterEvents(ctx, query) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) IsL2() bool { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) IsL2() bool { return c.ChainType().IsL2() } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) LatestBlockHeight(ctx context.Context) (h *big.Int, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) LatestBlockHeight(ctx context.Context) (h *big.Int, err error) { n, err := c.selectNode() if err != nil { return h, err @@ -530,7 +534,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().LatestBlockHeight(ctx) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) LINKBalance(ctx context.Context, accountAddress ADDR, linkAddress ADDR) (b *assets.Link, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) LINKBalance(ctx context.Context, accountAddress ADDR, linkAddress ADDR) (b *assets.Link, err error) { n, err := c.selectNode() if err != nil { return b, err @@ -538,7 +542,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().LINKBalance(ctx, accountAddress, linkAddress) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) NodeStates() (states map[string]string) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) NodeStates() (states map[string]string) { states = make(map[string]string) for _, n := range c.nodes { states[n.Name()] = n.State().String() @@ -549,7 +553,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) PendingSequenceAt(ctx context.Context, addr ADDR) (s SEQ, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) PendingSequenceAt(ctx context.Context, addr ADDR) (s SEQ, err error) { n, err := c.selectNode() if err != nil { return s, err @@ -557,7 +561,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().PendingSequenceAt(ctx, addr) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SendEmptyTransaction( +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) SendEmptyTransaction( ctx context.Context, newTxAttempt func(seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (attempt any, err error), seq SEQ, @@ -577,7 +581,7 @@ type sendTxResult struct { ResultCode SendTxReturnCode } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) broadcastTxAsync(ctx context.Context, +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) broadcastTxAsync(ctx context.Context, n SendOnlyNode[CHAIN_ID, RPC_CLIENT], tx TX) sendTxResult { txErr := n.RPC().SendTransaction(ctx, tx) c.lggr.Debugw("Node sent transaction", "name", n.String(), "tx", tx, "err", txErr) @@ -590,7 +594,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } // collectTxResults - refer to SendTransaction comment for implementation details, -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) collectTxResults(ctx context.Context, tx TX, healthyNodesNum int, txResults <-chan sendTxResult) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) collectTxResults(ctx context.Context, tx TX, healthyNodesNum int, txResults <-chan sendTxResult) error { if healthyNodesNum == 0 { return ErroringNodeError } @@ -633,7 +637,7 @@ loop: } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) reportSendTxAnomalies(tx TX, txResults <-chan sendTxResult) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) reportSendTxAnomalies(tx TX, txResults <-chan sendTxResult) { defer c.wg.Done() resultsByCode := map[SendTxReturnCode][]error{} // txResults eventually will be closed @@ -698,7 +702,7 @@ const sendTxQuorum = 0.7 // * If there is at least one terminal error - returns terminal error // * If there is both success and terminal error - returns success and reports invariant violation // * Otherwise, returns any (effectively random) of the errors. -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SendTransaction(ctx context.Context, tx TX) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) SendTransaction(ctx context.Context, tx TX) error { if len(c.nodes) == 0 { return ErroringNodeError } @@ -768,7 +772,7 @@ func findFirstIn[K comparable, V any](set map[K]V, keys []K) (V, bool) { return v, false } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SequenceAt(ctx context.Context, account ADDR, blockNumber *big.Int) (s SEQ, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) SequenceAt(ctx context.Context, account ADDR, blockNumber *big.Int) (s SEQ, err error) { n, err := c.selectNode() if err != nil { return s, err @@ -776,7 +780,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().SequenceAt(ctx, account, blockNumber) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) SimulateTransaction(ctx context.Context, tx TX) error { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) SimulateTransaction(ctx context.Context, tx TX) error { n, err := c.selectNode() if err != nil { return err @@ -784,7 +788,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().SimulateTransaction(ctx, tx) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) Subscribe(ctx context.Context, channel chan<- HEAD, args ...interface{}) (s types.Subscription, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) Subscribe(ctx context.Context, channel chan<- HEAD, args ...interface{}) (s types.Subscription, err error) { n, err := c.selectNode() if err != nil { return s, err @@ -792,7 +796,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().Subscribe(ctx, channel, args...) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) TokenBalance(ctx context.Context, account ADDR, tokenAddr ADDR) (b *big.Int, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) TokenBalance(ctx context.Context, account ADDR, tokenAddr ADDR) (b *big.Int, err error) { n, err := c.selectNode() if err != nil { return b, err @@ -800,7 +804,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().TokenBalance(ctx, account, tokenAddr) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) TransactionByHash(ctx context.Context, txHash TX_HASH) (tx TX, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) TransactionByHash(ctx context.Context, txHash TX_HASH) (tx TX, err error) { n, err := c.selectNode() if err != nil { return tx, err @@ -808,7 +812,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().TransactionByHash(ctx, txHash) } -func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) TransactionReceipt(ctx context.Context, txHash TX_HASH) (txr TX_RECEIPT, err error) { +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) TransactionReceipt(ctx context.Context, txHash TX_HASH) (txr TX_RECEIPT, err error) { n, err := c.selectNode() if err != nil { return txr, err diff --git a/common/client/multi_node_test.go b/common/client/multi_node_test.go index dabaae57c5d..43e4127556a 100644 --- a/common/client/multi_node_test.go +++ b/common/client/multi_node_test.go @@ -22,11 +22,11 @@ import ( ) type multiNodeRPCClient RPC[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, - types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable]] + types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], any] type testMultiNode struct { *multiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, - types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient] + types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient, any] } type multiNodeOpts struct { @@ -49,19 +49,19 @@ func newTestMultiNode(t *testing.T, opts multiNodeOpts) testMultiNode { } result := NewMultiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, - types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient](opts.logger, + types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient, any](opts.logger, opts.selectionMode, opts.leaseDuration, opts.noNewHeadsThreshold, opts.nodes, opts.sendonlys, opts.chainID, opts.chainType, opts.chainFamily, opts.classifySendTxError, opts.sendTxSoftTimeout) return testMultiNode{ result.(*multiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, - types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient]), + types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient, any]), } } func newMultiNodeRPCClient(t *testing.T) *mockRPC[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, - types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable]] { + types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], any] { return newMockRPC[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any, - types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable]](t) + types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], any](t) } func newHealthyNode(t *testing.T, chainID types.ID) *mockNode[types.ID, types.Head[Hashable], multiNodeRPCClient] { diff --git a/common/client/types.go b/common/client/types.go index fe9e4d7d482..c05ab238f57 100644 --- a/common/client/types.go +++ b/common/client/types.go @@ -24,7 +24,7 @@ type RPC[ TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], - + BATCH_ELEM any, ] interface { NodeClient[ CHAIN_ID, @@ -42,6 +42,7 @@ type RPC[ TX_RECEIPT, FEE, HEAD, + BATCH_ELEM, ] } @@ -84,6 +85,7 @@ type clientAPI[ TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], + BATCH_ELEM any, ] interface { connection[CHAIN_ID, HEAD] @@ -118,7 +120,7 @@ type clientAPI[ FilterEvents(ctx context.Context, query EVENT_OPS) ([]EVENT, error) // Misc - BatchCallContext(ctx context.Context, b []any) error + BatchCallContext(ctx context.Context, b []BATCH_ELEM) error CallContract( ctx context.Context, msg interface{}, diff --git a/core/chains/evm/client/chain_client.go b/core/chains/evm/client/chain_client.go index b16054b69a8..33deed1df32 100644 --- a/core/chains/evm/client/chain_client.go +++ b/core/chains/evm/client/chain_client.go @@ -36,6 +36,7 @@ type chainClient struct { *assets.Wei, *evmtypes.Head, RPCCLient, + rpc.BatchElem, ] logger logger.SugaredLogger } @@ -88,20 +89,16 @@ func (c *chainClient) BalanceAt(ctx context.Context, account common.Address, blo return c.multiNode.BalanceAt(ctx, account, blockNumber) } +// Request specific errors for batch calls are returned to the individual BatchElem. +// Ensure the same BatchElem slice provided by the caller is passed through the call stack +// to ensure the caller has access to the errors. func (c *chainClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { - batch := make([]any, len(b)) - for i, arg := range b { - batch[i] = any(arg) - } - return c.multiNode.BatchCallContext(ctx, batch) + return c.multiNode.BatchCallContext(ctx, b) } +// Similar to BatchCallContext, ensure the provided BatchElem slice is passed through func (c *chainClient) BatchCallContextAll(ctx context.Context, b []rpc.BatchElem) error { - batch := make([]any, len(b)) - for i, arg := range b { - batch[i] = any(arg) - } - return c.multiNode.BatchCallContextAll(ctx, batch) + return c.multiNode.BatchCallContextAll(ctx, b) } // TODO-1663: return custom Block type instead of geth's once client.go is deprecated. diff --git a/core/chains/evm/client/chain_client_test.go b/core/chains/evm/client/chain_client_test.go new file mode 100644 index 00000000000..6af9a67ee1c --- /dev/null +++ b/core/chains/evm/client/chain_client_test.go @@ -0,0 +1,70 @@ +package client_test + +import ( + "errors" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + commonclient "github.com/smartcontractkit/chainlink/v2/common/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +func newMockRpc(t *testing.T) *mocks.RPCCLient { + mockRpc := mocks.NewRPCCLient(t) + mockRpc.On("Dial", mock.Anything).Return(nil).Once() + mockRpc.On("Close").Return(nil).Once() + mockRpc.On("ChainID", mock.Anything).Return(testutils.FixtureChainID, nil).Once() + mockRpc.On("Subscribe", mock.Anything, mock.Anything, mock.Anything).Return(client.NewMockSubscription(), nil).Once() + mockRpc.On("SetAliveLoopSub", mock.Anything).Return().Once() + return mockRpc +} + +func TestChainClient_BatchCallContext(t *testing.T) { + t.Parallel() + + t.Run("batch requests return errors", func(t *testing.T) { + ctx := testutils.Context(t) + rpcError := errors.New("something went wrong") + blockNumResp := "" + blockNum := hexutil.EncodeBig(big.NewInt(42)) + b := []rpc.BatchElem{ + { + Method: "eth_getBlockByNumber", + Args: []interface{}{blockNum, true}, + Result: &types.Block{}, + }, + { + Method: "eth_blockNumber", + Result: &blockNumResp, + }, + } + + mockRpc := newMockRpc(t) + mockRpc.On("BatchCallContext", mock.Anything, b).Run(func(args mock.Arguments) { + reqs := args.Get(1).([]rpc.BatchElem) + for i := 0; i < len(reqs); i++ { + elem := &reqs[i] + elem.Error = rpcError + } + }).Return(nil).Once() + + client := client.NewChainClientWithMockedRpc(t, commonclient.NodeSelectionModeRoundRobin, time.Second*0, time.Second*0, testutils.FixtureChainID, mockRpc) + err := client.Dial(ctx) + require.NoError(t, err) + + err = client.BatchCallContext(ctx, b) + require.NoError(t, err) + for _, elem := range b { + require.ErrorIs(t, rpcError, elem.Error) + } + }) +} diff --git a/core/chains/evm/client/chain_id_sub_test.go b/core/chains/evm/client/chain_id_sub_test.go index c71b45c489e..f959376acca 100644 --- a/core/chains/evm/client/chain_id_sub_test.go +++ b/core/chains/evm/client/chain_id_sub_test.go @@ -11,22 +11,6 @@ import ( ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" ) -type mockSubscription struct { - unsubscribed bool - Errors chan error -} - -func newMockSubscription() *mockSubscription { - return &mockSubscription{Errors: make(chan error)} -} - -func (mes *mockSubscription) Err() <-chan error { return mes.Errors } - -func (mes *mockSubscription) Unsubscribe() { - mes.unsubscribed = true - close(mes.Errors) -} - func TestChainIDSubForwarder(t *testing.T) { t.Parallel() @@ -37,7 +21,7 @@ func TestChainIDSubForwarder(t *testing.T) { ch := make(chan *evmtypes.Head) forwarder := newChainIDSubForwarder(chainID, ch) - sub := newMockSubscription() + sub := NewMockSubscription() err := forwarder.start(sub, nil) assert.NoError(t, err) forwarder.Unsubscribe() @@ -54,7 +38,7 @@ func TestChainIDSubForwarder(t *testing.T) { ch := make(chan *evmtypes.Head) forwarder := newChainIDSubForwarder(chainID, ch) - sub := newMockSubscription() + sub := NewMockSubscription() err := forwarder.start(sub, nil) assert.NoError(t, err) sub.Errors <- errors.New("boo") @@ -72,7 +56,7 @@ func TestChainIDSubForwarder(t *testing.T) { ch := make(chan *evmtypes.Head) forwarder := newChainIDSubForwarder(chainID, ch) - sub := newMockSubscription() + sub := NewMockSubscription() err := forwarder.start(sub, nil) assert.NoError(t, err) forwarder.srcCh <- &evmtypes.Head{} @@ -90,7 +74,7 @@ func TestChainIDSubForwarder(t *testing.T) { ch := make(chan *evmtypes.Head) forwarder := newChainIDSubForwarder(chainID, ch) - sub := newMockSubscription() + sub := NewMockSubscription() errIn := errors.New("foo") errOut := forwarder.start(sub, errIn) assert.Equal(t, errIn, errOut) @@ -101,7 +85,7 @@ func TestChainIDSubForwarder(t *testing.T) { ch := make(chan *evmtypes.Head) forwarder := newChainIDSubForwarder(chainID, ch) - sub := newMockSubscription() + sub := NewMockSubscription() err := forwarder.start(sub, nil) assert.NoError(t, err) diff --git a/core/chains/evm/client/helpers_test.go b/core/chains/evm/client/helpers_test.go index c2f60e13f55..467195e11e8 100644 --- a/core/chains/evm/client/helpers_test.go +++ b/core/chains/evm/client/helpers_test.go @@ -127,6 +127,32 @@ func NewChainClientWithEmptyNode( return c } +func NewChainClientWithMockedRpc( + t *testing.T, + selectionMode string, + leaseDuration time.Duration, + noNewHeadsThreshold time.Duration, + chainID *big.Int, + rpc RPCCLient, +) Client { + + lggr := logger.Test(t) + + var chainType commonconfig.ChainType + + cfg := TestNodePoolConfig{ + NodeSelectionMode: NodeSelectionMode_RoundRobin, + } + parsed, _ := url.ParseRequestURI("ws://test") + + n := commonclient.NewNode[*big.Int, *evmtypes.Head, RPCCLient]( + cfg, noNewHeadsThreshold, lggr, *parsed, nil, "eth-primary-node-0", 1, chainID, 1, rpc, "EVM") + primaries := []commonclient.Node[*big.Int, *evmtypes.Head, RPCCLient]{n} + c := NewChainClient(lggr, selectionMode, leaseDuration, noNewHeadsThreshold, primaries, nil, chainID, chainType) + t.Cleanup(c.Close) + return c +} + type TestableSendOnlyNode interface { SendOnlyNode SetEthClient(newBatchSender BatchSender, newSender TxSender) @@ -137,3 +163,19 @@ const HeadResult = `{"difficulty":"0xf3a00","extraData":"0xd88301050384676574688 func IsDialed(s SendOnlyNode) bool { return s.(*sendOnlyNode).dialed } + +type mockSubscription struct { + unsubscribed bool + Errors chan error +} + +func NewMockSubscription() *mockSubscription { + return &mockSubscription{Errors: make(chan error)} +} + +func (mes *mockSubscription) Err() <-chan error { return mes.Errors } + +func (mes *mockSubscription) Unsubscribe() { + mes.unsubscribed = true + close(mes.Errors) +} diff --git a/core/chains/evm/client/mocks/rpc_client.go b/core/chains/evm/client/mocks/rpc_client.go new file mode 100644 index 00000000000..186fd2534e3 --- /dev/null +++ b/core/chains/evm/client/mocks/rpc_client.go @@ -0,0 +1,1028 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +package mocks + +import ( + big "math/big" + + assets "github.com/smartcontractkit/chainlink-common/pkg/assets" + + common "github.com/ethereum/go-ethereum/common" + + commontypes "github.com/smartcontractkit/chainlink/v2/common/types" + + context "context" + + coretypes "github.com/ethereum/go-ethereum/core/types" + + ethereum "github.com/ethereum/go-ethereum" + + evmassets "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + + mock "github.com/stretchr/testify/mock" + + rpc "github.com/ethereum/go-ethereum/rpc" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +// RPCCLient is an autogenerated mock type for the RPCCLient type +type RPCCLient struct { + mock.Mock +} + +// BalanceAt provides a mock function with given fields: ctx, accountAddress, blockNumber +func (_m *RPCCLient) BalanceAt(ctx context.Context, accountAddress common.Address, blockNumber *big.Int) (*big.Int, error) { + ret := _m.Called(ctx, accountAddress, blockNumber) + + if len(ret) == 0 { + panic("no return value specified for BalanceAt") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) (*big.Int, error)); ok { + return rf(ctx, accountAddress, blockNumber) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) *big.Int); ok { + r0 = rf(ctx, accountAddress, blockNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok { + r1 = rf(ctx, accountAddress, blockNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BatchCallContext provides a mock function with given fields: ctx, b +func (_m *RPCCLient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { + ret := _m.Called(ctx, b) + + if len(ret) == 0 { + panic("no return value specified for BatchCallContext") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []rpc.BatchElem) error); ok { + r0 = rf(ctx, b) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// BlockByHash provides a mock function with given fields: ctx, hash +func (_m *RPCCLient) BlockByHash(ctx context.Context, hash common.Hash) (*types.Head, error) { + ret := _m.Called(ctx, hash) + + if len(ret) == 0 { + panic("no return value specified for BlockByHash") + } + + var r0 *types.Head + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*types.Head, error)); ok { + return rf(ctx, hash) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) *types.Head); ok { + r0 = rf(ctx, hash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Head) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) error); ok { + r1 = rf(ctx, hash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BlockByHashGeth provides a mock function with given fields: ctx, hash +func (_m *RPCCLient) BlockByHashGeth(ctx context.Context, hash common.Hash) (*coretypes.Block, error) { + ret := _m.Called(ctx, hash) + + if len(ret) == 0 { + panic("no return value specified for BlockByHashGeth") + } + + var r0 *coretypes.Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*coretypes.Block, error)); ok { + return rf(ctx, hash) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) *coretypes.Block); ok { + r0 = rf(ctx, hash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) error); ok { + r1 = rf(ctx, hash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BlockByNumber provides a mock function with given fields: ctx, number +func (_m *RPCCLient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Head, error) { + ret := _m.Called(ctx, number) + + if len(ret) == 0 { + panic("no return value specified for BlockByNumber") + } + + var r0 *types.Head + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) (*types.Head, error)); ok { + return rf(ctx, number) + } + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) *types.Head); ok { + r0 = rf(ctx, number) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Head) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *big.Int) error); ok { + r1 = rf(ctx, number) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BlockByNumberGeth provides a mock function with given fields: ctx, number +func (_m *RPCCLient) BlockByNumberGeth(ctx context.Context, number *big.Int) (*coretypes.Block, error) { + ret := _m.Called(ctx, number) + + if len(ret) == 0 { + panic("no return value specified for BlockByNumberGeth") + } + + var r0 *coretypes.Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) (*coretypes.Block, error)); ok { + return rf(ctx, number) + } + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) *coretypes.Block); ok { + r0 = rf(ctx, number) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *big.Int) error); ok { + r1 = rf(ctx, number) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CallContext provides a mock function with given fields: ctx, result, method, args +func (_m *RPCCLient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { + var _ca []interface{} + _ca = append(_ca, ctx, result, method) + _ca = append(_ca, args...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CallContext") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, interface{}, string, ...interface{}) error); ok { + r0 = rf(ctx, result, method, args...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CallContract provides a mock function with given fields: ctx, msg, blockNumber +func (_m *RPCCLient) CallContract(ctx context.Context, msg interface{}, blockNumber *big.Int) ([]byte, error) { + ret := _m.Called(ctx, msg, blockNumber) + + if len(ret) == 0 { + panic("no return value specified for CallContract") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, interface{}, *big.Int) ([]byte, error)); ok { + return rf(ctx, msg, blockNumber) + } + if rf, ok := ret.Get(0).(func(context.Context, interface{}, *big.Int) []byte); ok { + r0 = rf(ctx, msg, blockNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, interface{}, *big.Int) error); ok { + r1 = rf(ctx, msg, blockNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ChainID provides a mock function with given fields: ctx +func (_m *RPCCLient) ChainID(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ChainID") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ClientVersion provides a mock function with given fields: _a0 +func (_m *RPCCLient) ClientVersion(_a0 context.Context) (string, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for ClientVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (string, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) string); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Close provides a mock function with given fields: +func (_m *RPCCLient) Close() { + _m.Called() +} + +// CodeAt provides a mock function with given fields: ctx, account, blockNumber +func (_m *RPCCLient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { + ret := _m.Called(ctx, account, blockNumber) + + if len(ret) == 0 { + panic("no return value specified for CodeAt") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) ([]byte, error)); ok { + return rf(ctx, account, blockNumber) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) []byte); ok { + r0 = rf(ctx, account, blockNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok { + r1 = rf(ctx, account, blockNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Dial provides a mock function with given fields: ctx +func (_m *RPCCLient) Dial(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Dial") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DialHTTP provides a mock function with given fields: +func (_m *RPCCLient) DialHTTP() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for DialHTTP") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DisconnectAll provides a mock function with given fields: +func (_m *RPCCLient) DisconnectAll() { + _m.Called() +} + +// EstimateGas provides a mock function with given fields: ctx, call +func (_m *RPCCLient) EstimateGas(ctx context.Context, call interface{}) (uint64, error) { + ret := _m.Called(ctx, call) + + if len(ret) == 0 { + panic("no return value specified for EstimateGas") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, interface{}) (uint64, error)); ok { + return rf(ctx, call) + } + if rf, ok := ret.Get(0).(func(context.Context, interface{}) uint64); ok { + r0 = rf(ctx, call) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context, interface{}) error); ok { + r1 = rf(ctx, call) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FilterEvents provides a mock function with given fields: ctx, query +func (_m *RPCCLient) FilterEvents(ctx context.Context, query ethereum.FilterQuery) ([]coretypes.Log, error) { + ret := _m.Called(ctx, query) + + if len(ret) == 0 { + panic("no return value specified for FilterEvents") + } + + var r0 []coretypes.Log + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ethereum.FilterQuery) ([]coretypes.Log, error)); ok { + return rf(ctx, query) + } + if rf, ok := ret.Get(0).(func(context.Context, ethereum.FilterQuery) []coretypes.Log); ok { + r0 = rf(ctx, query) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]coretypes.Log) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ethereum.FilterQuery) error); ok { + r1 = rf(ctx, query) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HeaderByHash provides a mock function with given fields: ctx, h +func (_m *RPCCLient) HeaderByHash(ctx context.Context, h common.Hash) (*coretypes.Header, error) { + ret := _m.Called(ctx, h) + + if len(ret) == 0 { + panic("no return value specified for HeaderByHash") + } + + var r0 *coretypes.Header + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*coretypes.Header, error)); ok { + return rf(ctx, h) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) *coretypes.Header); ok { + r0 = rf(ctx, h) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Header) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) error); ok { + r1 = rf(ctx, h) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HeaderByNumber provides a mock function with given fields: ctx, n +func (_m *RPCCLient) HeaderByNumber(ctx context.Context, n *big.Int) (*coretypes.Header, error) { + ret := _m.Called(ctx, n) + + if len(ret) == 0 { + panic("no return value specified for HeaderByNumber") + } + + var r0 *coretypes.Header + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) (*coretypes.Header, error)); ok { + return rf(ctx, n) + } + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) *coretypes.Header); ok { + r0 = rf(ctx, n) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Header) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *big.Int) error); ok { + r1 = rf(ctx, n) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LINKBalance provides a mock function with given fields: ctx, accountAddress, linkAddress +func (_m *RPCCLient) LINKBalance(ctx context.Context, accountAddress common.Address, linkAddress common.Address) (*assets.Link, error) { + ret := _m.Called(ctx, accountAddress, linkAddress) + + if len(ret) == 0 { + panic("no return value specified for LINKBalance") + } + + var r0 *assets.Link + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address) (*assets.Link, error)); ok { + return rf(ctx, accountAddress, linkAddress) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address) *assets.Link); ok { + r0 = rf(ctx, accountAddress, linkAddress) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*assets.Link) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address, common.Address) error); ok { + r1 = rf(ctx, accountAddress, linkAddress) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LatestBlockHeight provides a mock function with given fields: _a0 +func (_m *RPCCLient) LatestBlockHeight(_a0 context.Context) (*big.Int, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for LatestBlockHeight") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PendingCallContract provides a mock function with given fields: ctx, msg +func (_m *RPCCLient) PendingCallContract(ctx context.Context, msg interface{}) ([]byte, error) { + ret := _m.Called(ctx, msg) + + if len(ret) == 0 { + panic("no return value specified for PendingCallContract") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, interface{}) ([]byte, error)); ok { + return rf(ctx, msg) + } + if rf, ok := ret.Get(0).(func(context.Context, interface{}) []byte); ok { + r0 = rf(ctx, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, interface{}) error); ok { + r1 = rf(ctx, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PendingCodeAt provides a mock function with given fields: ctx, account +func (_m *RPCCLient) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { + ret := _m.Called(ctx, account) + + if len(ret) == 0 { + panic("no return value specified for PendingCodeAt") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address) ([]byte, error)); ok { + return rf(ctx, account) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address) []byte); ok { + r0 = rf(ctx, account) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address) error); ok { + r1 = rf(ctx, account) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PendingSequenceAt provides a mock function with given fields: ctx, addr +func (_m *RPCCLient) PendingSequenceAt(ctx context.Context, addr common.Address) (types.Nonce, error) { + ret := _m.Called(ctx, addr) + + if len(ret) == 0 { + panic("no return value specified for PendingSequenceAt") + } + + var r0 types.Nonce + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address) (types.Nonce, error)); ok { + return rf(ctx, addr) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address) types.Nonce); ok { + r0 = rf(ctx, addr) + } else { + r0 = ret.Get(0).(types.Nonce) + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address) error); ok { + r1 = rf(ctx, addr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SendEmptyTransaction provides a mock function with given fields: ctx, newTxAttempt, seq, gasLimit, fee, fromAddress +func (_m *RPCCLient) SendEmptyTransaction(ctx context.Context, newTxAttempt func(types.Nonce, uint32, *evmassets.Wei, common.Address) (interface{}, error), seq types.Nonce, gasLimit uint32, fee *evmassets.Wei, fromAddress common.Address) (string, error) { + ret := _m.Called(ctx, newTxAttempt, seq, gasLimit, fee, fromAddress) + + if len(ret) == 0 { + panic("no return value specified for SendEmptyTransaction") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, func(types.Nonce, uint32, *evmassets.Wei, common.Address) (interface{}, error), types.Nonce, uint32, *evmassets.Wei, common.Address) (string, error)); ok { + return rf(ctx, newTxAttempt, seq, gasLimit, fee, fromAddress) + } + if rf, ok := ret.Get(0).(func(context.Context, func(types.Nonce, uint32, *evmassets.Wei, common.Address) (interface{}, error), types.Nonce, uint32, *evmassets.Wei, common.Address) string); ok { + r0 = rf(ctx, newTxAttempt, seq, gasLimit, fee, fromAddress) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context, func(types.Nonce, uint32, *evmassets.Wei, common.Address) (interface{}, error), types.Nonce, uint32, *evmassets.Wei, common.Address) error); ok { + r1 = rf(ctx, newTxAttempt, seq, gasLimit, fee, fromAddress) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SendTransaction provides a mock function with given fields: ctx, tx +func (_m *RPCCLient) SendTransaction(ctx context.Context, tx *coretypes.Transaction) error { + ret := _m.Called(ctx, tx) + + if len(ret) == 0 { + panic("no return value specified for SendTransaction") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *coretypes.Transaction) error); ok { + r0 = rf(ctx, tx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SequenceAt provides a mock function with given fields: ctx, accountAddress, blockNumber +func (_m *RPCCLient) SequenceAt(ctx context.Context, accountAddress common.Address, blockNumber *big.Int) (types.Nonce, error) { + ret := _m.Called(ctx, accountAddress, blockNumber) + + if len(ret) == 0 { + panic("no return value specified for SequenceAt") + } + + var r0 types.Nonce + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) (types.Nonce, error)); ok { + return rf(ctx, accountAddress, blockNumber) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) types.Nonce); ok { + r0 = rf(ctx, accountAddress, blockNumber) + } else { + r0 = ret.Get(0).(types.Nonce) + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok { + r1 = rf(ctx, accountAddress, blockNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SetAliveLoopSub provides a mock function with given fields: _a0 +func (_m *RPCCLient) SetAliveLoopSub(_a0 commontypes.Subscription) { + _m.Called(_a0) +} + +// SimulateTransaction provides a mock function with given fields: ctx, tx +func (_m *RPCCLient) SimulateTransaction(ctx context.Context, tx *coretypes.Transaction) error { + ret := _m.Called(ctx, tx) + + if len(ret) == 0 { + panic("no return value specified for SimulateTransaction") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *coretypes.Transaction) error); ok { + r0 = rf(ctx, tx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Subscribe provides a mock function with given fields: ctx, channel, args +func (_m *RPCCLient) Subscribe(ctx context.Context, channel chan<- *types.Head, args ...interface{}) (commontypes.Subscription, error) { + var _ca []interface{} + _ca = append(_ca, ctx, channel) + _ca = append(_ca, args...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Subscribe") + } + + var r0 commontypes.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, chan<- *types.Head, ...interface{}) (commontypes.Subscription, error)); ok { + return rf(ctx, channel, args...) + } + if rf, ok := ret.Get(0).(func(context.Context, chan<- *types.Head, ...interface{}) commontypes.Subscription); ok { + r0 = rf(ctx, channel, args...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(commontypes.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, chan<- *types.Head, ...interface{}) error); ok { + r1 = rf(ctx, channel, args...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SubscribeFilterLogs provides a mock function with given fields: ctx, q, ch +func (_m *RPCCLient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- coretypes.Log) (ethereum.Subscription, error) { + ret := _m.Called(ctx, q, ch) + + if len(ret) == 0 { + panic("no return value specified for SubscribeFilterLogs") + } + + var r0 ethereum.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ethereum.FilterQuery, chan<- coretypes.Log) (ethereum.Subscription, error)); ok { + return rf(ctx, q, ch) + } + if rf, ok := ret.Get(0).(func(context.Context, ethereum.FilterQuery, chan<- coretypes.Log) ethereum.Subscription); ok { + r0 = rf(ctx, q, ch) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ethereum.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ethereum.FilterQuery, chan<- coretypes.Log) error); ok { + r1 = rf(ctx, q, ch) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SubscribersCount provides a mock function with given fields: +func (_m *RPCCLient) SubscribersCount() int32 { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SubscribersCount") + } + + var r0 int32 + if rf, ok := ret.Get(0).(func() int32); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int32) + } + + return r0 +} + +// SuggestGasPrice provides a mock function with given fields: ctx +func (_m *RPCCLient) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SuggestGasPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SuggestGasTipCap provides a mock function with given fields: ctx +func (_m *RPCCLient) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SuggestGasTipCap") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TokenBalance provides a mock function with given fields: ctx, accountAddress, tokenAddress +func (_m *RPCCLient) TokenBalance(ctx context.Context, accountAddress common.Address, tokenAddress common.Address) (*big.Int, error) { + ret := _m.Called(ctx, accountAddress, tokenAddress) + + if len(ret) == 0 { + panic("no return value specified for TokenBalance") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address) (*big.Int, error)); ok { + return rf(ctx, accountAddress, tokenAddress) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address) *big.Int); ok { + r0 = rf(ctx, accountAddress, tokenAddress) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address, common.Address) error); ok { + r1 = rf(ctx, accountAddress, tokenAddress) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TransactionByHash provides a mock function with given fields: ctx, txHash +func (_m *RPCCLient) TransactionByHash(ctx context.Context, txHash common.Hash) (*coretypes.Transaction, error) { + ret := _m.Called(ctx, txHash) + + if len(ret) == 0 { + panic("no return value specified for TransactionByHash") + } + + var r0 *coretypes.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*coretypes.Transaction, error)); ok { + return rf(ctx, txHash) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) *coretypes.Transaction); ok { + r0 = rf(ctx, txHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) error); ok { + r1 = rf(ctx, txHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TransactionReceipt provides a mock function with given fields: ctx, txHash +func (_m *RPCCLient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + ret := _m.Called(ctx, txHash) + + if len(ret) == 0 { + panic("no return value specified for TransactionReceipt") + } + + var r0 *types.Receipt + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*types.Receipt, error)); ok { + return rf(ctx, txHash) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) *types.Receipt); ok { + r0 = rf(ctx, txHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Receipt) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) error); ok { + r1 = rf(ctx, txHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TransactionReceiptGeth provides a mock function with given fields: ctx, txHash +func (_m *RPCCLient) TransactionReceiptGeth(ctx context.Context, txHash common.Hash) (*coretypes.Receipt, error) { + ret := _m.Called(ctx, txHash) + + if len(ret) == 0 { + panic("no return value specified for TransactionReceiptGeth") + } + + var r0 *coretypes.Receipt + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*coretypes.Receipt, error)); ok { + return rf(ctx, txHash) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) *coretypes.Receipt); ok { + r0 = rf(ctx, txHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Receipt) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) error); ok { + r1 = rf(ctx, txHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UnsubscribeAllExceptAliveLoop provides a mock function with given fields: +func (_m *RPCCLient) UnsubscribeAllExceptAliveLoop() { + _m.Called() +} + +// NewRPCCLient creates a new instance of RPCCLient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewRPCCLient(t interface { + mock.TestingT + Cleanup(func()) +}) *RPCCLient { + mock := &RPCCLient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 54656cf1d3e..29c5d8fbb8b 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -42,6 +42,7 @@ type RPCCLient interface { *evmtypes.Receipt, *assets.Wei, *evmtypes.Head, + rpc.BatchElem, ] BlockByHashGeth(ctx context.Context, hash common.Hash) (b *types.Block, err error) BlockByNumberGeth(ctx context.Context, number *big.Int) (b *types.Block, err error) @@ -315,24 +316,20 @@ func (r *rpcClient) CallContext(ctx context.Context, result interface{}, method return err } -func (r *rpcClient) BatchCallContext(ctx context.Context, b []any) error { +func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) if err != nil { return err } - batch := make([]rpc.BatchElem, len(b)) - for i, arg := range b { - batch[i] = arg.(rpc.BatchElem) - } defer cancel() lggr := r.newRqLggr().With("nBatchElems", len(b), "batchElems", b) lggr.Trace("RPC call: evmclient.Client#BatchCallContext") start := time.Now() if http != nil { - err = r.wrapHTTP(http.rpc.BatchCallContext(ctx, batch)) + err = r.wrapHTTP(http.rpc.BatchCallContext(ctx, b)) } else { - err = r.wrapWS(ws.rpc.BatchCallContext(ctx, batch)) + err = r.wrapWS(ws.rpc.BatchCallContext(ctx, b)) } duration := time.Since(start) diff --git a/core/chains/evm/client/send_only_node_test.go b/core/chains/evm/client/send_only_node_test.go index c2fdad06ec1..61db09a448c 100644 --- a/core/chains/evm/client/send_only_node_test.go +++ b/core/chains/evm/client/send_only_node_test.go @@ -20,7 +20,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -37,7 +36,7 @@ func TestNewSendOnlyNode(t *testing.T) { name := "TestNewSendOnlyNode" chainID := testutils.NewRandomEVMChainID() - node := evmclient.NewSendOnlyNode(lggr, *url, name, chainID) + node := client.NewSendOnlyNode(lggr, *url, name, chainID) assert.NotNil(t, node) // Must contain name & url with redacted password @@ -54,7 +53,7 @@ func TestStartSendOnlyNode(t *testing.T) { r := chainIDResp{chainID.Int64(), nil} url := r.newHTTPServer(t) lggr, observedLogs := logger.TestObserved(t, zap.WarnLevel) - s := evmclient.NewSendOnlyNode(lggr, *url, t.Name(), chainID) + s := client.NewSendOnlyNode(lggr, *url, t.Name(), chainID) defer func() { assert.NoError(t, s.Close()) }() err := s.Start(testutils.Context(t)) assert.NoError(t, err) // No errors expected @@ -67,7 +66,7 @@ func TestStartSendOnlyNode(t *testing.T) { chainID := testutils.FixtureChainID r := chainIDResp{chainID.Int64(), nil} url := r.newHTTPServer(t) - s := evmclient.NewSendOnlyNode(lggr, *url, t.Name(), testutils.FixtureChainID) + s := client.NewSendOnlyNode(lggr, *url, t.Name(), testutils.FixtureChainID) defer func() { assert.NoError(t, s.Close()) }() err := s.Start(testutils.Context(t)) @@ -80,7 +79,7 @@ func TestStartSendOnlyNode(t *testing.T) { t.Parallel() lggr, observedLogs := logger.TestObserved(t, zap.WarnLevel) invalidURL := url.URL{Scheme: "some rubbish", Host: "not a valid host"} - s := evmclient.NewSendOnlyNode(lggr, invalidURL, t.Name(), testutils.FixtureChainID) + s := client.NewSendOnlyNode(lggr, invalidURL, t.Name(), testutils.FixtureChainID) defer func() { assert.NoError(t, s.Close()) }() err := s.Start(testutils.Context(t)) @@ -112,10 +111,10 @@ func TestSendTransaction(t *testing.T) { chainID := testutils.FixtureChainID lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) url := testutils.MustParseURL(t, "http://place.holder") - s := evmclient.NewSendOnlyNode(lggr, + s := client.NewSendOnlyNode(lggr, *url, t.Name(), - testutils.FixtureChainID).(evmclient.TestableSendOnlyNode) + testutils.FixtureChainID).(client.TestableSendOnlyNode) require.NotNil(t, s) signedTx := createSignedTx(t, chainID, 1, []byte{1, 2, 3}) @@ -139,10 +138,10 @@ func TestBatchCallContext(t *testing.T) { lggr := logger.Test(t) chainID := testutils.FixtureChainID url := testutils.MustParseURL(t, "http://place.holder") - s := evmclient.NewSendOnlyNode( + s := client.NewSendOnlyNode( lggr, *url, "TestBatchCallContext", - chainID).(evmclient.TestableSendOnlyNode) + chainID).(client.TestableSendOnlyNode) blockNum := hexutil.EncodeBig(big.NewInt(42)) req := []rpc.BatchElem{ From 2b6cf28c5b86f6d5983e9cd29709a56c9fac1d8c Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Fri, 23 Feb 2024 16:47:00 +0100 Subject: [PATCH 87/98] bump pg to 15.6, add awscli to nix (#12157) --- charts/chainlink-cluster/values.yaml | 1 + shell.nix | 1 + 2 files changed, 2 insertions(+) diff --git a/charts/chainlink-cluster/values.yaml b/charts/chainlink-cluster/values.yaml index fefb819cf2f..67350af68c4 100644 --- a/charts/chainlink-cluster/values.yaml +++ b/charts/chainlink-cluster/values.yaml @@ -99,6 +99,7 @@ db: runAsUser: 999 runAsGroup: 999 stateful: false + image: "postgres:15.6" resources: requests: cpu: 1 diff --git a/shell.nix b/shell.nix index 7d219553368..44a6b6ab2c1 100644 --- a/shell.nix +++ b/shell.nix @@ -32,6 +32,7 @@ mkShell { jq # deployment + awscli2 devspace kubectl kubernetes-helm From 9a20034a39c8acca867a1fc061b1223288641ea9 Mon Sep 17 00:00:00 2001 From: Lei Date: Fri, 23 Feb 2024 10:33:01 -0800 Subject: [PATCH 88/98] use the block number provided or derived to run basic checks (#12086) --- core/scripts/chaincli/handler/debug.go | 85 ++++++++++++++++---------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/core/scripts/chaincli/handler/debug.go b/core/scripts/chaincli/handler/debug.go index 8b06937fc2c..4825499601d 100644 --- a/core/scripts/chaincli/handler/debug.go +++ b/core/scripts/chaincli/handler/debug.go @@ -98,50 +98,27 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { failCheckArgs("invalid upkeep ID", nil) } } - // get upkeep info + + // get trigger type, trigger type is immutable after its first setup triggerType, err := keeperRegistry21.GetTriggerType(latestCallOpts, upkeepID) if err != nil { failUnknown("failed to get trigger type: ", err) } - upkeepInfo, err := keeperRegistry21.GetUpkeep(latestCallOpts, upkeepID) - if err != nil { - failUnknown("failed to get trigger type: ", err) - } - minBalance, err := keeperRegistry21.GetMinBalance(latestCallOpts, upkeepID) - if err != nil { - failUnknown("failed to get min balance: ", err) - } - // do basic sanity checks - if (upkeepInfo.Target == gethcommon.Address{}) { - failCheckArgs("this upkeep does not exist on this registry", nil) - } - addLink("upkeep link", common.UpkeepLink(chainID, upkeepID)) - addLink("upkeep contract address", common.ContractExplorerLink(chainID, upkeepInfo.Target)) - if upkeepInfo.Paused { - resolveIneligible("upkeep is paused") - } - if upkeepInfo.MaxValidBlocknumber != math.MaxUint32 { - resolveIneligible("upkeep is cancelled") - } - message("upkeep is active (not paused or cancelled)") - if upkeepInfo.Balance.Cmp(minBalance) == -1 { - resolveIneligible("minBalance is < upkeep balance") - } - message("upkeep is funded above the min balance") - if bigmath.Div(bigmath.Mul(bigmath.Sub(upkeepInfo.Balance, minBalance), big.NewInt(100)), minBalance).Cmp(big.NewInt(5)) == -1 { - warning("upkeep balance is < 5% larger than minBalance") - } + // local state for pipeline results + var upkeepInfo iregistry21.KeeperRegistryBase21UpkeepInfo var checkResult iregistry21.CheckUpkeep var blockNum uint64 var performData []byte var workID [32]byte var trigger ocr2keepers.Trigger upkeepNeeded := false - // check upkeep + + // run basic checks and check upkeep by trigger type if triggerType == ConditionTrigger { message("upkeep identified as conditional trigger") + // validate inputs if len(args) > 1 { // if a block number is provided, use that block for both checkUpkeep and simulatePerformUpkeep blockNum, err = strconv.ParseUint(args[1], 10, 64) @@ -154,6 +131,9 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { triggerCallOpts = latestCallOpts } + // do basic checks + upkeepInfo = getUpkeepInfoAndRunBasicChecks(keeperRegistry21, triggerCallOpts, upkeepID, chainID) + var tmpCheckResult iregistry21.CheckUpkeep0 tmpCheckResult, err = keeperRegistry21.CheckUpkeep0(triggerCallOpts, upkeepID) if err != nil { @@ -214,6 +194,7 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { trigger = mustAutomationTrigger(txHash, logIndex, blockNum, receipt.BlockHash) workID = mustUpkeepWorkID(upkeepID, trigger) message(fmt.Sprintf("workID computed: %s", hex.EncodeToString(workID[:]))) + var hasKey bool hasKey, err = keeperRegistry21.HasDedupKey(latestCallOpts, workID) if err != nil { @@ -223,6 +204,10 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { resolveIneligible("upkeep was already performed") } triggerCallOpts = &bind.CallOpts{Context: ctx, BlockNumber: big.NewInt(receipt.BlockNumber.Int64())} + + // do basic checks + upkeepInfo = getUpkeepInfoAndRunBasicChecks(keeperRegistry21, triggerCallOpts, upkeepID, chainID) + var rawTriggerConfig []byte rawTriggerConfig, err = keeperRegistry21.GetUpkeepTriggerConfig(triggerCallOpts, upkeepID) if err != nil { @@ -265,10 +250,10 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { } else { resolveIneligible(fmt.Sprintf("invalid trigger type: %d", triggerType)) } - upkeepNeeded, performData = checkResult.UpkeepNeeded, checkResult.PerformData + upkeepNeeded, performData = checkResult.UpkeepNeeded, checkResult.PerformData if checkResult.UpkeepFailureReason != 0 { - message(fmt.Sprintf("checkUpkeep failed with UpkeepFailureReason %s", getCheckUpkeepFailureReason(checkResult.UpkeepFailureReason))) + message(fmt.Sprintf("checkUpkeep reverted with UpkeepFailureReason %s", getCheckUpkeepFailureReason(checkResult.UpkeepFailureReason))) } // handle data streams lookup @@ -316,7 +301,7 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { } if k.cfg.DataStreamsLegacyURL == "" || k.cfg.DataStreamsURL == "" || k.cfg.DataStreamsID == "" || k.cfg.DataStreamsKey == "" { - failCheckConfig("Data streams configs not set properly, check your DATA_STREAMS_LEGACY_URL, DATA_STREAMS_URL, DATA_STREAMS_ID and DATA_STREAMS_KEY", nil) + failCheckConfig("Data streams configs not set properly for this network, check your DATA_STREAMS settings in .env", nil) } // do mercury request @@ -394,6 +379,40 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { } } +func getUpkeepInfoAndRunBasicChecks(keeperRegistry21 *iregistry21.IKeeperRegistryMaster, callOpts *bind.CallOpts, upkeepID *big.Int, chainID int64) iregistry21.KeeperRegistryBase21UpkeepInfo { + // get upkeep info + upkeepInfo, err := keeperRegistry21.GetUpkeep(callOpts, upkeepID) + if err != nil { + failUnknown("failed to get upkeep info: ", err) + } + // get min balance + minBalance, err := keeperRegistry21.GetMinBalance(callOpts, upkeepID) + if err != nil { + failUnknown("failed to get min balance: ", err) + } + // do basic sanity checks + if (upkeepInfo.Target == gethcommon.Address{}) { + failCheckArgs("this upkeep does not exist on this registry", nil) + } + addLink("upkeep link", common.UpkeepLink(chainID, upkeepID)) + addLink("upkeep contract address", common.ContractExplorerLink(chainID, upkeepInfo.Target)) + if upkeepInfo.Paused { + resolveIneligible("upkeep is paused") + } + if upkeepInfo.MaxValidBlocknumber != math.MaxUint32 { + resolveIneligible("upkeep is canceled") + } + message("upkeep is active (not paused or canceled)") + if upkeepInfo.Balance.Cmp(minBalance) == -1 { + resolveIneligible("minBalance is < upkeep balance") + } + message("upkeep is funded above the min balance") + if bigmath.Div(bigmath.Mul(bigmath.Sub(upkeepInfo.Balance, minBalance), big.NewInt(100)), minBalance).Cmp(big.NewInt(5)) == -1 { + warning("upkeep balance is < 5% larger than minBalance") + } + return upkeepInfo +} + func getCheckUpkeepFailureReason(reasonIndex uint8) string { // Copied from KeeperRegistryBase2_1.sol reasonStrings := []string{ From 63d4bdffc8fd17e79075626acb27bec8517ffa09 Mon Sep 17 00:00:00 2001 From: Lei Date: Fri, 23 Feb 2024 15:27:18 -0800 Subject: [PATCH 89/98] Cla debugger docs (#12160) * Conditional upkeep additions * Revert "Conditional upkeep additions" This reverts commit c549065a97e5b70332c1af8e47040b88d43a995b. modified: core/scripts/chaincli/DEBUGGING.md deleted: core/scripts/chaincli/images/env_file_example.png deleted: core/scripts/chaincli/images/insufficient_check_gas.png deleted: core/scripts/chaincli/images/insufficient_perform_gas.png deleted: core/scripts/chaincli/images/tenderly_out_of_check_gas.png deleted: core/scripts/chaincli/images/upkeep_paused.png * Conditional upkeep additions * Update DEBUGGING.md fix images * Edit pass 1 * Edit pass 2 * log trigger * update readme to clarify go version and sanity check details (#12084) --------- Co-authored-by: De Clercq Wentzel <10665586+wentzeld@users.noreply.github.com> Co-authored-by: Crystal Gomes --- core/scripts/chaincli/DEBUGGING.md | 87 +++++++++++++----- .../chaincli/images/env_file_example.png | Bin 0 -> 296424 bytes .../chaincli/images/fix by increasing .png | Bin 0 -> 389387 bytes .../images/insufficient_check_gas.png | Bin 0 -> 286119 bytes .../images/insufficient_perform_gas.png | Bin 0 -> 359464 bytes .../images/log_trigger_log_doesnt_match.png | Bin 0 -> 383776 bytes .../images/tenderly_out_of_check_gas.png | Bin 0 -> 790861 bytes .../chaincli/images/txnHash_and_index.png | Bin 0 -> 141715 bytes .../chaincli/images/upkeep_doesnt_exist.png | Bin 0 -> 77919 bytes .../scripts/chaincli/images/upkeep_paused.png | Bin 0 -> 124735 bytes 10 files changed, 63 insertions(+), 24 deletions(-) create mode 100644 core/scripts/chaincli/images/env_file_example.png create mode 100644 core/scripts/chaincli/images/fix by increasing .png create mode 100644 core/scripts/chaincli/images/insufficient_check_gas.png create mode 100644 core/scripts/chaincli/images/insufficient_perform_gas.png create mode 100644 core/scripts/chaincli/images/log_trigger_log_doesnt_match.png create mode 100644 core/scripts/chaincli/images/tenderly_out_of_check_gas.png create mode 100644 core/scripts/chaincli/images/txnHash_and_index.png create mode 100644 core/scripts/chaincli/images/upkeep_doesnt_exist.png create mode 100644 core/scripts/chaincli/images/upkeep_paused.png diff --git a/core/scripts/chaincli/DEBUGGING.md b/core/scripts/chaincli/DEBUGGING.md index 6466a40fc31..54bfbe44072 100644 --- a/core/scripts/chaincli/DEBUGGING.md +++ b/core/scripts/chaincli/DEBUGGING.md @@ -1,37 +1,46 @@ -## Automation Debugging Script +# Automation Debugging Script -### Context +Use this script to debug and diagnose possible issues with registered upkeeps in Automation v2 registries. The script can debug custom logic upkeeps, log-trigger upkeeps, and upkeeps that use StreamsLookup. -The debugging script is a tool within ChainCLI designed to facilitate the debugging of upkeeps in Automation v21, covering both conditional and log-based scenarios. - -### Setup +## Setup Before starting, you will need: -1. Git clone this chainlink [repo](https://github.com/smartcontractkit/chainlink) -2. A working [Go](https://go.dev/doc/install) installation -2. Change directory to `core/scripts/chaincli` and create a `.env` file based on the example `.env.debugging.example` -### Configuration in `.env` File +- A registered [upkeep](https://docs.chain.link/chainlink-automation/overview/getting-started) +- A working [Go](https://go.dev/doc/install) installation, please use this Go [version](https://github.com/smartcontractkit/chainlink/blob/develop/go.mod#L3) + +1. Clone the chainlink [repo](https://github.com/smartcontractkit/chainlink) and navigate to the `core/scripts/chaincli` + directory: + ``` + git clone https://github.com/smartcontractkit/chainlink.git && cd chainlink/core/scripts/chaincli + ``` +1. Create a `.env` file based on the example `.env.debugging.example`: + + ``` + cp .env.debugging.example .env + ``` -#### Mandatory Fields +## Configuration -Ensure the following fields are provided in your `.env` file: +Fill in the values for these mandatory fields in your `.env` file: -- `NODE_URL`: Archival node URL -- `KEEPER_REGISTRY_ADDRESS`: Address of the Keeper Registry contract. Refer to the [Supported Networks](https://docs.chain.link/chainlink-automation/overview/supported-networks#configurations) doc for addresses. +- `NODE_URL`: Archival node URL for the network to "simulate" the upkeep. Use your own node or get an endpoint from Alchemy or Infura. +- `KEEPER_REGISTRY_ADDRESS`: Address of the registry where your upkeep is registered. Refer to the [Supported Networks](https://docs.chain.link/chainlink-automation/overview/supported-networks#configurations) doc for registry addresses. + + For example + ![Example_ENV_file](/core/scripts/chaincli/images/env_file_example.png "Example .ENV file") -#### Optional Fields (Streams Lookup) +#### StreamsLookup (optional) -If your targeted upkeep involves streams lookup, please provide the following details. If you are using Data Streams v0.3 (which is likely), only provide the DATA_STREAMS_URL. The DATA_STREAMS_LEGACY_URL is specifically for Data Streams v0.2. +If your targeted upkeep involves StreamsLookup, please provide the following details. If you are using Data Streams v0.3 (which is likely), only provide the `DATA_STREAMS_URL`. Ignore `DATA_STREAMS_LEGACY_URL`. - `DATA_STREAMS_ID` - `DATA_STREAMS_KEY` -- `DATA_STREAMS_LEGACY_URL` - `DATA_STREAMS_URL` -#### Optional Fields (Tenderly Integration) +#### Tenderly integration (optional) -For detailed transaction simulation logs, set up Tenderly credentials. Refer to the [Tenderly Documentation](https://docs.tenderly.co/other/platform-access/how-to-generate-api-access-tokens) for creating an API key, account name, and project name. +For detailed transaction simulation logs, set up Tenderly credentials. Refer to the [Tenderly documentation](https://docs.tenderly.co/other/platform-access/how-to-generate-api-access-tokens) to learn how to create an API key, account name, and project name on Tenderly. - `TENDERLY_KEY` - `TENDERLY_ACCOUNT_NAME` @@ -41,11 +50,12 @@ For detailed transaction simulation logs, set up Tenderly credentials. Refer to Execute the following command based on your upkeep type: -- For conditional upkeep, if a block number is given we use that block, otherwise we use the latest block: +- For custom logic: ```bash go run main.go keeper debug UPKEEP_ID [OPTIONAL BLOCK_NUMBER] ``` + If you don't specify a block number, the debugging script uses the latest block. - For log trigger upkeep: @@ -53,13 +63,13 @@ Execute the following command based on your upkeep type: go run main.go keeper debug UPKEEP_ID TX_HASH LOG_INDEX ``` -### Checks Performed by the Debugging Script +### What the debugging script checks -1. **Fetch and Sanity Check Upkeep:** +1. The script runs these basic checks on all upkeeps based on the TX_HASH or BLOCK_NUMBER (if provided) - Verify upkeep status: active, paused, or canceled - Check upkeep balance -2. **For Conditional Upkeep:** +2. **For Custom Logic Upkeep:** - Check conditional upkeep - Simulate `performUpkeep` @@ -74,7 +84,7 @@ Execute the following command based on your upkeep type: - Simulate `performUpkeep` -### Examples +#### Examples - Eligible and log trigger based and using mercury lookup v0.3: ```bash @@ -92,4 +102,33 @@ Execute the following command based on your upkeep type: ```bash go run main.go keeper debug 5591498142036749453487419299781783197030971023186134955311257372668222176389 0xc0686ae85d2a7a976ef46df6c613517b9fd46f23340ac583be4e44f5c8b7a186 1 ``` ---- \ No newline at end of file +### Common issues with Upkeeps and how to resolve them + +#### All upkeeps + +- Upkeep is underfunded + - Underfunded upkeeps will not perform. Fund your upkeep in the Automation [app](https://automation.chain.link/) +- Upkeep is paused + - Unpause your upkeep in the Automation [app](https://automation.chain.link/) +- Insufficient check gas + - There is a limit of 10,000,000 (as per Automation v2) on the amount of gas that can be used to "simulate" your `checkUpkeep` function. + - To diagnose if your upkeep is running out of check gas, you will need to enable the Tenderly options above and then open the simulation link once you run the script. + - ![Insufficient Check Gas](/core/scripts/chaincli/images/insufficient_check_gas.png "Open the Tenderly simulation and switch to debug mode") + - ![Out of Gas](/core/scripts/chaincli/images/tenderly_out_of_check_gas.png "Tenderly shows checkUpkeeps has consumed all available gas and is now out of gas") + - You will need to adjust your checkUpkeep to consume less gas than the limit +- Insufficient perform gas + - Your upkeep's perform transaction uses more gas than you specified + - ![Insufficient Perform Gas](/core/scripts/chaincli/images/insufficient_perform_gas.png "Insufficient perform gas") + - Use the Automation [app](https://automation.chain.link/) and increase the gas limit of your upkeep + - The maximum supported perform gas is 5,000,000 + +#### Log-trigger upkeeps + +Log-trigger upkeeps require that you also supply the txn hash containing the log and the index of the log that would have triggered your upkeep. You can find both in the block scanner of the chain in question. For example the txn hash is in the URL and the block number in the green circle on the left. +![Txn Hash and Log Index Number](/core/scripts/chaincli/images/txnHash_and_index.png "Find txn hash and log index in block scanner") + +- Log doesn't match the trigger config + - Log-trigger upkeeps come with a filter (aka trigger config), if the emitted log doesn't match the filter, the upkeep won't run. + - ![Log doesn't match](/core/scripts/chaincli/images/log_trigger_log_doesnt_match.png "Log doesn't match trigger config") + - Use the Automation [app](https://automation.chain.link/) to update the upkeep's trigger config to match the log. +--- diff --git a/core/scripts/chaincli/images/env_file_example.png b/core/scripts/chaincli/images/env_file_example.png new file mode 100644 index 0000000000000000000000000000000000000000..a002e9d31b0eeae751b248133fb996bd4c0962db GIT binary patch literal 296424 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�>jDQ;O@jh1mSlSyw3MARZ3 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
  • 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

      wUrAAE*O?v(wk@fct`U_Eg0()1MC0w}z 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

      T-NAmCtQ|!rnII8$GL`<8?VpB?eJA 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 literal 0 HcmV?d00001 diff --git a/core/scripts/chaincli/images/insufficient_perform_gas.png b/core/scripts/chaincli/images/insufficient_perform_gas.png new file mode 100644 index 0000000000000000000000000000000000000000..1aeeadd0cad5516a4d9c51d9d6f5b9cde0c6aa08 GIT binary patch literal 359464 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

  • |&9@`AEU3W-Z+?lr#9bzI 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�R^3$q^9AtUNSRFb>3dH(0)ABTOrQmep%USX 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