From a65e2386cf6e3212b727d8c1cf013753456a01a5 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Fri, 1 Sep 2023 19:35:15 +0300 Subject: [PATCH 01/88] Tt 562 functions + gateway performance tests, chaos suite (#10397) * TT-562 s4 tdh2 setup and tests * chaos suite * update deps * fix wrapper generation * encrypt s4 secrets * bump godeltaprof for go 1.21.0 * uniq IDs for secrets * gateway test for secrets_set * gateway test for secrets_set/secrets_list * more throughput through batch calls * update go.mod * load modes for gateway * finalize docs * decouple from env * update README * update go.sum --- .../testhelpers/FunctionsLoadTestClient.sol | 58 ++++- .../functions_load_test_client.go | 206 +++++++++++----- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- integration-tests/chaos/functions/full.yaml | 232 ++++++++++++++++++ .../contracts/contract_models.go | 6 +- .../contracts/ethereum_contracts.go | 76 +++++- integration-tests/go.mod | 10 +- integration-tests/go.sum | 14 +- integration-tests/load/functions/README.md | 45 +++- integration-tests/load/functions/config.go | 67 ++--- integration-tests/load/functions/config.toml | 51 ++-- .../load/functions/functions_test.go | 79 +++--- integration-tests/load/functions/gateway.go | 227 +++++++++++++++++ .../load/functions/gateway_gun.go | 110 +++++++++ .../load/functions/gateway_test.go | 73 ++++++ .../load/functions/onchain_monitoring.go | 61 +++++ .../load/functions/{gun.go => request_gun.go} | 17 +- integration-tests/load/functions/setup.go | 163 ++++++++++-- integration-tests/networks/known_networks.go | 6 +- 21 files changed, 1297 insertions(+), 212 deletions(-) create mode 100644 integration-tests/chaos/functions/full.yaml create mode 100644 integration-tests/load/functions/gateway.go create mode 100644 integration-tests/load/functions/gateway_gun.go create mode 100644 integration-tests/load/functions/gateway_test.go create mode 100644 integration-tests/load/functions/onchain_monitoring.go rename integration-tests/load/functions/{gun.go => request_gun.go} (65%) diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol index 7aa46e9ba06..047b45e9562 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol @@ -13,11 +13,13 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { uint32 public constant MAX_CALLBACK_GAS = 70_000; - bytes32 public s_lastRequestId; - bytes32 public s_lastResponse; - bytes32 public s_lastError; - uint32 public s_lastResponseLength; - uint32 public s_lastErrorLength; + bytes32 public lastRequestID; + bytes32 public lastResponse; + bytes32 public lastError; + uint32 public totalRequests; + uint32 public totalEmptyResponses; + uint32 public totalSucceededResponses; + uint32 public totalFailedResponses; constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {} @@ -29,6 +31,7 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { * @param subscriptionId Billing ID */ function sendRequest( + uint32 times, string calldata source, bytes calldata encryptedSecretsReferences, string[] calldata args, @@ -39,7 +42,33 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { req.initializeRequestForInlineJavaScript(source); if (encryptedSecretsReferences.length > 0) req.addSecretsReference(encryptedSecretsReferences); if (args.length > 0) req.setArgs(args); - s_lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId); + uint i = 0; + for (i = 0; i < times; i++) { + lastRequestID = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId); + totalRequests += 1; + } + } + + function resetStats() external onlyOwner { + lastRequestID = ""; + lastResponse = ""; + lastError = ""; + totalRequests = 0; + totalSucceededResponses = 0; + totalFailedResponses = 0; + totalEmptyResponses = 0; + } + + function getStats() public view onlyOwner returns (bytes32, bytes32, bytes32, uint32, uint32, uint32, uint32) { + return ( + lastRequestID, + lastResponse, + lastError, + totalRequests, + totalSucceededResponses, + totalFailedResponses, + totalEmptyResponses + ); } /** @@ -51,11 +80,18 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { */ function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override { // Save only the first 32 bytes of response/error to always fit within MAX_CALLBACK_GAS - s_lastRequestId = requestId; - s_lastResponse = bytesToBytes32(response); - s_lastResponseLength = uint32(response.length); - s_lastError = bytesToBytes32(err); - s_lastErrorLength = uint32(err.length); + lastRequestID = requestId; + lastResponse = bytesToBytes32(response); + lastError = bytesToBytes32(err); + if (response.length == 0) { + totalEmptyResponses += 1; + } + if (err.length != 0) { + totalFailedResponses += 1; + } + if (response.length != 0 && err.length == 0) { + totalSucceededResponses += 1; + } } function bytesToBytes32(bytes memory b) private pure returns (bytes32 out) { diff --git a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go index 90d1ac33533..d4f8d1fc7e6 100644 --- a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go +++ b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go @@ -31,8 +31,8 @@ var ( ) var FunctionsLoadTestClientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001a3d38038062001a3d833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051611868620001d5600039600081816101c601526109f101526118686000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112b4565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e1610143366004611387565b61022d565b6101176201117081565b6100e1610347565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e161019936600461146b565b610449565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61022883838361045d565b505050565b6102356104f2565b61027e6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6102c089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105759050565b85156103085761030887878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105869050565b83156103225761032261031b85876114a1565b82906105d0565b61033961032e82610613565b8462011170856109ec565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104516104f2565b61045a81610acb565b50565b600283905561046b82610bc0565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104ad81610bc0565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c4565b565b6105828260008084610c42565b5050565b80516000036105c1576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b805160000361060b576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b60606000610622610100610cd9565b905061066c6040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610cfa90919063ffffffff16565b825161068a90600281111561068357610683611539565b8290610d13565b60408051808201909152600881527f6c616e677561676500000000000000000000000000000000000000000000000060208201526106c9908290610cfa565b60408301516106e090801561068357610683611539565b60408051808201909152600681527f736f757263650000000000000000000000000000000000000000000000000000602082015261071f908290610cfa565b606083015161072f908290610cfa565b60a083015151156107895760408051808201909152601081527f726571756573745369676e6174757265000000000000000000000000000000006020820152610779908290610cfa565b60a0830151610789908290610d48565b60c083015151156108365760408051808201909152600481527f617267730000000000000000000000000000000000000000000000000000000060208201526107d3908290610cfa565b6107dc81610d55565b60005b8360c001515181101561082c5761081c8460c00151828151811061080557610805611568565b602002602001015183610cfa90919063ffffffff16565b610825816115c6565b90506107df565b5061083681610d79565b608083015151156109375760008360200151600281111561085957610859611539565b03610890576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e000000000000000000000000000000000060208201526108cf908290610cfa565b6108e88360200151600281111561068357610683611539565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610927908290610cfa565b6080830151610937908290610d48565b60e083015151156109e45760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610981908290610cfa565b61098a81610d55565b60005b8360e00151518110156109da576109ca8460e0015182815181106109b3576109b3611568565b602002602001015183610d4890919063ffffffff16565b6109d3816115c6565b905061098d565b506109e481610d79565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a519594939291906115fe565b6020604051808303816000875af1158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061169e565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610bd5575081515b60005b81811015610c3b57610beb8160086116b7565b848281518110610bfd57610bfd611568565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c34816115c6565b9050610bd8565b5050919050565b8051600003610c7d576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610c9057610c90611539565b90816002811115610ca357610ca3611539565b90525060408401828015610cb957610cb9611539565b90818015610cc957610cc9611539565b9052506060909301929092525050565b610ce161116b565b8051610ced9083610d97565b5060006020820152919050565b610d078260038351610e11565b81516102289082610f38565b8151610d209060c2610f60565b506105828282604051602001610d3891815260200190565b6040516020818303038152906040525b610d078260028351610e11565b610d60816004610fc9565b600181602001818151610d7391906116ce565b90525050565b610d84816007610fc9565b600181602001818151610d7391906116e1565b604080518082019091526060815260006020820152610db76020836116f4565b15610ddf57610dc76020836116f4565b610dd29060206116e1565b610ddc90836116ce565b91505b602080840183905260405180855260008152908184010181811015610e0357600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e3e578251610e389060e0600585901b168317610f60565b50505050565b60ff8167ffffffffffffffff1611610e80578251610e67906018611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166001610fe0565b61ffff8167ffffffffffffffff1611610ec3578251610eaa906019611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166002610fe0565b63ffffffff8167ffffffffffffffff1611610f08578251610eef90601a611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166004610fe0565b8251610f1f90601b611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166008610fe0565b604080518082019091526060815260006020820152610f5983838451611065565b9392505050565b6040805180820190915260608152600060208201528251516000610f858260016116ce565b905084602001518210610fa657610fa685610fa18360026116b7565b611154565b8451602083820101858153508051821115610fbf578181525b5093949350505050565b815161022890601f611fe0600585901b1617610f60565b604080518082019091526060815260006020820152835151600061100482856116ce565b905085602001518111156110215761102186610fa18360026116b7565b600060016110318661010061184f565b61103b91906116e1565b90508651828101878319825116178152508051831115611059578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561108857600080fd5b835151600061109784836116ce565b905085602001518111156110b4576110b486610fa18360026116b7565b8551805183820160200191600091808511156110ce578482525b505050602086015b6020861061110e57805182526110ed6020836116ce565b91506110fa6020826116ce565b90506111076020876116e1565b95506110d6565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516111608383610d97565b50610e388382610f38565b6040518060400160405280611193604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611216576112166111a0565b604052919050565b600067ffffffffffffffff831115611238576112386111a0565b61126960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116016111cf565b905082815283838301111561127d57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112a557600080fd5b610f598383356020850161121e565b6000806000606084860312156112c957600080fd5b83359250602084013567ffffffffffffffff808211156112e857600080fd5b6112f487838801611294565b9350604086013591508082111561130a57600080fd5b5061131786828701611294565b9150509250925092565b60008083601f84011261133357600080fd5b50813567ffffffffffffffff81111561134b57600080fd5b60208301915083602082850101111561136357600080fd5b9250929050565b803567ffffffffffffffff8116811461138257600080fd5b919050565b60008060008060008060008060a0898b0312156113a357600080fd5b883567ffffffffffffffff808211156113bb57600080fd5b6113c78c838d01611321565b909a50985060208b01359150808211156113e057600080fd5b6113ec8c838d01611321565b909850965060408b013591508082111561140557600080fd5b818b0191508b601f83011261141957600080fd5b81358181111561142857600080fd5b8c60208260051b850101111561143d57600080fd5b60208301965080955050505061145560608a0161136a565b9150608089013590509295985092959890939650565b60006020828403121561147d57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f5957600080fd5b600067ffffffffffffffff808411156114bc576114bc6111a0565b8360051b60206114cd8183016111cf565b8681529185019181810190368411156114e557600080fd5b865b8481101561152d578035868111156114ff5760008081fd5b880136601f8201126115115760008081fd5b61151f36823587840161121e565b8452509183019183016114e7565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115f7576115f7611597565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b8181101561163c5788810183015185820160c001528201611620565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050611685604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116b057600080fd5b5051919050565b8082028115828204841417610e0b57610e0b611597565b80820180821115610e0b57610e0b611597565b81810381811115610e0b57610e0b611597565b60008261172a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b8085111561178857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561176e5761176e611597565b8085161561177b57918102915b93841c9390800290611734565b509250929050565b60008261179f57506001610e0b565b816117ac57506000610e0b565b81600181146117c257600281146117cc576117e8565b6001915050610e0b565b60ff8411156117dd576117dd611597565b50506001821b610e0b565b5060208310610133831016604e8410600b841016171561180b575081810a610e0b565b611815838361172f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561184757611847611597565b029392505050565b6000610f59838361179056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStats\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resetStats\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalEmptyResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalFailedResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSucceededResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001cc238038062001cc2833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051611aed620001d56000396000818161027e0152610c220152611aed6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063724ec8a2116100975780638da5cb5b116100665780638da5cb5b146101c3578063c59d4847146101eb578063c9429e2a14610233578063f2fde38b1461025357600080fd5b8063724ec8a21461019057806379ba509714610198578063887efe94146101a05780638aea61dc146101b357600080fd5b806347c03186116100d357806347c031861461015c5780635c1d92e91461016557806362747e421461017d5780636d9809a01461018657600080fd5b80630ca76175146100fa57806329f0de3f1461010f5780632ab424da1461012b575b600080fd5b61010d6101083660046114e5565b610266565b005b61011860045481565b6040519081526020015b60405180910390f35b6005546101479068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b61011860025481565b60055461014790640100000000900463ffffffff1681565b61011860035481565b6101476201117081565b61010d6102e5565b61010d610326565b61010d6101ae3660046115fd565b610428565b6005546101479063ffffffff1681565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b6101f36105a2565b6040805197885260208801969096529486019390935263ffffffff91821660608601528116608085015290811660a08401521660c082015260e001610122565b600554610147906c01000000000000000000000000900463ffffffff1681565b61010d6102613660046116cc565b610607565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102d5576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102e083838361061b565b505050565b6102ed610723565b600060028190556003819055600455600580547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610430610723565b6104796040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6104bb89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506107a69050565b85156105035761050387878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506107b79050565b831561051d5761051d6105168587611702565b8290610801565b60005b8a63ffffffff168110156105955761054561053a83610844565b856201117086610c1d565b600255600580546001919060009061056490849063ffffffff166117c9565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061058d906117ed565b915050610520565b5050505050505050505050565b60008060008060008060006105b5610723565b50506002546003546004546005549298919750955063ffffffff8083169550680100000000000000008304811694506c0100000000000000000000000083048116935064010000000090920490911690565b61060f610723565b61061881610cfc565b50565b600283905561062982610df1565b60035561063581610df1565b6004558151600003610682576001600560048282829054906101000a900463ffffffff1661066391906117c9565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b8051156106ca5760016005600c8282829054906101000a900463ffffffff166106ab91906117c9565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b8151158015906106d957508051155b156102e0576001600560088282829054906101000a900463ffffffff1661070091906117c9565b92506101000a81548163ffffffff021916908363ffffffff160217905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103a3565b565b6107b38260008084610e73565b5050565b80516000036107f2576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b805160000361083c576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b60606000610853610100610f0a565b905061089d6040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610f2b90919063ffffffff16565b82516108bb9060028111156108b4576108b4611825565b8290610f44565b60408051808201909152600881527f6c616e677561676500000000000000000000000000000000000000000000000060208201526108fa908290610f2b565b60408301516109119080156108b4576108b4611825565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610950908290610f2b565b6060830151610960908290610f2b565b60a083015151156109ba5760408051808201909152601081527f726571756573745369676e61747572650000000000000000000000000000000060208201526109aa908290610f2b565b60a08301516109ba908290610f79565b60c08301515115610a675760408051808201909152600481527f61726773000000000000000000000000000000000000000000000000000000006020820152610a04908290610f2b565b610a0d81610f86565b60005b8360c0015151811015610a5d57610a4d8460c001518281518110610a3657610a36611854565b602002602001015183610f2b90919063ffffffff16565b610a56816117ed565b9050610a10565b50610a6781610faa565b60808301515115610b6857600083602001516002811115610a8a57610a8a611825565b03610ac1576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610b00908290610f2b565b610b19836020015160028111156108b4576108b4611825565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610b58908290610f2b565b6080830151610b68908290610f79565b60e08301515115610c155760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610bb2908290610f2b565b610bbb81610f86565b60005b8360e0015151811015610c0b57610bfb8460e001518281518110610be457610be4611854565b602002602001015183610f7990919063ffffffff16565b610c04816117ed565b9050610bbe565b50610c1581610faa565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610c82959493929190611883565b6020604051808303816000875af1158015610ca1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc59190611923565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610d7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103a3565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610e06575081515b60005b81811015610e6c57610e1c81600861193c565b848281518110610e2e57610e2e611854565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610e65816117ed565b9050610e09565b5050919050565b8051600003610eae576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610ec157610ec1611825565b90816002811115610ed457610ed4611825565b90525060408401828015610eea57610eea611825565b90818015610efa57610efa611825565b9052506060909301929092525050565b610f1261139c565b8051610f1e9083610fc8565b5060006020820152919050565b610f388260038351611042565b81516102e09082611169565b8151610f519060c2611191565b506107b38282604051602001610f6991815260200190565b6040516020818303038152906040525b610f388260028351611042565b610f918160046111fa565b600181602001818151610fa49190611953565b90525050565b610fb58160076111fa565b600181602001818151610fa49190611966565b604080518082019091526060815260006020820152610fe8602083611979565b1561101057610ff8602083611979565b611003906020611966565b61100d9083611953565b91505b60208084018390526040518085526000815290818401018181101561103457600080fd5b604052508290505b92915050565b60178167ffffffffffffffff161161106f5782516110699060e0600585901b168317611191565b50505050565b60ff8167ffffffffffffffff16116110b1578251611098906018611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166001611211565b61ffff8167ffffffffffffffff16116110f45782516110db906019611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166002611211565b63ffffffff8167ffffffffffffffff161161113957825161112090601a611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166004611211565b825161115090601b611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166008611211565b60408051808201909152606081526000602082015261118a83838451611296565b9392505050565b60408051808201909152606081526000602082015282515160006111b6826001611953565b9050846020015182106111d7576111d7856111d283600261193c565b611385565b84516020838201018581535080518211156111f0578181525b5093949350505050565b81516102e090601f611fe0600585901b1617611191565b60408051808201909152606081526000602082015283515160006112358285611953565b9050856020015181111561125257611252866111d283600261193c565b6000600161126286610100611ad4565b61126c9190611966565b9050865182810187831982511617815250805183111561128a578281525b50959695505050505050565b60408051808201909152606081526000602082015282518211156112b957600080fd5b83515160006112c88483611953565b905085602001518111156112e5576112e5866111d283600261193c565b8551805183820160200191600091808511156112ff578482525b505050602086015b6020861061133f578051825261131e602083611953565b915061132b602082611953565b9050611338602087611966565b9550611307565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516113918383610fc8565b506110698382611169565b60405180604001604052806113c4604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611447576114476113d1565b604052919050565b600067ffffffffffffffff831115611469576114696113d1565b61149a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611400565b90508281528383830111156114ae57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126114d657600080fd5b61118a8383356020850161144f565b6000806000606084860312156114fa57600080fd5b83359250602084013567ffffffffffffffff8082111561151957600080fd5b611525878388016114c5565b9350604086013591508082111561153b57600080fd5b50611548868287016114c5565b9150509250925092565b60008083601f84011261156457600080fd5b50813567ffffffffffffffff81111561157c57600080fd5b60208301915083602082850101111561159457600080fd5b9250929050565b60008083601f8401126115ad57600080fd5b50813567ffffffffffffffff8111156115c557600080fd5b6020830191508360208260051b850101111561159457600080fd5b803567ffffffffffffffff811681146115f857600080fd5b919050565b600080600080600080600080600060c08a8c03121561161b57600080fd5b893563ffffffff8116811461162f57600080fd5b985060208a013567ffffffffffffffff8082111561164c57600080fd5b6116588d838e01611552565b909a50985060408c013591508082111561167157600080fd5b61167d8d838e01611552565b909850965060608c013591508082111561169657600080fd5b506116a38c828d0161159b565b90955093506116b6905060808b016115e0565b915060a08a013590509295985092959850929598565b6000602082840312156116de57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461118a57600080fd5b600067ffffffffffffffff8084111561171d5761171d6113d1565b8360051b602061172e818301611400565b86815291850191818101903684111561174657600080fd5b865b8481101561178e578035868111156117605760008081fd5b880136601f8201126117725760008081fd5b61178036823587840161144f565b845250918301918301611748565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8181168382160190808211156117e6576117e661179a565b5092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361181e5761181e61179a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156118c15788810183015185820160c0015282016118a5565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505061190a604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b60006020828403121561193557600080fd5b5051919050565b808202811582820484141761103c5761103c61179a565b8082018082111561103c5761103c61179a565b8181038181111561103c5761103c61179a565b6000826119af577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b80851115611a0d57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156119f3576119f361179a565b80851615611a0057918102915b93841c93908002906119b9565b509250929050565b600082611a245750600161103c565b81611a315750600061103c565b8160018114611a475760028114611a5157611a6d565b600191505061103c565b60ff841115611a6257611a6261179a565b50506001821b61103c565b5060208310610133831016604e8410600b8410161715611a90575081810a61103c565b611a9a83836119b4565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611acc57611acc61179a565b029392505050565b600061118a8383611a1556fea164736f6c6343000813000a", } var FunctionsLoadTestClientABI = FunctionsLoadTestClientMetaData.ABI @@ -193,31 +193,81 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) MAXCALLBAC return _FunctionsLoadTestClient.Contract.MAXCALLBACKGAS(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) GetStats(opts *bind.CallOpts) ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) { var out []interface{} - err := _FunctionsLoadTestClient.contract.Call(opts, &out, "owner") + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "getStats") if err != nil { - return *new(common.Address), err + return *new([32]byte), *new([32]byte), *new([32]byte), *new(uint32), *new(uint32), *new(uint32), *new(uint32), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + out2 := *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + out3 := *abi.ConvertType(out[3], new(uint32)).(*uint32) + out4 := *abi.ConvertType(out[4], new(uint32)).(*uint32) + out5 := *abi.ConvertType(out[5], new(uint32)).(*uint32) + out6 := *abi.ConvertType(out[6], new(uint32)).(*uint32) + + return out0, out1, out2, out3, out4, out5, out6, err + +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) GetStats() ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) { + return _FunctionsLoadTestClient.Contract.GetStats(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) GetStats() ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) { + return _FunctionsLoadTestClient.Contract.GetStats(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastError(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastError") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) return out0, err } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) Owner() (common.Address, error) { - return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastError() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.LastError(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) Owner() (common.Address, error) { - return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastError() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.LastError(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastRequestID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastRequestID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastError(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastRequestID() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.LastRequestID(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastRequestID() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.LastRequestID(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastResponse(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastError") + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastResponse") if err != nil { return *new([32]byte), err @@ -229,17 +279,39 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastError(opts * } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastError() ([32]byte, error) { - return _FunctionsLoadTestClient.Contract.SLastError(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastResponse() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.LastResponse(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastResponse() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.LastResponse(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FunctionsLoadTestClient.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 (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) Owner() (common.Address, error) { + return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastError() ([32]byte, error) { - return _FunctionsLoadTestClient.Contract.SLastError(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) Owner() (common.Address, error) { + return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastErrorLength(opts *bind.CallOpts) (uint32, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalEmptyResponses(opts *bind.CallOpts) (uint32, error) { var out []interface{} - err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastErrorLength") + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalEmptyResponses") if err != nil { return *new(uint32), err @@ -251,61 +323,61 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastErrorLength( } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastErrorLength() (uint32, error) { - return _FunctionsLoadTestClient.Contract.SLastErrorLength(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalEmptyResponses() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalEmptyResponses(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastErrorLength() (uint32, error) { - return _FunctionsLoadTestClient.Contract.SLastErrorLength(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalEmptyResponses() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalEmptyResponses(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastRequestId(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalFailedResponses(opts *bind.CallOpts) (uint32, error) { var out []interface{} - err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastRequestId") + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalFailedResponses") if err != nil { - return *new([32]byte), err + return *new(uint32), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) return out0, err } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastRequestId() ([32]byte, error) { - return _FunctionsLoadTestClient.Contract.SLastRequestId(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalFailedResponses() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalFailedResponses(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastRequestId() ([32]byte, error) { - return _FunctionsLoadTestClient.Contract.SLastRequestId(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalFailedResponses() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalFailedResponses(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponse(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalRequests(opts *bind.CallOpts) (uint32, error) { var out []interface{} - err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastResponse") + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalRequests") if err != nil { - return *new([32]byte), err + return *new(uint32), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) return out0, err } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastResponse() ([32]byte, error) { - return _FunctionsLoadTestClient.Contract.SLastResponse(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalRequests() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalRequests(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastResponse() ([32]byte, error) { - return _FunctionsLoadTestClient.Contract.SLastResponse(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalRequests() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalRequests(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponseLength(opts *bind.CallOpts) (uint32, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalSucceededResponses(opts *bind.CallOpts) (uint32, error) { var out []interface{} - err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastResponseLength") + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalSucceededResponses") if err != nil { return *new(uint32), err @@ -317,12 +389,12 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponseLeng } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastResponseLength() (uint32, error) { - return _FunctionsLoadTestClient.Contract.SLastResponseLength(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalSucceededResponses() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalSucceededResponses(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastResponseLength() (uint32, error) { - return _FunctionsLoadTestClient.Contract.SLastResponseLength(&_FunctionsLoadTestClient.CallOpts) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalSucceededResponses() (uint32, error) { + return _FunctionsLoadTestClient.Contract.TotalSucceededResponses(&_FunctionsLoadTestClient.CallOpts) } func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { @@ -349,16 +421,28 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) Handle return _FunctionsLoadTestClient.Contract.HandleOracleFulfillment(&_FunctionsLoadTestClient.TransactOpts, requestId, response, err) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequest", source, encryptedSecretsReferences, args, subscriptionId, jobId) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) ResetStats(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "resetStats") +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) ResetStats() (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.ResetStats(&_FunctionsLoadTestClient.TransactOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) ResetStats() (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.ResetStats(&_FunctionsLoadTestClient.TransactOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequest", times, source, encryptedSecretsReferences, args, subscriptionId, jobId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, jobId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, jobId) } func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -938,23 +1022,31 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClient) Address() common.Addres type FunctionsLoadTestClientInterface interface { MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error) - Owner(opts *bind.CallOpts) (common.Address, error) + GetStats(opts *bind.CallOpts) ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) - SLastError(opts *bind.CallOpts) ([32]byte, error) + LastError(opts *bind.CallOpts) ([32]byte, error) - SLastErrorLength(opts *bind.CallOpts) (uint32, error) + LastRequestID(opts *bind.CallOpts) ([32]byte, error) - SLastRequestId(opts *bind.CallOpts) ([32]byte, error) + LastResponse(opts *bind.CallOpts) ([32]byte, error) - SLastResponse(opts *bind.CallOpts) ([32]byte, error) + Owner(opts *bind.CallOpts) (common.Address, error) + + TotalEmptyResponses(opts *bind.CallOpts) (uint32, error) + + TotalFailedResponses(opts *bind.CallOpts) (uint32, error) - SLastResponseLength(opts *bind.CallOpts) (uint32, error) + TotalRequests(opts *bind.CallOpts) (uint32, error) + + TotalSucceededResponses(opts *bind.CallOpts) (uint32, error) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) - SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) + ResetStats(opts *bind.TransactOpts) (*types.Transaction, error) + + SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) 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 818c5bc3d1c..46f10db9d5d 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 @@ -5,7 +5,7 @@ functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin 25036bdb94a50a81df4222418bf9aa1e0c8540d5834b7e6e639aa63a2a2c8206 functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin e453fd45029ff99658d029bfbb8711b748c432323f12585c039a30977e801a79 -functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin 28f2834dea12b3aefa7c696b64ca5272a1ab5cdf33365c9f7fafdc0b7d5669e8 +functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin 08b0ba467a0d2913ad146c293cc92ed1e0e5f25398bc8185addf9c4c1a41df2c functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin dd1d3527e19d65efe029c4a131ded44dc0ca961e5c4f459743992435431ec478 functions_v1_events_mock: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.bin 0f0ba42e0cc33c7abc8b8fd4fdfce903748a169886dd5f16cfdd56e75bcf708d diff --git a/core/scripts/go.mod b/core/scripts/go.mod index ef70cdc20fe..2a81e2bb05b 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -284,7 +284,7 @@ require ( github.com/prometheus/procfs v0.11.0 // indirect github.com/prometheus/prometheus v0.46.0 // indirect github.com/pyroscope-io/client v0.7.1 // indirect - github.com/pyroscope-io/godeltaprof v0.1.0 // indirect + github.com/pyroscope-io/godeltaprof v0.1.2 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rjeczalik/notify v0.9.3 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 5680f6e6619..708688e5e1f 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1310,8 +1310,8 @@ github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIsc 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.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE= -github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= +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/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= diff --git a/integration-tests/chaos/functions/full.yaml b/integration-tests/chaos/functions/full.yaml new file mode 100644 index 00000000000..9d62f899c62 --- /dev/null +++ b/integration-tests/chaos/functions/full.yaml @@ -0,0 +1,232 @@ +apiVersion: chaos-mesh.org/v1alpha1 +kind: Workflow +metadata: + namespace: chainlink + name: chainlink-flow +spec: + entry: entry + templates: + # root entry + - name: entry + templateType: Serial + deadline: 1h + children: + - killing + - network-delay-internal +# - external-deps-failure + # children chaos group + - name: killing + templateType: Serial + children: + - gateway-kill + - don-minority-kill + - don-majority-kill + - adapters-minority-kill + - adapters-majority-kill + # children chaos group + - name: network-delay-internal + templateType: Serial + children: + - gateway-delay + - don-minority-delay + - don-majority-delay + - adapters-minority-delay + - adapters-majority-delay + # children chaos group + - name: external-deps-failure + templateType: Serial + children: + - ea-url-resolve-failure + + # experiments (killing) + - name: gateway-kill + templateType: PodChaos + deadline: 1m + podChaos: + selector: + namespaces: + - chainlink + labelSelectors: + 'app.kubernetes.io/instance': cln-gateway-staging1-node + mode: one + action: pod-kill + - name: don-minority-kill + templateType: PodChaos + deadline: 1m + podChaos: + selector: + namespaces: + - chainlink + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - clc-ocr2-dr-matic-testnet-nodes-0 + - clc-ocr2-dr-matic-testnet-boot + mode: all + action: pod-kill + - name: don-majority-kill + templateType: PodChaos + deadline: 1m + podChaos: + selector: + namespaces: + - chainlink + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - clc-ocr2-dr-matic-testnet-nodes-1 + - clc-ocr2-dr-matic-testnet-nodes-0 + - clc-ocr2-dr-matic-testnet-boot + mode: all + action: pod-kill + - name: adapters-minority-kill + templateType: PodChaos + deadline: 1m + podChaos: + selector: + namespaces: + - adapters + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - universal-mumbai-0 + mode: all + action: pod-kill + - name: adapters-majority-kill + templateType: PodChaos + deadline: 1m + podChaos: + selector: + namespaces: + - adapters + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - universal-mumbai-1 + - universal-mumbai-0 + mode: all + action: pod-kill + + # TODO: enable when chaosd is installed on all the nodes + # experiments (delays) + - name: gateway-delay + templateType: NetworkChaos + deadline: 1m + networkChaos: + selector: + namespaces: + - chainlink + labelSelectors: + 'app.kubernetes.io/instance': cln-gateway-staging1-node + mode: all + action: delay + delay: + latency: 200ms + correlation: '0' + jitter: 0ms + direction: to + - name: don-minority-delay + templateType: NetworkChaos + deadline: 1m + networkChaos: + selector: + namespaces: + - chainlink + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - clc-ocr2-dr-matic-testnet-nodes-0 + - clc-ocr2-dr-matic-testnet-boot + mode: all + action: delay + delay: + latency: 200ms + correlation: '0' + jitter: 0ms + direction: to + - name: don-majority-delay + templateType: NetworkChaos + deadline: 1m + networkChaos: + selector: + namespaces: + - chainlink + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - clc-ocr2-dr-matic-testnet-nodes-1 + - clc-ocr2-dr-matic-testnet-nodes-0 + - clc-ocr2-dr-matic-testnet-boot + mode: all + action: delay + delay: + latency: 200ms + correlation: '0' + jitter: 0ms + direction: to + - name: adapters-minority-delay + templateType: NetworkChaos + deadline: 1m + networkChaos: + selector: + namespaces: + - adapters + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - universal-mumbai-0 + mode: all + action: delay + delay: + latency: 200ms + correlation: '0' + jitter: 0ms + direction: to + - name: adapters-majority-delay + templateType: NetworkChaos + deadline: 1m + networkChaos: + selector: + namespaces: + - adapters + expressionSelectors: + - key: app.kubernetes.io/instance + operator: In + values: + - universal-mumbai-1 + - universal-mumbai-0 + mode: all + action: delay + delay: + latency: 200ms + correlation: '0' + jitter: 0ms + direction: to + + # experiments (external deps failure) +# - name: ea-url-resolve-failure +# templateType: NetworkChaos +# deadline: 3m +# networkChaos: +# selector: +# namespaces: +# - chainlink +# mode: all +# action: partition +# direction: to +# target: +# selector: +# namespaces: +# - chainlink +# mode: all +# externalTargets: +# - >- +# my-url.com + diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index 6fd34a9a3fe..941eba73ebf 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -351,6 +351,8 @@ type AuthorizedForwarder interface { type FunctionsCoordinator interface { Address() string + GetThresholdPublicKey() ([]byte, error) + GetDONPublicKey() ([]byte, error) } type FunctionsRouter interface { @@ -360,5 +362,7 @@ type FunctionsRouter interface { type FunctionsLoadTestClient interface { Address() string - SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error + ResetStats() error + GetStats() (*EthereumFunctionsLoadStats, error) + SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error } diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 0aebd60560f..8f80ed3896c 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -25,7 +25,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_client_example" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router" @@ -2113,7 +2112,7 @@ func (e *EthereumFunctionsRouter) CreateSubscriptionWithConsumer(consumer string return 0, err } for _, l := range r.Logs { - log.Warn().Interface("Log", common.Bytes2Hex(l.Data)).Send() + log.Info().Interface("Log", common.Bytes2Hex(l.Data)).Send() } topicsMap := map[string]interface{}{} @@ -2122,14 +2121,14 @@ func (e *EthereumFunctionsRouter) CreateSubscriptionWithConsumer(consumer string return 0, err } for _, ev := range fabi.Events { - log.Warn().Str("EventName", ev.Name).Send() + log.Info().Str("EventName", ev.Name).Send() } topicOneInputs := abi.Arguments{fabi.Events["SubscriptionCreated"].Inputs[0]} topicOneHash := []common.Hash{r.Logs[0].Topics[1:][0]} if err := abi.ParseTopicsIntoMap(topicsMap, topicOneInputs, topicOneHash); err != nil { return 0, errors.Wrap(err, "failed to decode topic value") } - log.Warn().Interface("NewTopicsDecoded", topicsMap).Send() + log.Info().Interface("NewTopicsDecoded", topicsMap).Send() if topicsMap["subscriptionId"] == 0 { return 0, errors.New("failed to decode subscription ID after creation") } @@ -2142,6 +2141,22 @@ type EthereumFunctionsCoordinator struct { instance *functions_coordinator.FunctionsCoordinator } +func (e *EthereumFunctionsCoordinator) GetThresholdPublicKey() ([]byte, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(e.client.GetDefaultWallet().Address()), + Context: context.Background(), + } + return e.instance.GetThresholdPublicKey(opts) +} + +func (e *EthereumFunctionsCoordinator) GetDONPublicKey() ([]byte, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(e.client.GetDefaultWallet().Address()), + Context: context.Background(), + } + return e.instance.GetDONPublicKey(opts) +} + func (e *EthereumFunctionsCoordinator) Address() string { return e.address.Hex() } @@ -2156,19 +2171,64 @@ func (e *EthereumFunctionsLoadTestClient) Address() string { return e.address.Hex() } -func (e *EthereumFunctionsLoadTestClient) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error { +type EthereumFunctionsLoadStats struct { + LastRequestID string + LastResponse string + LastError string + Total uint32 + Succeeded uint32 + Errored uint32 + Empty uint32 +} + +func Bytes32ToSlice(a [32]byte) (r []byte) { + r = append(r, a[:]...) + return +} + +func (e *EthereumFunctionsLoadTestClient) GetStats() (*EthereumFunctionsLoadStats, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(e.client.GetDefaultWallet().Address()), + Context: context.Background(), + } + lr, lbody, lerr, total, succeeded, errored, empty, err := e.instance.GetStats(opts) + if err != nil { + return nil, err + } + return &EthereumFunctionsLoadStats{ + LastRequestID: string(Bytes32ToSlice(lr)), + LastResponse: string(Bytes32ToSlice(lbody)), + LastError: string(Bytes32ToSlice(lerr)), + Total: total, + Succeeded: succeeded, + Errored: errored, + Empty: empty, + }, nil +} + +func (e *EthereumFunctionsLoadTestClient) ResetStats() error { opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) if err != nil { return err } - tx, err := e.instance.SendRequest(opts, source, encryptedSecretsReferences, args, subscriptionId, jobId) + tx, err := e.instance.ResetStats(opts) if err != nil { return err } if err := e.client.ProcessTransaction(tx); err != nil { return err } - revertReason, _, _ := e.client.RevertReasonFromTx(tx.Hash(), functions_client_example.FunctionsClientExampleABI) - log.Debug().Str("RevertReason", revertReason).Send() return nil } + +func (e *EthereumFunctionsLoadTestClient) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := e.instance.SendRequest(opts, times, source, encryptedSecretsReferences, args, subscriptionId, jobId) + if err != nil { + return err + } + return e.client.ProcessTransaction(tx) +} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e1384facb91..bb9bf9cfff0 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -20,11 +20,12 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-env v0.36.0 - github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230828224428-5b8a157a94d0 + github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230829222228-4afd1b3d385c github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 github.com/smartcontractkit/ocr2keepers v0.7.19 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 + github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230829114801-14bf715f805e github.com/smartcontractkit/wasp v0.3.0 github.com/spf13/cobra v1.6.1 github.com/stretchr/testify v1.8.4 @@ -158,12 +159,12 @@ require ( 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.3 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // 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.8 // 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.3 // 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 @@ -386,7 +387,6 @@ require ( github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e // indirect - github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230829114801-14bf715f805e // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 20be19c04f0..87b904bceb4 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1014,8 +1014,9 @@ github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2uj github.com/go-openapi/errors v0.20.3/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 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= 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= @@ -1025,8 +1026,8 @@ github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8en 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.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= -github.com/go-openapi/spec v0.20.8/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= @@ -1035,8 +1036,9 @@ github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KA 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 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= 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-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= @@ -2247,8 +2249,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97ac github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918/go.mod h1:/yp/sqD8Iz5GU5fcercjrw0ivJF7HDcupYg+Gjr7EPg= -github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230828224428-5b8a157a94d0 h1:DvIwUQc3/yWlvuXD/t30aOyX5BPVomM7OQT8ZO9VFFo= -github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230828224428-5b8a157a94d0/go.mod h1:t6FJX3akEfAO31p96ru0ilNPfE9P2UshUlXTIkI58LM= +github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230829222228-4afd1b3d385c h1:8/L+5JupikVsMga6z0WBElp1RgRO6BB5BF+QsBsSrOI= +github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230829222228-4afd1b3d385c/go.mod h1:t6FJX3akEfAO31p96ru0ilNPfE9P2UshUlXTIkI58LM= github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI= github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= diff --git a/integration-tests/load/functions/README.md b/integration-tests/load/functions/README.md index ec94b9ded0a..6b80137cf48 100644 --- a/integration-tests/load/functions/README.md +++ b/integration-tests/load/functions/README.md @@ -1,12 +1,53 @@ -### Functions Load tests +### Functions & S4 Gateway Load tests -## Usage +## Setup +Export vars ``` +export SELECTED_NETWORKS=MUMBAI +export MUMBAI_KEYS=... +export MUMBAI_URLS=... export LOKI_TOKEN=... export LOKI_URL=... +``` +See more config options in [config.toml](./config.toml) +## Usage + +Soak `1 TX/sec - 40 requests per TX` +``` go test -v -run TestFunctionsLoad/functions_soak_test ``` +Stress `1 TX/sec - 78 requests per TX` (max gas) +``` +go test -v -run TestFunctionsLoad/functions_stress_test +``` +Gateway `secrets_list` test +``` +go test -v -timeout 24h -run TestGatewayLoad/gateway_secrets_list_soak_test +``` +Gateway `secrets_set` test +``` +go test -v -timeout 24h -run TestGatewayLoad/gateway_secrets_set_soak_test +``` + +Chaos suite can be combined with any test, can be found [here](../../chaos/functions/full.yaml) + +Default [dashboard](https://chainlinklabs.grafana.net/d/FunctionsV1/functionsv1?orgId=1&from=now-5m&to=now&var-go_test_name=All&var-gen_name=All&var-branch=All&var-commit=All&var-call_group=All&refresh=5s) + +## Redeploying client and funding a new sub +When contracts got redeployed on `Mumbai` just comment these lines in config +``` +# comment both client and sub to automatically create a new pair +client_addr = "0x64a351fbAa61681A5a7e569Cc5A691150c4D73D2" +subscription_id = 23 +``` +Then insert new client addr and subscription number back + +## Debug +Show more logs +``` +export WASP_LOG_LEVEL=debug +``` ### Dashboards diff --git a/integration-tests/load/functions/config.go b/integration-tests/load/functions/config.go index baba37d2c82..9f0a5bda0c7 100644 --- a/integration-tests/load/functions/config.go +++ b/integration-tests/load/functions/config.go @@ -17,21 +17,26 @@ const ( ) type PerformanceConfig struct { - Soak *Soak `toml:"Soak"` - Load *Load `toml:"Load"` - SoakVolume *SoakVolume `toml:"SoakVolume"` - LoadVolume *LoadVolume `toml:"LoadVolume"` - Common *Common `toml:"Common"` + Soak *Soak `toml:"Soak"` + Stress *Stress `toml:"Stress"` + GatewayListSoak *GatewayListSoak `toml:"GatewayListSoak"` + GatewaySetSoak *GatewaySetSoak `toml:"GatewaySetSoak"` + Common *Common `toml:"Common"` + MumbaiPrivateKey string } type Common struct { Funding - LINKTokenAddr string `toml:"link_token_addr"` - Coordinator string `toml:"coordinator_addr"` - Router string `toml:"router_addr"` - LoadTestClient string `toml:"client_example_addr"` - SubscriptionID uint64 `toml:"subscription_id"` - DONID string `toml:"don_id"` + LINKTokenAddr string `toml:"link_token_addr"` + Coordinator string `toml:"coordinator_addr"` + Router string `toml:"router_addr"` + LoadTestClient string `toml:"client_addr"` + SubscriptionID uint64 `toml:"subscription_id"` + DONID string `toml:"don_id"` + GatewayURL string `toml:"gateway_url"` + Receiver string `toml:"receiver"` + FunctionsCallPayload string `toml:"functions_call_payload"` + Secrets string `toml:"secrets"` } type Funding struct { @@ -40,29 +45,25 @@ type Funding struct { } type Soak struct { - RPS int64 `toml:"rps"` - Duration *models.Duration `toml:"duration"` + RPS int64 `toml:"rps"` + RequestsPerCall uint32 `toml:"requests_per_call"` + Duration *models.Duration `toml:"duration"` } -type SoakVolume struct { - Products int64 `toml:"products"` - Pace *models.Duration `toml:"pace"` - Duration *models.Duration `toml:"duration"` +type Stress struct { + RPS int64 `toml:"rps"` + RequestsPerCall uint32 `toml:"requests_per_call"` + Duration *models.Duration `toml:"duration"` } -type Load struct { - RPSFrom int64 `toml:"rps_from"` - RPSIncrease int64 `toml:"rps_increase"` - RPSSteps int `toml:"rps_steps"` - Duration *models.Duration `toml:"duration"` +type GatewayListSoak struct { + RPS int64 `toml:"rps"` + Duration *models.Duration `toml:"duration"` } -type LoadVolume struct { - ProductsFrom int64 `toml:"products_from"` - ProductsIncrease int64 `toml:"products_increase"` - ProductsSteps int `toml:"products_steps"` - Pace *models.Duration `toml:"pace"` - Duration *models.Duration `toml:"duration"` +type GatewaySetSoak struct { + RPS int64 `toml:"rps"` + Duration *models.Duration `toml:"duration"` } func ReadConfig() (*PerformanceConfig, error) { @@ -76,5 +77,15 @@ func ReadConfig() (*PerformanceConfig, error) { return nil, errors.Wrap(err, ErrUnmarshalPerfConfig) } log.Debug().Interface("PerformanceConfig", cfg).Msg("Parsed performance config") + mpk := os.Getenv("MUMBAI_KEYS") + murls := os.Getenv("MUMBAI_URLS") + snet := os.Getenv("SELECTED_NETWORKS") + if mpk == "" || murls == "" || snet == "" { + return nil, errors.New( + "ensure variables are set:\nMUMBAI_KEYS variable, private keys, comma separated\nSELECTED_NETWORKS=MUMBAI\nMUMBAI_URLS variable, websocket urls, comma separated", + ) + } else { + cfg.MumbaiPrivateKey = mpk + } return cfg, nil } diff --git a/integration-tests/load/functions/config.toml b/integration-tests/load/functions/config.toml index 14cedcd9a5d..a5cf4dbb379 100644 --- a/integration-tests/load/functions/config.toml +++ b/integration-tests/load/functions/config.toml @@ -1,34 +1,35 @@ [Soak] rps = 1 -duration = "1h" +requests_per_call = 40 +duration = "10m" -[Load] -rps_from = 1 -rps_increase = 1 -rps_steps = 10 -duration = "3m" +[Stress] +rps = 1 +requests_per_call = 78 +duration = "10m" -[SoakVolume] -products = 5 -pace = "1s" -duration = "3m" +[GatewayListSoak] +rps = 95 +duration = "10m" -[LoadVolume] -products_from = 1 -products_increase = 1 -products_steps = 10 -pace = "1s" -duration = "3m" +[GatewaySetSoak] +rps = 95 +duration = "10m" [Common] # Polygon Mumbai only for now +receiver = "0x3098B6665589959711A48a6bAe5B7F2908f6a3bE" +don_id = "fun-staging-mumbai-1" +gateway_url = "https://gateway-staging1.main.stage.cldev.sh" link_token_addr = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB" -coordinator_addr = "0x69b4C680209737B877c93327fC2144ec39eaC423" -router_addr = "0xa4Ac8b863A6b4fB064B6bdF87aD61d389d97748d" -client_example_addr = "0x2720cC3a112d33B5C1D40270f7c7BE7CADec1690" -don_id = "functions_staging_mumbai" -# comment it to automatically create and fund a new one -subscription_id = 48 -# not used until we have full DON setup -# node_funds = 10 -sub_funds = 7 \ No newline at end of file +coordinator_addr = "0x6D6a83BB356b7242E88C1A2b290102fde26590D0" +router_addr = "0x2673266D3Cd08b53494B5a92B66DEec7F1408E7A" +# comment both client and sub to automatically create a new pair +client_addr = "0x64a351fbAa61681A5a7e569Cc5A691150c4D73D2" +subscription_id = 23 +sub_funds = 10 + +functions_call_payload = "const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); return Functions.encodeUint256(response.data.id)" +#functions_call_payload = "return Functions.encodeUint256(BigInt(secrets.ltsecret))" +# uncomment to upload new secrets to s4 +#secrets = "{\"ltsecret\": \"1\"}" \ No newline at end of file diff --git a/integration-tests/load/functions/functions_test.go b/integration-tests/load/functions/functions_test.go index 656c3b80ec1..16311ac440b 100644 --- a/integration-tests/load/functions/functions_test.go +++ b/integration-tests/load/functions/functions_test.go @@ -10,52 +10,69 @@ import ( func TestFunctionsLoad(t *testing.T) { cfg, err := ReadConfig() require.NoError(t, err) - env, functionContracts, err := SetupLocalLoadTestEnv(cfg) + ft, err := SetupLocalLoadTestEnv(cfg) require.NoError(t, err) - env.ParallelTransactions(true) + ft.EVMClient.ParallelTransactions(false) labels := map[string]string{ "branch": "functions_healthcheck", "commit": "functions_healthcheck", } - singleFeedConfig := &wasp.Config{ - T: t, - LoadType: wasp.RPS, - GenName: "gun", - CallTimeout: 2 * time.Minute, - Gun: NewSingleFunctionCallGun( - functionContracts, - "const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); return Functions.encodeUint256(response.data.id)", - []byte{}, - []string{}, - cfg.Common.SubscriptionID, - StringToByte32(cfg.Common.DONID), - ), - Labels: labels, - LokiConfig: wasp.NewEnvLokiConfig(), - } + MonitorLoadStats(t, ft, labels) t.Run("functions soak test", func(t *testing.T) { - singleFeedConfig.Schedule = wasp.Plain( - cfg.Soak.RPS, - cfg.Soak.Duration.Duration(), - ) _, err := wasp.NewProfile(). - Add(wasp.NewGenerator(singleFeedConfig)). + Add(wasp.NewGenerator(&wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "functions_soak_gen", + RateLimitUnitDuration: 5 * time.Second, + CallTimeout: 3 * time.Minute, + Schedule: wasp.Plain( + cfg.Soak.RPS, + cfg.Soak.Duration.Duration(), + ), + Gun: NewSingleFunctionCallGun( + ft, + cfg.Soak.RequestsPerCall, + cfg.Common.FunctionsCallPayload, + []byte{}, + []string{}, + cfg.Common.SubscriptionID, + StringToByte32(cfg.Common.DONID), + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + })). Run(true) require.NoError(t, err) }) - t.Run("functions load test", func(t *testing.T) { - singleFeedConfig.Schedule = wasp.Steps( - cfg.Load.RPSFrom, - cfg.Load.RPSIncrease, - cfg.Load.RPSSteps, - cfg.Load.Duration.Duration(), - ) + t.Run("functions stress test", func(t *testing.T) { _, err = wasp.NewProfile(). - Add(wasp.NewGenerator(singleFeedConfig)). + Add(wasp.NewGenerator(&wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "functions_stress_gen", + RateLimitUnitDuration: 5 * time.Second, + CallTimeout: 3 * time.Minute, + Schedule: wasp.Plain( + cfg.Stress.RPS, + cfg.Stress.Duration.Duration(), + ), + Gun: NewSingleFunctionCallGun( + ft, + cfg.Stress.RequestsPerCall, + cfg.Common.FunctionsCallPayload, + []byte{}, + []string{}, + cfg.Common.SubscriptionID, + StringToByte32(cfg.Common.DONID), + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + })). Run(true) require.NoError(t, err) }) diff --git a/integration-tests/load/functions/gateway.go b/integration-tests/load/functions/gateway.go new file mode 100644 index 00000000000..12406c79eb1 --- /dev/null +++ b/integration-tests/load/functions/gateway.go @@ -0,0 +1,227 @@ +package loadfunctions + +import ( + "bytes" + "crypto/ecdsa" + "crypto/rand" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/ecies" + "github.com/go-resty/resty/v2" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + "github.com/smartcontractkit/chainlink/v2/core/services/s4" + "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy" + "time" +) + +type RPCResponse struct { + ID string `json:"id"` + Jsonrpc string `json:"jsonrpc"` + Result struct { + Body struct { + DonID string `json:"don_id"` + MessageID string `json:"message_id"` + Method string `json:"method"` + Payload struct { + NodeResponses []struct { + Body struct { + DonID string `json:"don_id"` + MessageID string `json:"message_id"` + Method string `json:"method"` + Payload struct { + Success bool `json:"success"` + } `json:"payload"` + Receiver string `json:"receiver"` + } `json:"body"` + Signature string `json:"signature"` + } `json:"node_responses"` + Success bool `json:"success"` + } `json:"payload"` + Receiver string `json:"receiver"` + } `json:"body"` + Signature string `json:"signature"` + } `json:"result"` +} + +func UploadS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) error { + key, err := crypto.HexToECDSA(s4Cfg.PrivateKey) + if err != nil { + return err + } + address := crypto.PubkeyToAddress(key.PublicKey) + var payloadJSON []byte + if s4Cfg.Method == functions.MethodSecretsSet { + envelope := s4.Envelope{ + Address: address.Bytes(), + SlotID: s4Cfg.S4SetSlotID, + Version: s4Cfg.S4SetVersion, + Payload: []byte(s4Cfg.S4SetPayload), + Expiration: time.Now().UnixMilli() + s4Cfg.S4SetExpirationPeriod, + } + signature, err := envelope.Sign(key) + if err != nil { + return err + } + + s4SetPayload := functions.SecretsSetRequest{ + SlotID: envelope.SlotID, + Version: envelope.Version, + Expiration: envelope.Expiration, + Payload: []byte(s4Cfg.S4SetPayload), + Signature: signature, + } + + payloadJSON, err = json.Marshal(s4SetPayload) + if err != nil { + return err + } + } + + msg := &api.Message{ + Body: api.MessageBody{ + MessageId: s4Cfg.MessageID, + Method: s4Cfg.Method, + DonId: s4Cfg.DonID, + Payload: json.RawMessage(payloadJSON), + }, + } + + err = msg.Sign(key) + if err != nil { + return err + } + codec := api.JsonRPCCodec{} + rawMsg, err := codec.EncodeRequest(msg) + if err != nil { + return err + } + var result *RPCResponse + resp, err := rc.R(). + SetBody(rawMsg). + Post(s4Cfg.GatewayURL) + if err != nil { + return err + } + if resp.StatusCode() != 200 { + return fmt.Errorf("status code was %d, expected 200", resp.StatusCode()) + } + if err := json.Unmarshal(resp.Body(), &result); err != nil { + return err + } + log.Debug().Interface("Result", result).Msg("S4 secrets_set response result") + for _, nodeResponse := range result.Result.Body.Payload.NodeResponses { + if !nodeResponse.Body.Payload.Success { + return fmt.Errorf("node response was not succesful") + } + } + return nil +} + +func ListS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) error { + key, err := crypto.HexToECDSA(s4Cfg.PrivateKey) + if err != nil { + return err + } + + msg := &api.Message{ + Body: api.MessageBody{ + MessageId: s4Cfg.MessageID, + Method: s4Cfg.Method, + DonId: s4Cfg.DonID, + Receiver: s4Cfg.RecieverAddr, + }, + } + + err = msg.Sign(key) + if err != nil { + return err + } + codec := api.JsonRPCCodec{} + rawMsg, err := codec.EncodeRequest(msg) + if err != nil { + return err + } + msgdec, err := codec.DecodeRequest(rawMsg) + if err != nil { + return err + } + log.Debug().Interface("Request", msgdec).Msg("Sending RPC request") + var result map[string]interface{} + resp, err := rc.R(). + SetBody(rawMsg). + Post(s4Cfg.GatewayURL) + if err != nil { + return err + } + if err := json.Unmarshal(resp.Body(), &result); err != nil { + return err + } + log.Debug().Interface("Result", result).Msg("S4 secrets_list response result") + if resp.StatusCode() != 200 { + return fmt.Errorf("status code was %d, expected 200", resp.StatusCode()) + } + return nil +} + +func ParseTDH2Key(data []byte) (*tdh2easy.PublicKey, error) { + pk := &tdh2easy.PublicKey{} + if err := pk.Unmarshal(data); err != nil { + return nil, err + } + return pk, nil +} + +func EncryptS4Secrets(deployerPk *ecdsa.PrivateKey, tdh2Pk *tdh2easy.PublicKey, donKey []byte, msgJSON string) (string, error) { + // 65 bytes PublicKey format, should start with 0x04 to be processed by crypto.UnmarshalPubkey() + b := make([]byte, 1) + b[0] = 0x04 + donKey = bytes.Join([][]byte{b, donKey}, nil) + donPubKey, err := crypto.UnmarshalPubkey(donKey) + if err != nil { + return "", errors.Wrap(err, "failed to unmarshal DON key") + } + eciesDONPubKey := ecies.ImportECDSAPublic(donPubKey) + signature, err := deployerPk.Sign(rand.Reader, []byte(msgJSON), nil) + if err != nil { + return "", errors.Wrap(err, "failed to sign the msg with Ethereum key") + } + signedSecrets, err := json.Marshal(struct { + Signature []byte `json:"signature"` + Message string `json:"message"` + }{ + Signature: signature, + Message: msgJSON, + }) + if err != nil { + return "", errors.Wrap(err, "failed to marshal signed secrets") + } + ct, err := ecies.Encrypt(rand.Reader, eciesDONPubKey, signedSecrets, nil, nil) + if err != nil { + return "", errors.Wrap(err, "failed to encrypt with DON key") + } + ct0xFormat, err := json.Marshal(map[string]interface{}{"0x0": base64.StdEncoding.EncodeToString(ct)}) + if err != nil { + return "", errors.Wrap(err, "failed to marshal DON key encrypted format") + } + ctTDH2Format, err := tdh2easy.Encrypt(tdh2Pk, ct0xFormat) + if err != nil { + return "", errors.Wrap(err, "failed to encrypt with TDH2 public key") + } + tdh2Message, err := ctTDH2Format.Marshal() + if err != nil { + return "", errors.Wrap(err, "failed to marshal TDH2 encrypted msg") + } + finalMsg, err := json.Marshal(map[string]interface{}{ + "encryptedSecrets": "0x" + hex.EncodeToString(tdh2Message), + }) + if err != nil { + return "", errors.Wrap(err, "failed to marshal secrets msg") + } + return string(finalMsg), nil +} diff --git a/integration-tests/load/functions/gateway_gun.go b/integration-tests/load/functions/gateway_gun.go new file mode 100644 index 00000000000..5677e79b105 --- /dev/null +++ b/integration-tests/load/functions/gateway_gun.go @@ -0,0 +1,110 @@ +package loadfunctions + +import ( + "crypto/ecdsa" + "fmt" + "github.com/go-resty/resty/v2" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy" + "github.com/smartcontractkit/wasp" + "math/rand" + "os" + "strconv" + "time" +) + +/* SingleFunctionCallGun is a gun that constantly requests randomness for one feed */ + +type GatewaySecretsSetGun struct { + Cfg *PerformanceConfig + Resty *resty.Client + SlotID uint + Method string + EthereumPrivateKey *ecdsa.PrivateKey + ThresholdPublicKey *tdh2easy.PublicKey + DONPublicKey []byte +} + +func NewGatewaySecretsSetGun(cfg *PerformanceConfig, method string, pKey *ecdsa.PrivateKey, tdh2PubKey *tdh2easy.PublicKey, donPubKey []byte) *GatewaySecretsSetGun { + return &GatewaySecretsSetGun{ + Cfg: cfg, + Resty: resty.New(), + Method: method, + EthereumPrivateKey: pKey, + ThresholdPublicKey: tdh2PubKey, + DONPublicKey: donPubKey, + } +} + +func callSetSecrets(m *GatewaySecretsSetGun) *wasp.CallResult { + randNum := strconv.Itoa(rand.Intn(100000)) + randSlot := uint(rand.Intn(5)) + version := uint64(time.Now().UnixNano()) + expiration := int64(60 * 60 * 1000) + secret := fmt.Sprintf("{\"ltsecret\": \"%s\"}", randNum) + log.Debug(). + Uint("SlotID", randSlot). + Str("MessageID", randNum). + Uint64("Version", version). + Int64("Expiration", expiration). + Str("Secret", secret). + Msg("Sending S4 envelope") + secrets, err := EncryptS4Secrets( + m.EthereumPrivateKey, + m.ThresholdPublicKey, + m.DONPublicKey, + secret, + ) + if err != nil { + return &wasp.CallResult{Error: err.Error(), Failed: true} + } + if err := UploadS4Secrets(m.Resty, &S4SecretsCfg{ + GatewayURL: fmt.Sprintf("%s/user", m.Cfg.Common.GatewayURL), + PrivateKey: os.Getenv("MUMBAI_KEYS"), + MessageID: randNum, + Method: "secrets_set", + DonID: m.Cfg.Common.DONID, + S4SetSlotID: randSlot, + S4SetVersion: version, + S4SetExpirationPeriod: expiration, + S4SetPayload: secrets, + }); err != nil { + return &wasp.CallResult{Error: err.Error(), Failed: true} + } + return &wasp.CallResult{} +} + +func callSecretsList(m *GatewaySecretsSetGun) *wasp.CallResult { + randNum := strconv.Itoa(rand.Intn(100000)) + randSlot := uint(rand.Intn(5)) + version := uint64(time.Now().UnixNano()) + expiration := int64(60 * 60 * 1000) + if err := ListS4Secrets(m.Resty, &S4SecretsCfg{ + GatewayURL: fmt.Sprintf("%s/user", m.Cfg.Common.GatewayURL), + RecieverAddr: m.Cfg.Common.Receiver, + PrivateKey: os.Getenv("MUMBAI_KEYS"), + MessageID: randNum, + Method: m.Method, + DonID: m.Cfg.Common.DONID, + S4SetSlotID: randSlot, + S4SetVersion: version, + S4SetExpirationPeriod: expiration, + }); err != nil { + return &wasp.CallResult{Error: err.Error(), Failed: true} + } + return &wasp.CallResult{} +} + +// Call implements example gun call, assertions on response bodies should be done here +func (m *GatewaySecretsSetGun) Call(_ *wasp.Generator) *wasp.CallResult { + var res *wasp.CallResult + switch m.Method { + case "secrets_set": + res = callSetSecrets(m) + case "secrets_list": + res = callSecretsList(m) + default: + panic("gateway gun must use either 'secrets_set' or 'list' methods") + } + return res +} diff --git a/integration-tests/load/functions/gateway_test.go b/integration-tests/load/functions/gateway_test.go new file mode 100644 index 00000000000..946afdd711a --- /dev/null +++ b/integration-tests/load/functions/gateway_test.go @@ -0,0 +1,73 @@ +package loadfunctions + +import ( + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + "github.com/smartcontractkit/wasp" + "github.com/stretchr/testify/require" + "testing" +) + +func TestGatewayLoad(t *testing.T) { + cfg, err := ReadConfig() + require.NoError(t, err) + ft, err := SetupLocalLoadTestEnv(cfg) + require.NoError(t, err) + ft.EVMClient.ParallelTransactions(false) + + labels := map[string]string{ + "branch": "gateway_healthcheck", + "commit": "gateway_healthcheck", + } + + secretsListCfg := &wasp.Config{ + LoadType: wasp.RPS, + GenName: functions.MethodSecretsList, + Schedule: wasp.Plain( + cfg.GatewayListSoak.RPS, + cfg.GatewayListSoak.Duration.Duration(), + ), + Gun: NewGatewaySecretsSetGun( + cfg, + functions.MethodSecretsList, + ft.EthereumPrivateKey, + ft.ThresholdPublicKey, + ft.DONPublicKey, + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + } + + secretsSetCfg := &wasp.Config{ + LoadType: wasp.RPS, + GenName: functions.MethodSecretsSet, + Schedule: wasp.Plain( + cfg.GatewaySetSoak.RPS, + cfg.GatewaySetSoak.Duration.Duration(), + ), + Gun: NewGatewaySecretsSetGun( + cfg, + functions.MethodSecretsSet, + ft.EthereumPrivateKey, + ft.ThresholdPublicKey, + ft.DONPublicKey, + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + } + + t.Run("gateway secrets list soak test", func(t *testing.T) { + secretsListCfg.T = t + _, err := wasp.NewProfile(). + Add(wasp.NewGenerator(secretsListCfg)). + Run(true) + require.NoError(t, err) + }) + + t.Run("gateway secrets set soak test", func(t *testing.T) { + secretsListCfg.T = t + _, err := wasp.NewProfile(). + Add(wasp.NewGenerator(secretsSetCfg)). + Run(true) + require.NoError(t, err) + }) +} diff --git a/integration-tests/load/functions/onchain_monitoring.go b/integration-tests/load/functions/onchain_monitoring.go new file mode 100644 index 00000000000..0a8b4cef46a --- /dev/null +++ b/integration-tests/load/functions/onchain_monitoring.go @@ -0,0 +1,61 @@ +package loadfunctions + +import ( + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/wasp" + "testing" + "time" +) + +/* Monitors on-chain stats of LoadConsumer and pushes them to Loki every second */ + +const ( + LokiTypeLabel = "functions_contracts_load_summary" + ErrMetrics = "failed to get Functions load test metrics" + ErrLokiClient = "failed to create Loki client for monitoring" + ErrLokiPush = "failed to push monitoring metrics to Loki" +) + +type LoadStats struct { + Succeeded uint32 + Errored uint32 + Empty uint32 +} + +func MonitorLoadStats(t *testing.T, ft *FunctionsTest, labels map[string]string) { + go func() { + updatedLabels := make(map[string]string) + for k, v := range labels { + updatedLabels[k] = v + } + updatedLabels["type"] = LokiTypeLabel + updatedLabels["go_test_name"] = t.Name() + updatedLabels["gen_name"] = "performance" + lc, err := wasp.NewLokiClient(wasp.NewEnvLokiConfig()) + if err != nil { + log.Error().Err(err).Msg(ErrLokiClient) + return + } + if err := ft.LoadTestClient.ResetStats(); err != nil { + log.Error().Err(err).Msg("failed to reset load test client stats") + } + for { + time.Sleep(5 * time.Second) + stats, err := ft.LoadTestClient.GetStats() + if err != nil { + log.Error().Err(err).Msg(ErrMetrics) + } + log.Info(). + Hex("LastReqID", []byte(stats.LastRequestID)). + Str("LastResponse", stats.LastResponse). + Str("LastError", stats.LastError). + Uint32("Total", stats.Total). + Uint32("Succeeded", stats.Succeeded). + Uint32("Errored", stats.Errored). + Uint32("Empty", stats.Empty).Msg("On-chain stats for load test client") + if err := lc.HandleStruct(wasp.LabelsMapToModel(updatedLabels), time.Now(), stats); err != nil { + log.Error().Err(err).Msg(ErrLokiPush) + } + } + }() +} diff --git a/integration-tests/load/functions/gun.go b/integration-tests/load/functions/request_gun.go similarity index 65% rename from integration-tests/load/functions/gun.go rename to integration-tests/load/functions/request_gun.go index 358e0acb986..5cbff36179e 100644 --- a/integration-tests/load/functions/gun.go +++ b/integration-tests/load/functions/request_gun.go @@ -7,7 +7,8 @@ import ( /* SingleFunctionCallGun is a gun that constantly requests randomness for one feed */ type SingleFunctionCallGun struct { - contracts *Contracts + ft *FunctionsTest + times uint32 source string encryptedSecretsReferences []byte args []string @@ -15,9 +16,10 @@ type SingleFunctionCallGun struct { jobId [32]byte } -func NewSingleFunctionCallGun(contracts *Contracts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) *SingleFunctionCallGun { +func NewSingleFunctionCallGun(ft *FunctionsTest, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) *SingleFunctionCallGun { return &SingleFunctionCallGun{ - contracts: contracts, + ft: ft, + times: times, source: source, encryptedSecretsReferences: encryptedSecretsReferences, args: args, @@ -28,7 +30,14 @@ func NewSingleFunctionCallGun(contracts *Contracts, source string, encryptedSecr // Call implements example gun call, assertions on response bodies should be done here func (m *SingleFunctionCallGun) Call(l *wasp.Generator) *wasp.CallResult { - err := m.contracts.LoadTestClient.SendRequest(m.source, m.encryptedSecretsReferences, m.args, m.subscriptionId, m.jobId) + err := m.ft.LoadTestClient.SendRequest( + m.times, + m.source, + m.encryptedSecretsReferences, + m.args, + m.subscriptionId, + m.jobId, + ) if err != nil { return &wasp.CallResult{Error: err.Error(), Failed: true} } diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go index cd8038c41ba..0433b5beb61 100644 --- a/integration-tests/load/functions/setup.go +++ b/integration-tests/load/functions/setup.go @@ -1,64 +1,173 @@ package loadfunctions import ( + "crypto/ecdsa" + "fmt" + "github.com/ethereum/go-ethereum/crypto" + "github.com/go-resty/resty/v2" "github.com/pkg/errors" "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/integration-tests/networks" chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy" "math/big" + mrand "math/rand" + "os" + "strconv" + "time" ) -type Contracts struct { - LinkToken contracts.LinkToken - Coordinator contracts.FunctionsCoordinator - Router contracts.FunctionsRouter - LoadTestClient contracts.FunctionsLoadTestClient +type FunctionsTest struct { + EVMClient blockchain.EVMClient + ContractDeployer contracts.ContractDeployer + ContractLoader contracts.ContractLoader + LinkToken contracts.LinkToken + Coordinator contracts.FunctionsCoordinator + Router contracts.FunctionsRouter + LoadTestClient contracts.FunctionsLoadTestClient + EthereumPrivateKey *ecdsa.PrivateKey + EthereumPublicKey *ecdsa.PublicKey + ThresholdPublicKey *tdh2easy.PublicKey + DONPublicKey []byte + ThresholdPublicKeyBytes []byte + ThresholdEncryptedSecrets string } -func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*test_env.CLClusterTestEnv, *Contracts, error) { - env, err := test_env.NewCLTestEnvBuilder(). - Build() +type S4SecretsCfg struct { + GatewayURL string + PrivateKey string + RecieverAddr string + MessageID string + Method string + DonID string + S4SetSlotID uint + S4SetVersion uint64 + S4SetExpirationPeriod int64 + S4SetPayload string +} + +func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*FunctionsTest, error) { + bc, err := blockchain.NewEVMClientFromNetwork(networks.SelectedNetwork) + if err != nil { + return nil, err + } + cd, err := contracts.NewContractDeployer(bc) + if err != nil { + return nil, err + } + + cl, err := contracts.NewContractLoader(bc) if err != nil { - return env, nil, err + return nil, err } - env.EVMClient.GetNonceSetting() - lt, err := env.ContractLoader.LoadLINKToken(cfg.Common.LINKTokenAddr) if err != nil { - return env, nil, err + return nil, err } - coord, err := env.ContractLoader.LoadFunctionsCoordinator(cfg.Common.Coordinator) + lt, err := cl.LoadLINKToken(cfg.Common.LINKTokenAddr) if err != nil { - return env, nil, err + return nil, err } - router, err := env.ContractLoader.LoadFunctionsRouter(cfg.Common.Router) + coord, err := cl.LoadFunctionsCoordinator(cfg.Common.Coordinator) if err != nil { - return env, nil, err + return nil, err } - loadTestClient, err := env.ContractLoader.LoadFunctionsLoadTestClient(cfg.Common.LoadTestClient) + router, err := cl.LoadFunctionsRouter(cfg.Common.Router) if err != nil { - return env, nil, err + return nil, err + } + var loadTestClient contracts.FunctionsLoadTestClient + if cfg.Common.LoadTestClient != "" { + loadTestClient, err = cl.LoadFunctionsLoadTestClient(cfg.Common.LoadTestClient) + } else { + loadTestClient, err = cd.DeployFunctionsLoadTestClient(cfg.Common.Router) + } + if err != nil { + return nil, err } if cfg.Common.SubscriptionID == 0 { log.Info().Msg("Creating new subscription") subID, err := router.CreateSubscriptionWithConsumer(loadTestClient.Address()) if err != nil { - return env, nil, errors.Wrap(err, "failed to create a new subscription") + return nil, errors.Wrap(err, "failed to create a new subscription") } encodedSubId, err := chainlinkutils.ABIEncode(`[{"type":"uint64"}]`, subID) if err != nil { - return env, nil, errors.Wrap(err, "failed to encode subscription ID for funding") + return nil, errors.Wrap(err, "failed to encode subscription ID for funding") } _, err = lt.TransferAndCall(router.Address(), big.NewInt(0).Mul(cfg.Common.Funding.SubFunds, big.NewInt(1e18)), encodedSubId) if err != nil { - return env, nil, errors.Wrap(err, "failed to transferAndCall router, LINK funding") + return nil, errors.Wrap(err, "failed to transferAndCall router, LINK funding") } cfg.Common.SubscriptionID = subID } - return env, &Contracts{ - LinkToken: lt, - Coordinator: coord, - Router: router, - LoadTestClient: loadTestClient, + pKey, pubKey, err := parseEthereumPrivateKey(os.Getenv("MUMBAI_KEYS")) + if err != nil { + return nil, errors.Wrap(err, "failed to load Ethereum private key") + } + tpk, err := coord.GetThresholdPublicKey() + if err != nil { + return nil, errors.Wrap(err, "failed to get Threshold public key") + } + log.Info().Hex("ThresholdPublicKeyBytesHex", tpk).Msg("Loaded coordinator keys") + donPubKey, err := coord.GetDONPublicKey() + if err != nil { + return nil, errors.Wrap(err, "failed to get DON public key") + } + log.Info().Hex("DONPublicKeyHex", donPubKey).Msg("Loaded coordinator keys") + tdh2pk, err := ParseTDH2Key(tpk) + if err != nil { + return nil, errors.Wrap(err, "failed to unmarshal tdh2 public key") + } + var encryptedSecrets string + if cfg.Common.Secrets != "" { + encryptedSecrets, err = EncryptS4Secrets(pKey, tdh2pk, donPubKey, cfg.Common.Secrets) + if err != nil { + return nil, errors.Wrap(err, "failed to generate tdh2 secrets") + } + if err := UploadS4Secrets(resty.New(), &S4SecretsCfg{ + GatewayURL: fmt.Sprintf("%s/user", cfg.Common.GatewayURL), + PrivateKey: cfg.MumbaiPrivateKey, + MessageID: strconv.Itoa(mrand.Intn(100000-1) + 1), + Method: "secrets_set", + DonID: cfg.Common.DONID, + S4SetSlotID: uint(mrand.Intn(5)), + S4SetVersion: uint64(time.Now().UnixNano()), + S4SetExpirationPeriod: 60 * 60 * 1000, + S4SetPayload: encryptedSecrets, + }); err != nil { + return nil, errors.Wrap(err, "failed to upload secrets to S4") + } + } + return &FunctionsTest{ + EVMClient: bc, + ContractDeployer: cd, + ContractLoader: cl, + LinkToken: lt, + Coordinator: coord, + Router: router, + LoadTestClient: loadTestClient, + EthereumPrivateKey: pKey, + EthereumPublicKey: pubKey, + ThresholdPublicKey: tdh2pk, + ThresholdPublicKeyBytes: tpk, + ThresholdEncryptedSecrets: encryptedSecrets, + DONPublicKey: donPubKey, }, nil } + +func parseEthereumPrivateKey(pk string) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) { + pKey, err := crypto.HexToECDSA(pk) + if err != nil { + return nil, nil, errors.Wrap(err, "failed to convert Ethereum key from hex") + } + + publicKey := pKey.Public() + pubKey, ok := publicKey.(*ecdsa.PublicKey) + if !ok { + return nil, nil, errors.Wrap(err, "failed to get public key from Ethereum private key") + } + log.Info().Str("Address", crypto.PubkeyToAddress(*pubKey).Hex()).Msg("Parsed private key for address") + return pKey, pubKey, nil +} diff --git a/integration-tests/networks/known_networks.go b/integration-tests/networks/known_networks.go index 1fdd35e93c2..41148ba2043 100644 --- a/integration-tests/networks/known_networks.go +++ b/integration-tests/networks/known_networks.go @@ -300,11 +300,11 @@ var ( ChainID: 80001, Simulated: false, ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, + Timeout: blockchain.JSONStrDuration{Duration: 3 * time.Minute}, MinimumConfirmations: 1, - GasEstimationBuffer: 1000, + GasEstimationBuffer: 100000, FinalityDepth: 550, - DefaultGasLimit: 6000000, + DefaultGasLimit: 8000000, } AvalancheMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ From 11490c64325053d2d50f9c9e077cc5d7dbe488d0 Mon Sep 17 00:00:00 2001 From: David Cauchi <13139524+davidcauchi@users.noreply.github.com> Date: Fri, 1 Sep 2023 19:44:52 +0200 Subject: [PATCH 02/88] Add regex to include config toml files (#10440) --- .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 027f60e6bb6..74ce6edac25 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -41,6 +41,7 @@ jobs: - '**/*go.mod' - '.github/workflows/integration-tests.yml' - '**/*Dockerfile' + - 'core/**/config/**/*.toml' - name: Collect Metrics if: always() id: collect-gha-metrics From 50d5570b2bc9863c8898a60604a8404f4ecd3c24 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 1 Sep 2023 16:49:05 -0400 Subject: [PATCH 03/88] [TT-549] Renable Live Test Runs (#10379) * Debug on * Bypass build test * Change secret names * Strip Private Keys * Fix strip * Fix funding * Clean imports * Cleanup * Formatting * Remove if check * Regularly Scheduled Programming --- .github/workflows/integration-tests.yml | 10 ++--- integration-tests/actions/actions.go | 9 ++-- .../actions/automation_ocr_helpers.go | 16 +++---- integration-tests/docker/test_env/cl_node.go | 7 ++- integration-tests/docker/test_env/test_env.go | 43 +++++++++++++++++- .../docker/test_env/test_env_builder.go | 3 +- integration-tests/networks/known_networks.go | 13 +++--- integration-tests/smoke/automation_test.go | 44 ++++++++++++++----- integration-tests/smoke/cron_test.go | 15 ++++++- integration-tests/smoke/flux_test.go | 19 +++++--- integration-tests/smoke/forwarder_ocr_test.go | 18 ++++++-- .../smoke/forwarders_ocr2_test.go | 12 ++++- integration-tests/smoke/keeper_test.go | 10 ++++- integration-tests/smoke/ocr2_test.go | 17 +++++-- integration-tests/smoke/ocr_test.go | 24 ++++++---- integration-tests/smoke/runlog_test.go | 19 +++++--- integration-tests/smoke/vrf_test.go | 19 +++++--- integration-tests/smoke/vrfv2_test.go | 8 +++- integration-tests/smoke/vrfv2plus_test.go | 19 +++++--- integration-tests/types/config/node/core.go | 3 +- 20 files changed, 244 insertions(+), 84 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 74ce6edac25..8c1d5be828c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -803,7 +803,7 @@ jobs: pull-requests: write id-token: write contents: read - needs: [build-chainlink, build-test-image] + needs: [build-chainlink] env: SELECTED_NETWORKS: ${{ matrix.testnet }} CHAINLINK_COMMIT_SHA: ${{ github.sha }} @@ -812,11 +812,11 @@ jobs: EVM_KEYS: ${{ secrets.QA_EVM_KEYS }} TEST_EVM_KEYS: ${{ secrets.QA_EVM_KEYS }} - TEST_OPTIMISM_GOERLI_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_URLS }} - TEST_OPTIMISM_GOERLI_HTTP_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_HTTP_URLS }} + OPTIMISM_GOERLI_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_URLS }} + OPTIMISM_GOERLI_HTTP_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_HTTP_URLS }} - TEST_ARBITRUM_GOERLI_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_URLS }} - TEST_ARBITRUM_GOERLI_HTTP_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_HTTP_URLS }} + ARBITRUM_GOERLI_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_URLS }} + ARBITRUM_GOERLI_HTTP_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_HTTP_URLS }} strategy: fail-fast: false matrix: diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index ffb71cb7424..82187fd0cb8 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -263,7 +263,7 @@ func TeardownSuite( for _, c := range clients { if c != nil && chainlinkNodes != nil && len(chainlinkNodes) > 0 { - if err := returnFunds(chainlinkNodes, c); err != nil { + if err := ReturnFunds(chainlinkNodes, c); err != nil { // This printed line is required for tests that use real funds to propagate the failure // out to the system running the test. Do not remove fmt.Println(environment.FAILED_FUND_RETURN) @@ -306,7 +306,7 @@ func TeardownRemoteSuite( l.Warn().Msgf("Error deleting jobs %+v", err) } - if err = returnFunds(chainlinkNodes, client); err != nil { + if err = ReturnFunds(chainlinkNodes, client); err != nil { l.Error().Err(err).Str("Namespace", namespace). Msg("Error attempting to return funds from chainlink nodes to network's default wallet. " + "Environment is left running so you can try manually!") @@ -337,8 +337,9 @@ func DeleteAllJobs(chainlinkNodes []*client.ChainlinkK8sClient) error { return nil } -// Returns all the funds from the chainlink nodes to the networks default address -func returnFunds(chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient blockchain.EVMClient) error { +// ReturnFunds attempts to return all the funds from the chainlink nodes to the network's default address +// all from a remote, k8s style environment +func ReturnFunds(chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient blockchain.EVMClient) error { if blockchainClient == nil { return errors.New("blockchain client is nil, unable to return funds from chainlink nodes") } diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index a2f2633f68d..bfea6ec302c 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -11,25 +11,23 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - "github.com/stretchr/testify/require" - "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "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" ocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2keepers20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config" ocr2keepers30config "github.com/smartcontractkit/ocr2keepers/pkg/v3/config" + "github.com/stretchr/testify/require" + "gopkg.in/guregu/null.v4" "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/libocr/offchainreporting2plus/types" - - "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( diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index 0ec62808feb..a78f9e52ad6 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -18,17 +18,16 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/pkg/errors" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" tc "github.com/testcontainers/testcontainers-go" tcwait "github.com/testcontainers/testcontainers-go/wait" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/logwatch" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" - "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/utils" diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go index c056e92b9fc..e90bf5618ab 100644 --- a/integration-tests/docker/test_env/test_env.go +++ b/integration-tests/docker/test_env/test_env.go @@ -1,8 +1,10 @@ package test_env import ( + "encoding/json" "math/big" + "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/rs/zerolog/log" @@ -12,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/logwatch" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/integration-tests/client" @@ -194,3 +195,43 @@ func (te *CLClusterTestEnv) Terminate() error { // the containers and the Network return nil } + +// Cleanup cleans the environment up after it's done being used, mainly for returning funds when on live networks. +// Intended to be used as part of t.Cleanup() in tests. +func (te *CLClusterTestEnv) Cleanup() error { + log.Info().Msg("Attempting to return Chainlink node funds to default network wallets") + if te.EVMClient == nil { + return errors.New("blockchain client is nil, unable to return funds from chainlink nodes") + } + if te.CLNodes == nil { + return errors.New("chainlink nodes are nil, unable to return funds from chainlink nodes") + } + if te.EVMClient.NetworkSimulated() { + log.Info().Str("Network Name", te.EVMClient.GetNetworkName()). + Msg("Network is a simulated network. Skipping fund return.") + return nil + } + + for _, chainlinkNode := range te.CLNodes { + fundedKeys, err := chainlinkNode.API.ExportEVMKeysForChain(te.EVMClient.GetChainID().String()) + if err != nil { + return err + } + for _, key := range fundedKeys { + keyToDecrypt, err := json.Marshal(key) + if err != nil { + return err + } + // This can take up a good bit of RAM and time. When running on the remote-test-runner, this can lead to OOM + // issues. So we avoid running in parallel; slower, but safer. + decryptedKey, err := keystore.DecryptKey(keyToDecrypt, client.ChainlinkKeyPassword) + if err != nil { + return err + } + if err = te.EVMClient.ReturnFunds(decryptedKey.PrivateKey); err != nil { + return err + } + } + } + return nil +} diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index bacee0c956f..27f98b36139 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -6,11 +6,10 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/logwatch" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/networks/known_networks.go b/integration-tests/networks/known_networks.go index 41148ba2043..4d12d6b5b60 100644 --- a/integration-tests/networks/known_networks.go +++ b/integration-tests/networks/known_networks.go @@ -558,17 +558,18 @@ func setKeys(prefix string, network *blockchain.EVMNetwork) { } envVar := fmt.Sprintf("%s_KEYS", prefix) - keysEnv, err := utils.GetEnv(envVar) + keysFromEnv, err := utils.GetEnv(envVar) if err != nil { log.Fatal().Err(err).Str("env var", envVar).Msg("Error getting env var") } - if keysEnv == "" { - keys := strings.Split(os.Getenv("EVM_KEYS"), ",") + if keysFromEnv == "" { log.Warn().Msg(fmt.Sprintf("No '%s' env var defined, defaulting to 'EVM_KEYS'", envVar)) - network.PrivateKeys = keys - return + keysFromEnv = os.Getenv("EVM_KEYS") + } + keys := strings.Split(keysFromEnv, ",") + for i, key := range keys { + keys[i] = strings.TrimPrefix(key, "0x") } - keys := strings.Split(keysEnv, ",") network.PrivateKeys = keys // log public keys for debugging diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 8855a8a125d..5aa7668d151 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/onsi/gomega" + "github.com/rs/zerolog/log" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" @@ -108,7 +109,9 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -234,7 +237,9 @@ func TestAutomationAddFunds(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -288,7 +293,9 @@ func TestAutomationPauseUnPause(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -303,7 +310,7 @@ func TestAutomationPauseUnPause(t *testing.T) { gom := gomega.NewGomegaWithT(t) gom.Eventually(func(g gomega.Gomega) { - // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5 + // Check if the upkeeps are performing multiple times by analyzing their counters and checking they are greater than 5 for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) @@ -374,7 +381,9 @@ func TestAutomationRegisterUpkeep(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -448,7 +457,9 @@ func TestAutomationPauseRegistry(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( @@ -508,7 +519,9 @@ func TestAutomationKeeperNodesDown(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -596,7 +609,9 @@ func TestAutomationPerformSimulation(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -663,7 +678,9 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -779,7 +796,9 @@ func TestUpdateCheckData(t *testing.T) { "registry_2_1": ethereum.RegistryVersion_2_1, } - for name, registryVersion := range registryVersions { + for n, rv := range registryVersions { + name := n + registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() @@ -902,6 +921,11 @@ func setupAutomationTest( require.NoError(t, err, "Error building contract deployer") chainlinkNodes, err = client.ConnectChainlinkNodes(testEnvironment) require.NoError(t, err, "Error connecting to Chainlink nodes") + t.Cleanup(func() { + if err := actions.ReturnFunds(chainlinkNodes, chainClient); err != nil { + log.Error().Err(err).Msg("Error returning funds") + } + }) chainClient.ParallelTransactions(true) txCost, err := chainClient.EstimateCostForChainlinkOperations(1000) diff --git a/integration-tests/smoke/cron_test.go b/integration-tests/smoke/cron_test.go index 30eadb8f16b..0285e2d23c7 100644 --- a/integration-tests/smoke/cron_test.go +++ b/integration-tests/smoke/cron_test.go @@ -2,16 +2,21 @@ package smoke import ( "fmt" + "testing" + "github.com/google/uuid" "github.com/onsi/gomega" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/stretchr/testify/require" - "testing" ) func TestCronBasic(t *testing.T) { t.Parallel() + l := utils.GetTestLogger(t) env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). @@ -19,6 +24,12 @@ func TestCronBasic(t *testing.T) { WithCLNodes(1). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) + err = env.MockServer.Client.SetValuePath("/variable", 5) require.NoError(t, err, "Setting value path in mockserver shouldn't fail") diff --git a/integration-tests/smoke/flux_test.go b/integration-tests/smoke/flux_test.go index da06fc4b57a..c4cd02b857d 100644 --- a/integration-tests/smoke/flux_test.go +++ b/integration-tests/smoke/flux_test.go @@ -3,18 +3,21 @@ package smoke import ( "context" "fmt" + "math/big" + "strings" + "testing" + "time" + "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "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/docker/test_env" - "github.com/stretchr/testify/require" - "math/big" - "strings" - "testing" - "time" ) func TestFluxBasic(t *testing.T) { @@ -27,6 +30,12 @@ func TestFluxBasic(t *testing.T) { WithCLNodes(3). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) + nodeAddresses, err := env.ChainlinkNodeAddresses() require.NoError(t, err, "Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail") env.EVMClient.ParallelTransactions(true) diff --git a/integration-tests/smoke/forwarder_ocr_test.go b/integration-tests/smoke/forwarder_ocr_test.go index 0b58be41d74..e4cf5cb0527 100644 --- a/integration-tests/smoke/forwarder_ocr_test.go +++ b/integration-tests/smoke/forwarder_ocr_test.go @@ -1,26 +1,37 @@ package smoke import ( + "context" "math/big" "testing" - "context" "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/stretchr/testify/require" ) func TestForwarderOCRBasic(t *testing.T) { t.Parallel() + l := utils.GetTestLogger(t) + env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). WithMockServer(1). WithForwarders(). WithCLNodes(6). - WithFunding(big.NewFloat(10)). + WithFunding(big.NewFloat(.1)). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) + env.ParallelTransactions(true) nodeClients := env.GetAPIs() @@ -55,6 +66,7 @@ func TestForwarderOCRBasic(t *testing.T) { authorizedForwarders, env.EVMClient, ) + require.NoError(t, err, "Error deploying OCR contracts") err = actions.CreateOCRJobsWithForwarderLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client) require.NoError(t, err, "failed to setup forwarder jobs") diff --git a/integration-tests/smoke/forwarders_ocr2_test.go b/integration-tests/smoke/forwarders_ocr2_test.go index cb6a3f0556d..81c521ff387 100644 --- a/integration-tests/smoke/forwarders_ocr2_test.go +++ b/integration-tests/smoke/forwarders_ocr2_test.go @@ -10,6 +10,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" @@ -17,6 +19,8 @@ import ( func TestForwarderOCR2Basic(t *testing.T) { t.Parallel() + l := utils.GetTestLogger(t) + env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). WithMockServer(1). @@ -26,9 +30,15 @@ func TestForwarderOCR2Basic(t *testing.T) { )). WithForwarders(). WithCLNodes(6). - WithFunding(big.NewFloat(10)). + WithFunding(big.NewFloat(.1)). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) + env.ParallelTransactions(true) nodeClients := env.GetAPIs() diff --git a/integration-tests/smoke/keeper_test.go b/integration-tests/smoke/keeper_test.go index 00cbe07eb0f..f07c42ab3d8 100644 --- a/integration-tests/smoke/keeper_test.go +++ b/integration-tests/smoke/keeper_test.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" @@ -21,7 +22,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" - "github.com/smartcontractkit/chainlink/v2/core/store/models" ) const ( @@ -105,7 +105,7 @@ func TestKeeperBasicSmoke(t *testing.T) { require.NoError(t, err, "Error creating keeper jobs") gom.Eventually(func(g gomega.Gomega) error { - // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 10 + // Check if the upkeeps are performing multiple times by analyzing their counters and checking they are greater than 10 for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) @@ -1089,6 +1089,7 @@ func setupKeeperTest(t *testing.T) ( clNodeConfig.Keeper.TurnLookBack = &turnLookBack clNodeConfig.Keeper.Registry.SyncInterval = &syncInterval clNodeConfig.Keeper.Registry.PerformGasOverhead = &performGasOverhead + l := utils.GetTestLogger(t) env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). @@ -1098,6 +1099,11 @@ func setupKeeperTest(t *testing.T) ( WithFunding(big.NewFloat(.5)). Build() require.NoError(t, err, "Error deploying test environment") + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) env.ParallelTransactions(true) diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 7dd0b23223c..6588586c39d 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -4,27 +4,32 @@ import ( "context" "fmt" "math/big" + "strings" "testing" "time" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-env/environment" "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" - "github.com/stretchr/testify/require" - "strings" ) // Tests a basic OCRv2 median feed func TestOCRv2Basic(t *testing.T) { + l := utils.GetTestLogger(t) + env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). WithMockServer(1). @@ -33,9 +38,15 @@ func TestOCRv2Basic(t *testing.T) { node.WithP2Pv2(), )). WithCLNodes(6). - WithFunding(big.NewFloat(10)). + WithFunding(big.NewFloat(.1)). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) + env.ParallelTransactions(true) nodeClients := env.GetAPIs() diff --git a/integration-tests/smoke/ocr_test.go b/integration-tests/smoke/ocr_test.go index 1ae52ade305..50d6abe662b 100644 --- a/integration-tests/smoke/ocr_test.go +++ b/integration-tests/smoke/ocr_test.go @@ -1,24 +1,35 @@ package smoke import ( + "context" + "math/big" "testing" - "context" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/stretchr/testify/require" - "math/big" ) func TestOCRBasic(t *testing.T) { t.Parallel() + l := utils.GetTestLogger(t) + env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). WithMockServer(1). WithCLNodes(6). - WithFunding(big.NewFloat(10)). + WithFunding(big.NewFloat(.1)). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) + env.ParallelTransactions(true) nodeClients := env.GetAPIs() @@ -27,9 +38,6 @@ func TestOCRBasic(t *testing.T) { linkTokenContract, err := env.ContractDeployer.DeployLinkTokenContract() require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, big.NewFloat(.05)) - require.NoError(t, err, "Error funding Chainlink nodes") - ocrInstances, err := actions.DeployOCRContractsLocal(1, linkTokenContract, env.ContractDeployer, workerNodes, env.EVMClient) require.NoError(t, err) err = env.EVMClient.WaitForEvents() @@ -38,7 +46,7 @@ func TestOCRBasic(t *testing.T) { err = actions.CreateOCRJobsLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client) require.NoError(t, err) - _ = actions.StartNewRound(1, ocrInstances, env.EVMClient) + err = actions.StartNewRound(1, ocrInstances, env.EVMClient) require.NoError(t, err) answer, err := ocrInstances[0].GetLatestAnswer(context.Background()) diff --git a/integration-tests/smoke/runlog_test.go b/integration-tests/smoke/runlog_test.go index d40d5677fde..cd2a099b142 100644 --- a/integration-tests/smoke/runlog_test.go +++ b/integration-tests/smoke/runlog_test.go @@ -3,27 +3,36 @@ package smoke import ( "context" "fmt" + "math/big" + "strings" + "testing" + "github.com/google/uuid" "github.com/onsi/gomega" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/stretchr/testify/require" - "math/big" - "strings" - "testing" ) func TestRunLogBasic(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) + env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). WithMockServer(1). WithCLNodes(1). - WithFunding(big.NewFloat(1)). + WithFunding(big.NewFloat(.1)). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) lt, err := env.ContractDeployer.DeployLinkTokenContract() require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") diff --git a/integration-tests/smoke/vrf_test.go b/integration-tests/smoke/vrf_test.go index 2f3a8bb40f5..0e12b185a6a 100644 --- a/integration-tests/smoke/vrf_test.go +++ b/integration-tests/smoke/vrf_test.go @@ -3,29 +3,38 @@ package smoke import ( "context" "fmt" + "math/big" + "testing" + "time" + "github.com/google/uuid" "github.com/onsi/gomega" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv1" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/stretchr/testify/require" - "math/big" - "testing" - "time" ) func TestVRFBasic(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) + env, err := test_env.NewCLTestEnvBuilder(). WithGeth(). WithMockServer(1). WithCLNodes(1). - WithFunding(big.NewFloat(1)). + WithFunding(big.NewFloat(.1)). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) env.ParallelTransactions(true) lt, err := actions.DeployLINKToken(env.ContractDeployer) diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index ed9b9f16318..41f9d2ee5ee 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -7,9 +7,10 @@ import ( "time" "github.com/onsi/gomega" - "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions" vrfConst "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" @@ -27,6 +28,11 @@ func TestVRFv2Basic(t *testing.T) { WithFunding(vrfConst.ChainlinkNodeFundingAmountEth). Build() require.NoError(t, err) + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) env.ParallelTransactions(true) mockFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfConst.LinkEthFeedResponse) diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index b3a99f8ca4e..9b6dc5a8626 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -2,16 +2,18 @@ package smoke import ( "context" - "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus" - "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus/vrfv2plus_constants" - "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "math/big" "testing" "time" - "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/utils" + + "github.com/smartcontractkit/chainlink/integration-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus" + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus/vrfv2plus_constants" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" ) func TestVRFv2PlusBilling(t *testing.T) { @@ -23,8 +25,12 @@ func TestVRFv2PlusBilling(t *testing.T) { WithCLNodes(1). WithFunding(vrfv2plus_constants.ChainlinkNodeFundingAmountEth). Build() - require.NoError(t, err, "error creating test env") + t.Cleanup(func() { + if err := env.Cleanup(); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + }) env.ParallelTransactions(true) @@ -51,6 +57,7 @@ func TestVRFv2PlusBilling(t *testing.T) { subBalanceBeforeRequest := subscription.Balance jobRunsBeforeTest, err := env.CLNodes[0].API.MustReadRunsByJob(job.Job.Data.ID) + require.NoError(t, err, "error reading job runs") // test and assert err = vrfv2PlusContracts.LoadTestConsumer.RequestRandomness( diff --git a/integration-tests/types/config/node/core.go b/integration-tests/types/config/node/core.go index 4e60e1ece5c..0d433daa1b4 100644 --- a/integration-tests/types/config/node/core.go +++ b/integration-tests/types/config/node/core.go @@ -10,8 +10,6 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - - utils2 "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/smartcontractkit/chainlink/v2/core/assets" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/config/toml" @@ -22,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils/config" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" + utils2 "github.com/smartcontractkit/chainlink/integration-tests/utils" ) var ( From ceea5fb045b644af9985e925703209852b0684c7 Mon Sep 17 00:00:00 2001 From: jinhoonbang Date: Fri, 1 Sep 2023 22:52:49 -0700 Subject: [PATCH 04/88] =?UTF-8?q?remove=20check=20for=20finality=20depth?= =?UTF-8?q?=20in=20bhs=20and=20bhf.=20Do=20not=20update=20interna=E2=80=A6?= =?UTF-8?q?=20(#10391)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove check for finality depth in bhs and bhf. Do not update internal stored mapping based on IsStored() * fix delegate_test.go * address comments for trusted bhs. revert blockheaderfeeder changes * add a debug log * fix failing test --- core/services/blockhashstore/delegate.go | 6 - core/services/blockhashstore/delegate_test.go | 8 - core/services/blockhashstore/feeder.go | 48 ++-- core/services/blockhashstore/feeder_test.go | 210 ++++++++++-------- 4 files changed, 140 insertions(+), 132 deletions(-) diff --git a/core/services/blockhashstore/delegate.go b/core/services/blockhashstore/delegate.go index f3008af7b8b..0342dff78b7 100644 --- a/core/services/blockhashstore/delegate.go +++ b/core/services/blockhashstore/delegate.go @@ -65,12 +65,6 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC return nil, errors.New("log poller must be enabled to run blockhashstore") } - if jb.BlockhashStoreSpec.WaitBlocks < int32(chain.Config().EVM().FinalityDepth()) { - return nil, fmt.Errorf( - "waitBlocks must be greater than or equal to chain's finality depth (%d), currently %d", - chain.Config().EVM().FinalityDepth(), jb.BlockhashStoreSpec.WaitBlocks) - } - keys, err := d.ks.EnabledKeysForChain(chain.ID()) if err != nil { return nil, errors.Wrap(err, "getting sending keys") diff --git a/core/services/blockhashstore/delegate_test.go b/core/services/blockhashstore/delegate_test.go index b0456206861..3a9c01ae399 100644 --- a/core/services/blockhashstore/delegate_test.go +++ b/core/services/blockhashstore/delegate_test.go @@ -128,14 +128,6 @@ func TestDelegate_ServicesForSpec(t *testing.T) { assert.Error(t, err) }) - t.Run("WaitBlocks less than EvmFinalityDepth", func(t *testing.T) { - spec := job.Job{BlockhashStoreSpec: &job.BlockhashStoreSpec{ - WaitBlocks: defaultWaitBlocks - 1, - }} - _, err := delegate.ServicesForSpec(spec) - assert.Error(t, err) - }) - t.Run("missing EnabledKeysForChain", func(t *testing.T) { _, err := testData.ethKeyStore.Delete(testData.sendingKey.ID()) require.NoError(t, err) diff --git a/core/services/blockhashstore/feeder.go b/core/services/blockhashstore/feeder.go index 22bbf7f163d..14e51e68394 100644 --- a/core/services/blockhashstore/feeder.go +++ b/core/services/blockhashstore/feeder.go @@ -37,6 +37,7 @@ func NewFeeder( lookbackBlocks: lookbackBlocks, latestBlock: latestBlock, stored: make(map[uint64]struct{}), + storedTrusted: make(map[uint64]common.Hash), lastRunBlock: 0, wgStored: sync.WaitGroup{}, } @@ -54,12 +55,12 @@ type Feeder struct { lookbackBlocks int latestBlock func(ctx context.Context) (uint64, error) - stored map[uint64]struct{} - lastRunBlock uint64 - wgStored sync.WaitGroup - batchLock sync.Mutex - storedLock sync.RWMutex - errsLock sync.Mutex + stored map[uint64]struct{} // used for trustless feeder + storedTrusted map[uint64]common.Hash // used for trusted feeder + lastRunBlock uint64 + wgStored sync.WaitGroup + batchLock sync.Mutex + errsLock sync.Mutex } // Run the feeder. @@ -103,10 +104,10 @@ func (f *Feeder) Run(ctx context.Context) error { "block", block) errs = multierr.Append(errs, errors.Wrap(err, "checking if stored")) } else if stored { + // IsStored() can be based on unfinalized blocks. Therefore, f.stored mapping is not updated f.lggr.Infow("Blockhash already stored", "block", block, "latestBlock", latestBlock, "unfulfilledReqIDs", LimitReqIDs(unfulfilledReqs, 50)) - f.stored[block] = struct{}{} continue } @@ -161,13 +162,6 @@ func (f *Feeder) runTrusted( if len(unfulfilled) == 0 { return } - f.storedLock.RLock() - if _, ok := f.stored[block]; ok { - // Already stored - f.storedLock.RUnlock() - return - } - f.storedLock.RUnlock() // Do not store a block if it has been marked as stored; otherwise, store it even // if the RPC call errors, as to be conservative. @@ -185,9 +179,6 @@ func (f *Feeder) runTrusted( f.lggr.Infow("Blockhash already stored", "block", block, "latestBlock", latestBlock, "unfulfilledReqIDs", LimitReqIDs(unfulfilled, 50)) - f.storedLock.Lock() - f.stored[block] = struct{}{} - f.storedLock.Unlock() return } @@ -224,15 +215,23 @@ func (f *Feeder) runTrusted( // append its blockhash to our blockhashes we want to store. // If it is the log poller block pertaining to our recent block number, assig it. for _, b := range lpBlocks { + if b.BlockNumber == int64(latestBlock) { + latestBlockhash = b.BlockHash + } + if f.storedTrusted[uint64(b.BlockNumber)] == b.BlockHash { + // blockhash is already stored. skip to save gas + continue + } if _, ok := batch[uint64(b.BlockNumber)]; ok { blocksToStore = append(blocksToStore, uint64(b.BlockNumber)) blockhashesToStore = append(blockhashesToStore, b.BlockHash) } - if b.BlockNumber == int64(latestBlock) { - latestBlockhash = b.BlockHash - } } + if len(blocksToStore) == 0 { + f.lggr.Debugw("no blocks to store", "latestBlock", latestBlock) + return errs + } // Store the batch of blocks and their blockhashes. err = f.bhs.StoreTrusted(ctx, blocksToStore, blockhashesToStore, latestBlock, latestBlockhash) if err != nil { @@ -246,12 +245,15 @@ func (f *Feeder) runTrusted( errs = multierr.Append(errs, errors.Wrap(err, "checking if stored")) return errs } + for i, block := range blocksToStore { + f.storedTrusted[block] = blockhashesToStore[i] + } } - // Prune stored, anything older than fromBlock can be discarded. - for b := range f.stored { + // Prune storedTrusted, anything older than fromBlock can be discarded. + for b := range f.storedTrusted { if b < fromBlock { - delete(f.stored, b) + delete(f.storedTrusted, b) } } diff --git a/core/services/blockhashstore/feeder_test.go b/core/services/blockhashstore/feeder_test.go index 7efb7052985..e015253ba28 100644 --- a/core/services/blockhashstore/feeder_test.go +++ b/core/services/blockhashstore/feeder_test.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" mocklp "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -46,61 +47,67 @@ var ( _ Coordinator = &TestCoordinator{} _ BHS = &TestBHS{} tests = []struct { - name string - requests []Event - fulfillments []Event - wait int - lookback int - latest uint64 - bhs TestBHS - expectedStored []uint64 - expectedErrMsg string + name string + requests []Event + fulfillments []Event + wait int + lookback int + latest uint64 + bhs TestBHS + expectedStored []uint64 + expectedStoredMapBlocks []uint64 // expected state of stored map in Feeder struct + expectedErrMsg string }{ { - name: "single unfulfilled request", - requests: []Event{{Block: 150, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{150}, + name: "single unfulfilled request", + requests: []Event{{Block: 150, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{150}, + expectedStoredMapBlocks: []uint64{150}, }, { - name: "single fulfilled request", - requests: []Event{{Block: 150, ID: "1000"}}, - fulfillments: []Event{{Block: 155, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{}, + name: "single fulfilled request", + requests: []Event{{Block: 150, ID: "1000"}}, + fulfillments: []Event{{Block: 155, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{}, + expectedStoredMapBlocks: []uint64{}, }, { - name: "single already fulfilled", - requests: []Event{{Block: 150, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 200, - bhs: TestBHS{Stored: []uint64{150}}, - expectedStored: []uint64{150}, + name: "single already fulfilled", + requests: []Event{{Block: 150, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 200, + bhs: TestBHS{Stored: []uint64{150}}, + expectedStored: []uint64{150}, + expectedStoredMapBlocks: []uint64{}, }, { - name: "error checking if stored, store anyway", - requests: []Event{{Block: 150, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 200, - bhs: TestBHS{ErrorsIsStored: []uint64{150}}, - expectedStored: []uint64{150}, - expectedErrMsg: "checking if stored: error checking if stored", + name: "error checking if stored, store anyway", + requests: []Event{{Block: 150, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 200, + bhs: TestBHS{ErrorsIsStored: []uint64{150}}, + expectedStored: []uint64{150}, + expectedStoredMapBlocks: []uint64{150}, + expectedErrMsg: "checking if stored: error checking if stored", }, { - name: "error storing, continue to next block anyway", - requests: []Event{{Block: 150, ID: "1000"}, {Block: 151, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 200, - bhs: TestBHS{ErrorsStore: []uint64{150}}, - expectedStored: []uint64{151}, - expectedErrMsg: "storing block: error storing", + name: "error storing, continue to next block anyway", + requests: []Event{{Block: 150, ID: "1000"}, {Block: 151, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 200, + bhs: TestBHS{ErrorsStore: []uint64{150}}, + expectedStored: []uint64{151}, + expectedStoredMapBlocks: []uint64{151}, + expectedErrMsg: "storing block: error storing", }, { name: "multiple requests same block, some fulfilled", @@ -111,10 +118,11 @@ var ( fulfillments: []Event{ {Block: 150, ID: "10001"}, {Block: 150, ID: "10003"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{150}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{150}, + expectedStoredMapBlocks: []uint64{150}, }, { name: "multiple requests same block, all fulfilled", @@ -126,52 +134,58 @@ var ( {Block: 150, ID: "10001"}, {Block: 150, ID: "10002"}, {Block: 150, ID: "10003"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{}, + expectedStoredMapBlocks: []uint64{}, }, { - name: "fulfillment no matching request no error", - requests: []Event{{Block: 150, ID: "1000"}}, - fulfillments: []Event{{Block: 199, ID: "10002"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{150}, + name: "fulfillment no matching request no error", + requests: []Event{{Block: 150, ID: "1000"}}, + fulfillments: []Event{{Block: 199, ID: "10002"}}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{150}, + expectedStoredMapBlocks: []uint64{150}, }, { - name: "multiple unfulfilled requests", - requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{150, 151}, + name: "multiple unfulfilled requests", + requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{150, 151}, + expectedStoredMapBlocks: []uint64{150, 151}, }, { - name: "multiple fulfilled requests", - requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}}, - fulfillments: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{}, + name: "multiple fulfilled requests", + requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}}, + fulfillments: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{}, + expectedStoredMapBlocks: []uint64{}, }, { - name: "recent unfulfilled request do not store", - requests: []Event{{Block: 185, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{}, + name: "recent unfulfilled request do not store", + requests: []Event{{Block: 185, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{}, + expectedStoredMapBlocks: []uint64{}, }, { - name: "old unfulfilled request do not store", - requests: []Event{{Block: 99, ID: "1000"}, {Block: 57, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{}, + name: "old unfulfilled request do not store", + requests: []Event{{Block: 99, ID: "1000"}, {Block: 57, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{}, + expectedStoredMapBlocks: []uint64{}, }, { name: "mixed", @@ -204,18 +218,20 @@ var ( // Block 154 {Block: 154, ID: "10007"}}, - wait: 25, - lookback: 100, - latest: 200, - expectedStored: []uint64{150, 153}, + wait: 25, + lookback: 100, + latest: 200, + expectedStored: []uint64{150, 153}, + expectedStoredMapBlocks: []uint64{150, 153}, }, { - name: "lookback before 0th block", - requests: []Event{{Block: 20, ID: "1000"}}, - wait: 25, - lookback: 100, - latest: 50, - expectedStored: []uint64{20}, + name: "lookback before 0th block", + requests: []Event{{Block: 20, ID: "1000"}}, + wait: 25, + lookback: 100, + latest: 50, + expectedStored: []uint64{20}, + expectedStoredMapBlocks: []uint64{20}, }, } ) @@ -250,6 +266,7 @@ func TestFeeder(t *testing.T) { } require.ElementsMatch(t, test.expectedStored, test.bhs.Stored) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) }) } } @@ -341,6 +358,7 @@ func TestFeederWithLogPollerVRFv1(t *testing.T) { require.EqualError(t, err, test.expectedErrMsg) } require.ElementsMatch(t, test.expectedStored, test.bhs.Stored) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) }) } } @@ -436,6 +454,7 @@ func TestFeederWithLogPollerVRFv2(t *testing.T) { require.EqualError(t, err, test.expectedErrMsg) } require.ElementsMatch(t, test.expectedStored, test.bhs.Stored) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) }) } } @@ -531,6 +550,7 @@ func TestFeederWithLogPollerVRFv2Plus(t *testing.T) { require.EqualError(t, err, test.expectedErrMsg) } require.ElementsMatch(t, test.expectedStored, test.bhs.Stored) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) }) } } From 2d574bec1c3d188aadd670516d6ae0554acbefd9 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Sat, 2 Sep 2023 02:12:57 -0400 Subject: [PATCH 05/88] Upgrade forge-std to 1.6.0 (#10459) --- contracts/foundry-lib/forge-std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/foundry-lib/forge-std b/contracts/foundry-lib/forge-std index f4264050aca..1d9650e9512 160000 --- a/contracts/foundry-lib/forge-std +++ b/contracts/foundry-lib/forge-std @@ -1 +1 @@ -Subproject commit f4264050aca5a2eedf243f9bd54b544c5a373bd2 +Subproject commit 1d9650e951204a0ddce9ff89c32f1997984cef4d From 5b78a81aba14db55aecd6bb41e936c8cf39b3f6d Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Sat, 2 Sep 2023 08:13:10 +0200 Subject: [PATCH 06/88] add foundry refresh make command (#10442) --- contracts/GNUmakefile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index ea70ae43f93..501ef968482 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -31,6 +31,15 @@ pnpmdep: ## Install solidity contract dependencies through pnpm abigen: ## Build & install abigen. ../tools/bin/build_abigen +.PHONY: mockery +mockery: $(mockery) ## Install mockery. + go install github.com/vektra/mockery/v2@v2.28.1 + +.PHONY: foundry-refresh +foundry-refresh: + foundryup + git submodule deinit -f . + git submodule update --init --recursive # To generate gethwrappers for a specific product, either set the `FOUNDRY_PROFILE` # env var or call the target with `FOUNDRY_PROFILE=product` @@ -43,7 +52,7 @@ abigen: ## Build & install abigen. # make call example # make FOUNDRY_PROFILE=llo-feeds wrappers .PHONY: wrappers -wrappers: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. +wrappers: pnpmdep mockery abigen ## Recompiles solidity contracts and their go wrappers. ./scripts/native_solc_compile_all_$(FOUNDRY_PROFILE) go generate ../core/gethwrappers/$(FOUNDRY_PROFILE) @@ -51,7 +60,7 @@ wrappers: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. # assumption that native_solc_compile_all contains sub-calls to each product, and # go_generate does the same. .PHONY: wrappers-all -wrappers-all: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. +wrappers-all: pnpmdep mockery abigen ## Recompiles solidity contracts and their go wrappers. # go_generate contains a call to compile all contracts before generating wrappers go generate ../core/gethwrappers/go_generate.go From 6954c90b8df07fc115563a319bf9d794f3ab8057 Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:57:20 +0100 Subject: [PATCH 07/88] Add debug logs when updating lastPoll / lastRepoll block (#10461) * Add debug logs when updating lastPoll / lastRepoll block * update to use uf1 --- .../ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go | 1 + .../ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go | 1 + 2 files changed, 2 insertions(+) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go index 84d373f03b6..acb3e2eaff1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go @@ -318,6 +318,7 @@ func (p *logEventProvider) updateFiltersLastPoll(entries []upkeepFilter) { p.filterStore.UpdateFilters(func(orig, f upkeepFilter) upkeepFilter { if f.lastPollBlock > orig.lastPollBlock { orig.lastPollBlock = f.lastPollBlock + p.lggr.Debugw("Updated lastPollBlock", "lastPollBlock", f.lastPollBlock, "upkeepID", f.upkeepID) } return orig }, entries...) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go index 7ac981e9952..5acfa1ee0c8 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -355,6 +355,7 @@ func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startB } r.filterStore.UpdateFilters(func(uf1, uf2 upkeepFilter) upkeepFilter { uf1.lastRePollBlock = end + r.lggr.Debugw("Updated lastRePollBlock", "lastRePollBlock", end, "upkeepID", uf1.upkeepID) return uf1 }, f) From 2837bafb411e26192a309b62c29e2775a71c0a8f Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Sun, 3 Sep 2023 11:11:38 -0500 Subject: [PATCH 08/88] bump pyroscope; use new import paths (#10463) --- core/logger/pyroscope.go | 2 +- core/scripts/go.mod | 4 ++-- core/scripts/go.sum | 8 ++++---- core/services/chainlink/application.go | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- integration-tests/go.mod | 3 ++- integration-tests/go.sum | 5 ++++- 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/core/logger/pyroscope.go b/core/logger/pyroscope.go index 3303fe51dee..226c241d36d 100644 --- a/core/logger/pyroscope.go +++ b/core/logger/pyroscope.go @@ -3,7 +3,7 @@ package logger import ( "runtime" - "github.com/pyroscope-io/client/pyroscope" + "github.com/grafana/pyroscope-go" "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/static" diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 2a81e2bb05b..8966ac2d2f4 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -147,6 +147,8 @@ require ( github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/sessions v1.2.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/grafana/pyroscope-go v1.0.2 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.3 // indirect github.com/graph-gophers/dataloader v5.0.0+incompatible // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect @@ -283,8 +285,6 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.0 // indirect github.com/prometheus/prometheus v0.46.0 // indirect - github.com/pyroscope-io/client v0.7.1 // indirect - github.com/pyroscope-io/godeltaprof v0.1.2 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rjeczalik/notify v0.9.3 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 708688e5e1f..1a4bba2fccc 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -570,6 +570,10 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/pyroscope-go v1.0.2 h1:dEFgO9VbhYTwuwpCC5coTpuW0JjISEWDZtvRAW9v5Tw= +github.com/grafana/pyroscope-go v1.0.2/go.mod h1:bShDKsVZdzxq+Ol6no0JKigU9y5FTWUcFditMXaH09o= +github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk= +github.com/grafana/pyroscope-go/godeltaprof v0.1.3/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko= 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= @@ -1308,10 +1312,6 @@ github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPH github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73vCMk/Kw= github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4= 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/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= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index d56f4d3f257..b2e8719e607 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -11,8 +11,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/google/uuid" + "github.com/grafana/pyroscope-go" "github.com/pkg/errors" - "github.com/pyroscope-io/client/pyroscope" "go.uber.org/multierr" "go.uber.org/zap/zapcore" diff --git a/go.mod b/go.mod index 6cb4b175cb1..a2007f5bac3 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/gorilla/securecookie v1.1.1 github.com/gorilla/sessions v1.2.1 github.com/gorilla/websocket v1.5.0 + github.com/grafana/pyroscope-go v1.0.2 github.com/graph-gophers/dataloader v5.0.0+incompatible github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/go-plugin v1.4.10 @@ -58,7 +59,6 @@ require ( github.com/prometheus/client_model v0.4.0 github.com/prometheus/common v0.44.0 github.com/prometheus/prometheus v0.46.0 - github.com/pyroscope-io/client v0.7.1 github.com/robfig/cron/v3 v3.0.1 github.com/rogpeppe/go-internal v1.11.0 github.com/scylladb/go-reflectx v1.0.1 @@ -195,6 +195,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/gorilla/context v1.1.1 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect @@ -308,7 +309,6 @@ require ( 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/procfs v0.11.0 // indirect - github.com/pyroscope-io/godeltaprof v0.1.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 4c07fe3735b..4deab41bc40 100644 --- a/go.sum +++ b/go.sum @@ -565,6 +565,10 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/pyroscope-go v1.0.2 h1:dEFgO9VbhYTwuwpCC5coTpuW0JjISEWDZtvRAW9v5Tw= +github.com/grafana/pyroscope-go v1.0.2/go.mod h1:bShDKsVZdzxq+Ol6no0JKigU9y5FTWUcFditMXaH09o= +github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk= +github.com/grafana/pyroscope-go/godeltaprof v0.1.3/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko= 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= @@ -1310,10 +1314,6 @@ github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPH github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73vCMk/Kw= github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4= 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.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE= -github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= 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= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index bb9bf9cfff0..32e13bbd80e 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -202,6 +202,8 @@ require ( github.com/grafana/dskit v0.0.0-20230201083518-528d8a7d52f2 // indirect github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737 // indirect github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765 // indirect + github.com/grafana/pyroscope-go v1.0.2 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.3 // 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 @@ -366,7 +368,6 @@ require ( github.com/prometheus/procfs v0.11.0 // indirect github.com/prometheus/prometheus v0.46.0 // indirect github.com/pyroscope-io/client v0.7.1 // indirect - github.com/pyroscope-io/godeltaprof v0.1.2 // 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 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 87b904bceb4..b5948436181 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1289,6 +1289,10 @@ github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737 h1:o45+fZAYRtTjx+9f github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737/go.mod h1:kxNnWCr4EMobhndjy7a2Qpm7jkLPnJW2ariYvY77hLE= github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765 h1:VXitROTlmZtLzvokNe8ZbUKpmwldM4Hy1zdNRO32jKU= github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765/go.mod h1:DhJMrd2QInI/1CNtTN43BZuTmkccdizW1jZ+F6aHkhY= +github.com/grafana/pyroscope-go v1.0.2 h1:dEFgO9VbhYTwuwpCC5coTpuW0JjISEWDZtvRAW9v5Tw= +github.com/grafana/pyroscope-go v1.0.2/go.mod h1:bShDKsVZdzxq+Ol6no0JKigU9y5FTWUcFditMXaH09o= +github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk= +github.com/grafana/pyroscope-go/godeltaprof v0.1.3/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= @@ -2166,7 +2170,6 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T 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/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= From 528dfc608f9f84a4eeaab3efb2e559f41cb85f34 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier Date: Mon, 4 Sep 2023 10:53:15 +0530 Subject: [PATCH 09/88] [AUTO-4790] increase delta stage for integration-tests (#10398) * Update keeper_test.go * set deltaStage 30s * automation tests - set deltaStage 30s --- integration-tests/benchmark/keeper_test.go | 4 ++-- integration-tests/chaos/automation_chaos_test.go | 2 +- integration-tests/reorg/automation_reorg_test.go | 2 +- integration-tests/smoke/automation_test.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index 491d4fe1f3d..6ce0fb7138f 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -244,13 +244,13 @@ var networkConfig = map[string]NetworkConfig{ "SimulatedGeth": { upkeepSLA: int64(20), blockTime: time.Second, - deltaStage: time.Duration(0), + deltaStage: 30 * time.Second, funding: big.NewFloat(100_000), }, "geth": { upkeepSLA: int64(20), blockTime: time.Second, - deltaStage: time.Duration(0), + deltaStage: 30 * time.Second, funding: big.NewFloat(100_000), }, "GoerliTestnet": { diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index ee6562aa5b4..0da3271785e 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -240,7 +240,7 @@ func TestAutomationChaos(t *testing.T) { actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, eth_contracts.RegistryVersion_2_0) nodesWithoutBootstrap := chainlinkNodes[1:] - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second) 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/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index f1a1bfcc6ad..4a75d92d5d1 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -183,7 +183,7 @@ func TestAutomationReorg(t *testing.T) { actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, ethereum.RegistryVersion_2_0) nodesWithoutBootstrap := chainlinkNodes[1:] - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second) 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 5aa7668d151..57ca733b594 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -767,7 +767,7 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { highCheckGasLimit := automationDefaultRegistryConfig highCheckGasLimit.CheckGasLimit = uint32(5000000) highCheckGasLimit.RegistryVersion = registryVersion - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, highCheckGasLimit, registrar.Address(), 5*time.Second) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, highCheckGasLimit, registrar.Address(), 30*time.Second) require.NoError(t, err, "Error building OCR config") err = registry.SetConfig(highCheckGasLimit, ocrConfig) @@ -951,7 +951,7 @@ func setupAutomationTest( actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion) nodesWithoutBootstrap := chainlinkNodes[1:] - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, registryConfig, registrar.Address(), 5*time.Second) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, registryConfig, registrar.Address(), 30*time.Second) require.NoError(t, err, "Error building OCR config vars") err = registry.SetConfig(automationDefaultRegistryConfig, ocrConfig) require.NoError(t, err, "Registry config should be set successfully") From 39f7cde8e3a03697b427611fd820c295605fcf16 Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 4 Sep 2023 12:07:22 +0300 Subject: [PATCH 10/88] chore: skip ocr2vrf tests (#10448) due to flakiness --- .../plugins/ocr2vrf/internal/ocr2vrf_integration_test.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go index dbd8f830f79..c6a4552683a 100644 --- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go @@ -8,7 +8,6 @@ import ( "fmt" "math/big" "net" - "os" "testing" "time" @@ -323,16 +322,12 @@ func setupNodeOCR2( } func TestIntegration_OCR2VRF_ForwarderFlow(t *testing.T) { - if os.Getenv("CI") == "" && os.Getenv("VRF_LOCAL_TESTING") == "" { - t.Skip("Skipping test locally.") - } + t.Skip() runOCR2VRFTest(t, true) } func TestIntegration_OCR2VRF(t *testing.T) { - if os.Getenv("CI") == "" && os.Getenv("VRF_LOCAL_TESTING") == "" { - t.Skip("Skipping test locally.") - } + t.Skip() runOCR2VRFTest(t, false) } From fe6fd64a912dfcd75e203550fefac6514faf95a6 Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Mon, 4 Sep 2023 11:37:00 +0100 Subject: [PATCH 11/88] Fix bug in updating last poll block for filter (#10462) --- .../plugins/ocr2keeper/evm21/logprovider/provider.go | 6 ++++-- .../ocr2keeper/evm21/logprovider/provider_test.go | 12 +++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go index acb3e2eaff1..8fbbb1e0a9d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go @@ -363,7 +363,7 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [ // maxBurst will be used to increase the burst limit to allow a long range scan maxBurst := int(lookbackBlocks + 1) - for _, filter := range filters { + for i, filter := range filters { if len(filter.addr) == 0 { continue } @@ -408,7 +408,9 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [ p.buffer.enqueue(filter.upkeepID, filteredLogs...) - filter.lastPollBlock = latest + // Update the lastPollBlock for filter in slice this is then + // updated into filter store in updateFiltersLastPoll + filters[i].lastPollBlock = latest } return merr diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go index 9e3eb8565c3..159e229a2ff 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go @@ -255,7 +255,8 @@ func TestLogEventProvider_ReadLogs(t *testing.T) { }, }, nil) - p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200)) + filterStore := NewUpkeepFilterStore() + p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, filterStore, NewOptions(200)) var ids []*big.Int for i := 0; i < 10; i++ { @@ -277,6 +278,15 @@ func TestLogEventProvider_ReadLogs(t *testing.T) { require.NoError(t, p.ReadLogs(ctx, ids[:2]...)) logs := p.buffer.peek(10) require.Len(t, logs, 2) + + var updatedFilters []upkeepFilter + filterStore.RangeFiltersByIDs(func(i int, f upkeepFilter) { + updatedFilters = append(updatedFilters, f.Clone()) + }, ids[:2]...) + for _, f := range updatedFilters { + // Last poll block should be updated + require.Equal(t, int64(1), f.lastPollBlock) + } }) // TODO: test rate limiting From f07c491fd7ae3bb0b966ff6d12c4a4f83a4934ef Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 4 Sep 2023 19:59:40 +0400 Subject: [PATCH 12/88] chore: fix shared snapshot (#10471) * chore: fix shared snapshot * empty commit to trigger CI again * another empty to trigger ci * fix: add snapshots to filters * chore: update all snapshots * chore: add .gitmodules and foundry-lib to filters --- .github/workflows/solidity-foundry.yml | 3 + .../gas-snapshots/automation-dev.gas-snapshot | 4 +- .../gas-snapshots/automation.gas-snapshot | 8 +- .../gas-snapshots/functions.gas-snapshot | 16 +- .../gas-snapshots/llo-feeds.gas-snapshot | 432 +++++++++--------- contracts/gas-snapshots/shared.gas-snapshot | 38 +- contracts/gas-snapshots/vrf.gas-snapshot | 28 +- 7 files changed, 266 insertions(+), 263 deletions(-) diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 45f1d8e9d79..abdb64d1763 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -23,6 +23,9 @@ jobs: - 'contracts/src/v0.8/**/*' - '.github/workflows/solidity-foundry.yml' - 'contracts/foundry.toml' + - 'contracts/gas-snapshots/*.gas-snapshot' + - '.gitmodules' + - 'contracts/foundry-lib' tests: strategy: diff --git a/contracts/gas-snapshots/automation-dev.gas-snapshot b/contracts/gas-snapshots/automation-dev.gas-snapshot index 1a939d69e19..badbfba604c 100644 --- a/contracts/gas-snapshots/automation-dev.gas-snapshot +++ b/contracts/gas-snapshots/automation-dev.gas-snapshot @@ -1,5 +1,5 @@ AutomationForwarder_forward:testBasicSuccess() (gas: 87630) -AutomationForwarder_forward:testNotAuthorizedReverts() (gas: 21681) +AutomationForwarder_forward:testNotAuthorizedReverts() (gas: 25427) AutomationForwarder_forward:testWrongFunctionSelectorSuccess() (gas: 17958) AutomationForwarder_updateRegistry:testBasicSuccess() (gas: 14577) -AutomationForwarder_updateRegistry:testNotFromRegistryNotAuthorizedReverts() (gas: 13893) \ No newline at end of file +AutomationForwarder_updateRegistry:testNotFromRegistryNotAuthorizedReverts() (gas: 17665) \ No newline at end of file diff --git a/contracts/gas-snapshots/automation.gas-snapshot b/contracts/gas-snapshots/automation.gas-snapshot index 934aebf982d..a90453b1029 100644 --- a/contracts/gas-snapshots/automation.gas-snapshot +++ b/contracts/gas-snapshots/automation.gas-snapshot @@ -1,8 +1,8 @@ HeartbeatRequester_getAggregatorRequestHeartbeat:testBasicSuccess() (gas: 75412) HeartbeatRequester_getAggregatorRequestHeartbeat:testHeartbeatNotPermittedReverts() (gas: 21730) -HeartbeatRequester_permitHeartbeat:testBasicDeployerSuccess() (gas: 48280) -HeartbeatRequester_permitHeartbeat:testBasicSuccess() (gas: 45856) -HeartbeatRequester_permitHeartbeat:testOnlyCallableByOwnerReverts() (gas: 13796) +HeartbeatRequester_permitHeartbeat:testBasicDeployerSuccess() (gas: 48229) +HeartbeatRequester_permitHeartbeat:testBasicSuccess() (gas: 45844) +HeartbeatRequester_permitHeartbeat:testOnlyCallableByOwnerReverts() (gas: 17584) HeartbeatRequester_removeHeartbeat:testBasicSuccess() (gas: 30192) -HeartbeatRequester_removeHeartbeat:testOnlyCallableByOwnerReverts() (gas: 11629) +HeartbeatRequester_removeHeartbeat:testOnlyCallableByOwnerReverts() (gas: 15417) HeartbeatRequester_removeHeartbeat:testRemoveNoPermitsSuccess() (gas: 15660) \ No newline at end of file diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index fa2c9dba497..7ee4f779d6a 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,17 +1,17 @@ -FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13430) +FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13452) FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974) FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255) FunctionsOracle_setDONPublicKey:testSetDONPublicKeySuccess() (gas: 126453) -FunctionsOracle_setDONPublicKey:testSetDONPublicKey_gas() (gas: 97558) +FunctionsOracle_setDONPublicKey:testSetDONPublicKey_gas() (gas: 97580) FunctionsOracle_setRegistry:testEmptyPublicKeyReverts() (gas: 10635) FunctionsOracle_setRegistry:testOnlyOwnerReverts() (gas: 10927) FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35791) FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987) FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905) -FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13293) -FunctionsRouter_Pause:test_Pause_Success() (gas: 20205) -FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13338) -FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77279) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26347) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15699) +FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13315) +FunctionsRouter_Pause:test_Pause_Success() (gas: 20254) +FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13294) +FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77334) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26368) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15714) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152436) \ No newline at end of file diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 482b3edc12b..18499e0f6c2 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -1,255 +1,255 @@ -FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 47621) -FeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 21051) -FeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 52298) -FeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 112748) -FeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 23646) -FeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 69576) -FeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 63969) -FeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 48730) -FeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 20326) +FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52609) +FeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 25927) +FeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 57240) +FeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 120182) +FeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 28588) +FeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 74518) +FeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 71365) +FeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56167) +FeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 25300) FeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 14621) FeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 17579) -FeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 83432) -FeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 51511) -FeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 47789) -FeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 44614) -FeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 71358) -FeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 40470) -FeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 12600) -FeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 49535) -FeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12339) -FeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 36370) -FeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 251051) -FeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 61024) -FeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 43696) -FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 60080) -FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 56719) -FeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 47021) +FeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 90869) +FeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56477) +FeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52755) +FeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49580) +FeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78792) +FeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 46384) +FeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17568) +FeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54523) +FeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12361) +FeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41347) +FeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 260960) +FeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 68464) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49645) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67562) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 64156) +FeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 51987) FeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 14641) -FeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 44805) -FeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 50542) -FeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 75290) -FeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 44657) -FeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 44615) +FeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49771) +FeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55510) +FeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82724) +FeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49623) +FeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49581) FeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 17579) -FeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 45838) -FeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 47404) -FeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 25823) -FeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 45814) -FeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 12211) -FeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 36393) -FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 46866) -FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 70581) -FeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 19160) -FeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 14846) -FeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 187316) -FeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 12367) -FeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 206512) -FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 189668) -FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 113142) -FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 21857) -FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 153995) -FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 22485) -FeeManagerProcessFeeTest:test_processFeeNative() (gas: 166691) -FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 114102) -FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 24176) -FeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 25660) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 176693) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 128211) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 152075) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 87203) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 183653) -FeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 23529) -FeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 23997) -FeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 24986) -FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 30202) -FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 146602) -FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 50621) -FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 113108) -FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 32904) -FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeUnwrappedReports() (gas: 286610) -FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeWrappedReports() (gas: 267369) -FeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 229026) -FeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 262798) -FeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 66250) -FeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 243449) -FeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 271565) -FeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 290783) +FeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50760) +FeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 52375) +FeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30789) +FeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50802) +FeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17188) +FeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41370) +FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51832) +FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78015) +FeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 24103) +FeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19814) +FeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 197190) +FeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17338) +FeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 218523) +FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 201471) +FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 120576) +FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 26799) +FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 163879) +FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 27360) +FeeManagerProcessFeeTest:test_processFeeNative() (gas: 176574) +FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 121514) +FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 29118) +FeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30602) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 184105) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 135624) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 159487) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 94615) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 191065) +FeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 28471) +FeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 28939) +FeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 29928) +FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 35144) +FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 156485) +FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 55585) +FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 120542) +FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 37846) +FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeUnwrappedReports() (gas: 296517) +FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeWrappedReports() (gas: 279759) +FeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 236449) +FeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 270220) +FeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 71195) +FeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 253350) +FeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 283979) +FeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 300708) FeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 11011) -FeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 14580) -FeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 41313) -FeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 46123) -FeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 46091) -FeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 71754) -FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 41011) -FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 44871) -FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 70774) +FeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19570) +FeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46281) +FeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 51089) +FeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 51057) +FeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79188) +FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 46960) +FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49837) +FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78208) FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 15198) -RewardManagerClaimTest:test_claimAllRecipients() (gas: 263344) -RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 145864) -RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 315564) -RewardManagerClaimTest:test_claimSingleRecipient() (gas: 83367) -RewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 300721) -RewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 29488) -RewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 35524) -RewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 81096) -RewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 19727) -RewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 360373) -RewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 128499) -RewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 464475) +RewardManagerClaimTest:test_claimAllRecipients() (gas: 275763) +RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 153306) +RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330467) +RewardManagerClaimTest:test_claimSingleRecipient() (gas: 88340) +RewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 315671) +RewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 34461) +RewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 40491) +RewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86069) +RewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 24700) +RewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 385336) +RewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 138411) +RewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 489469) RewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 13550) -RewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 51601) -RewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 244544) -RewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 15559) -RewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 244790) -RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 255968) -RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 259108) -RewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 23623) -RewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 20065) -RewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 26139) -RewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 79428) -RewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 192529) -RewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 267295) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 487453) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 269391) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 276703) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 249180) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 145948) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 124471) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 97872) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 551064) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 56091) +RewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 55574) +RewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 249515) +RewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20518) +RewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 249761) +RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 260965) +RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 264101) +RewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28592) +RewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 25013) +RewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31098) +RewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84397) +RewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 197492) +RewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 279714) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 509889) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 281833) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 291618) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 261589) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 153390) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 131911) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 105334) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 578510) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 63533) RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 28864) -RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 139395) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 146842) RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 18363) RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 24381) -RewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 364823) -RewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 128515) -RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 190638) -RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 210530) -RewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 186872) -RewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 121134) -RewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 186535) -RewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 16504) -RewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 185999) -RewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 175763) -RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 85276) -RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 178782) -RewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 180711) -RewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 82166) -RewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 105471) -RewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 16367) -RewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 255602) +RewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 389786) +RewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 138427) +RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 200572) +RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 220442) +RewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 191821) +RewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 126091) +RewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 193950) +RewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 21452) +RewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 193416) +RewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 180711) +RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 90224) +RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 183724) +RewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 185681) +RewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 87113) +RewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 110394) +RewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 21366) +RewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259335) RewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59390) -RewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 12039) -RewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 356489) -RewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 274297) -RewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 14757) -RewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 206711) -RewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 268121) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 240361) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 254433) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 144023) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 254507) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 351970) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 253649) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 283778) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 256457) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 254436) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 255845) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 254576) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 246971) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 245257) +RewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17016) +RewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 373819) +RewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 279281) +RewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19727) +RewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 219095) +RewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 273103) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 245309) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259381) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 148982) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259455) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 369300) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 258597) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288735) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 261406) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 259384) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 260794) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 259524) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 251916) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 250201) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesAMiddleDigest() (gas: 24155) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesTheFirstDigest() (gas: 24122) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyUnsetsDigestsInSequence() (gas: 44043) -VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfCalledByNonOwner() (gas: 11278) +VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfCalledByNonOwner() (gas: 15016) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnEmptyDigest() (gas: 10907) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnNonExistentDigest() (gas: 13381) -VerifierActivateConfigTest:test_revertsIfDigestIsEmpty() (gas: 10962) +VerifierActivateConfigTest:test_revertsIfDigestIsEmpty() (gas: 10984) VerifierActivateConfigTest:test_revertsIfDigestNotSet() (gas: 13394) -VerifierActivateConfigTest:test_revertsIfNotOwner() (gas: 13433) -VerifierActivateConfigWithDeactivatedConfigTest:test_allowsVerification() (gas: 93473) +VerifierActivateConfigTest:test_revertsIfNotOwner() (gas: 17171) +VerifierActivateConfigWithDeactivatedConfigTest:test_allowsVerification() (gas: 97164) VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13157) -VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 13360) -VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 13415) -VerifierBulkVerifyBillingReport:test_verifyBulkReportWithUnwrappedAndWrappedNativeDefaultsToUnwrapped() (gas: 386271) -VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndUnwrappedNative() (gas: 694977) -VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndWrappedNative() (gas: 677095) -VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 560297) -VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 773047) -VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 572112) -VerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 573880) -VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 583847) -VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 590874) +VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 17098) +VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 17153) +VerifierBulkVerifyBillingReport:test_verifyBulkReportWithUnwrappedAndWrappedNativeDefaultsToUnwrapped() (gas: 391227) +VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndUnwrappedNative() (gas: 702466) +VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndWrappedNative() (gas: 687045) +VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 570309) +VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 783120) +VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 579516) +VerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 581327) +VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 588801) +VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 595828) VerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 59939) VerifierConstructorTest:test_setsTheCorrectProperties() (gas: 1788491) -VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas: 188300) -VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 109631) -VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 95877) -VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 66189) -VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 201062) -VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 105778) -VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1357277) +VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas: 192062) +VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 113377) +VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 99613) +VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 69932) +VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 204824) +VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 109546) +VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1357299) VerifierProxyConstructorTest:test_correctlySetsTheOwner() (gas: 1337313) -VerifierProxyConstructorTest:test_correctlySetsVersion() (gas: 6939) -VerifierProxyInitializeVerifierTest:test_revertsIfDigestAlreadySet() (gas: 50333) +VerifierProxyConstructorTest:test_correctlySetsVersion() (gas: 6873) +VerifierProxyInitializeVerifierTest:test_revertsIfDigestAlreadySet() (gas: 54085) VerifierProxyInitializeVerifierTest:test_revertsIfNotCorrectVerifier() (gas: 13572) -VerifierProxyInitializeVerifierTest:test_revertsIfNotOwner() (gas: 13441) -VerifierProxyInitializeVerifierTest:test_revertsIfVerifierAlreadyInitialized() (gas: 42047) +VerifierProxyInitializeVerifierTest:test_revertsIfNotOwner() (gas: 17179) +VerifierProxyInitializeVerifierTest:test_revertsIfVerifierAlreadyInitialized() (gas: 42069) VerifierProxyInitializeVerifierTest:test_revertsIfZeroAddress() (gas: 10970) -VerifierProxyInitializeVerifierTest:test_setFeeManagerZeroAddress() (gas: 10913) -VerifierProxyInitializeVerifierTest:test_updatesVerifierIfVerifier() (gas: 49583) +VerifierProxyInitializeVerifierTest:test_setFeeManagerZeroAddress() (gas: 10935) +VerifierProxyInitializeVerifierTest:test_updatesVerifierIfVerifier() (gas: 53315) VerifierProxySetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35384) -VerifierProxySetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 11367) +VerifierProxySetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 15105) VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 32120) VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 12219) VerifierProxyUnsetVerifierTest:test_revertsIfDigestDoesNotExist() (gas: 13141) -VerifierProxyUnsetVerifierTest:test_revertsIfNotAdmin() (gas: 11227) +VerifierProxyUnsetVerifierTest:test_revertsIfNotAdmin() (gas: 14965) VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVerifier() (gas: 12697) -VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17943) +VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17965) VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 198408) -VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 116352) -VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538560) -VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 964093) -VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 520118) -VerifierSetConfigFromSourceTest:test_revertsIfCalledByNonOwner() (gas: 179353) +VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 116307) +VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538582) +VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 964048) +VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 520140) +VerifierSetConfigFromSourceTest:test_revertsIfCalledByNonOwner() (gas: 183115) VerifierSetConfigTest:test_correctlyUpdatesTheConfig() (gas: 1057669) -VerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 179222) -VerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 251572) +VerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 182962) +VerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 251529) VerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 176521) VerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 15813) -VerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 22169) +VerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 22191) VerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 228002) -VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538347) -VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 963662) -VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 519899) +VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538369) +VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 963617) +VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 519921) VerifierSupportsInterfaceTest:test_falseIfIsNotCorrectInterface() (gas: 5590) -VerifierSupportsInterfaceTest:test_trueIfIsCorrectInterface() (gas: 5611) -VerifierTestBillingReport:test_verifyWithLink() (gas: 273128) -VerifierTestBillingReport:test_verifyWithNative() (gas: 313819) -VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 318543) -VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 325609) -VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 127491) -VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 183370) -VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 84461) -VerifierVerifyMultipleConfigDigestTest:test_revertsIfVerifyingWithAnUnsetDigest() (gas: 124325) -VerifierVerifySingleConfigDigestTest:test_emitsAnEventIfReportVerified() (gas: 183205) -VerifierVerifySingleConfigDigestTest:test_returnsThePriceAndBlockNumIfReportVerified() (gas: 183374) -VerifierVerifySingleConfigDigestTest:test_revertsIfConfigDigestNotSet() (gas: 112427) -VerifierVerifySingleConfigDigestTest:test_revertsIfDuplicateSignersHaveSigned() (gas: 178569) -VerifierVerifySingleConfigDigestTest:test_revertsIfMismatchedSignatureLength() (gas: 49272) -VerifierVerifySingleConfigDigestTest:test_revertsIfReportHasUnconfiguredFeedID() (gas: 100230) +VerifierSupportsInterfaceTest:test_trueIfIsCorrectInterface() (gas: 5633) +VerifierTestBillingReport:test_verifyWithLink() (gas: 280557) +VerifierTestBillingReport:test_verifyWithNative() (gas: 321248) +VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 323491) +VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 330557) +VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 131228) +VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 187132) +VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 88205) +VerifierVerifyMultipleConfigDigestTest:test_revertsIfVerifyingWithAnUnsetDigest() (gas: 128062) +VerifierVerifySingleConfigDigestTest:test_emitsAnEventIfReportVerified() (gas: 186945) +VerifierVerifySingleConfigDigestTest:test_returnsThePriceAndBlockNumIfReportVerified() (gas: 187114) +VerifierVerifySingleConfigDigestTest:test_revertsIfConfigDigestNotSet() (gas: 116130) +VerifierVerifySingleConfigDigestTest:test_revertsIfDuplicateSignersHaveSigned() (gas: 182315) +VerifierVerifySingleConfigDigestTest:test_revertsIfMismatchedSignatureLength() (gas: 53037) +VerifierVerifySingleConfigDigestTest:test_revertsIfReportHasUnconfiguredFeedID() (gas: 103976) VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 100992) -VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 180320) -VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 106285) -VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 190530) -Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 205085) +VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 184066) +VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 110031) +VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 194270) +Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 208841) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 542038) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 565410) -Verifier_setConfig:testSetConfigSuccess_gas() (gas: 922406) +Verifier_setConfig:testSetConfigSuccess_gas() (gas: 922428) Verifier_verify:testVerifyProxySuccess_gas() (gas: 195530) -Verifier_verify:testVerifySuccess_gas() (gas: 182991) -Verifier_verifyWithFee:testVerifyProxyWithLinkFeeSuccess_gas() (gas: 244551) -Verifier_verifyWithFee:testVerifyProxyWithNativeFeeSuccess_gas() (gas: 262962) \ No newline at end of file +Verifier_verify:testVerifySuccess_gas() (gas: 186725) +Verifier_verifyWithFee:testVerifyProxyWithLinkFeeSuccess_gas() (gas: 244506) +Verifier_verifyWithFee:testVerifyProxyWithNativeFeeSuccess_gas() (gas: 262984) \ No newline at end of file diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index cb2e8defe4a..cf003c5a26d 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -1,32 +1,32 @@ -BurnMintERC677_approve:testApproveSuccess() (gas: 52254) -BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10641) -BurnMintERC677_burn:testBasicBurnSuccess() (gas: 164344) -BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 43462) -BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 18035) +BurnMintERC677_approve:testApproveSuccess() (gas: 55248) +BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10663) +BurnMintERC677_burn:testBasicBurnSuccess() (gas: 164342) +BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 47201) +BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 21841) BurnMintERC677_burn:testSenderNotBurnerReverts() (gas: 13359) -BurnMintERC677_burnFrom:testBurnFromSuccess() (gas: 54662) -BurnMintERC677_burnFrom:testExceedsBalanceReverts() (gas: 32873) -BurnMintERC677_burnFrom:testInsufficientAllowanceReverts() (gas: 18107) +BurnMintERC677_burnFrom:testBurnFromSuccess() (gas: 57658) +BurnMintERC677_burnFrom:testExceedsBalanceReverts() (gas: 35864) +BurnMintERC677_burnFrom:testInsufficientAllowanceReverts() (gas: 21849) BurnMintERC677_burnFrom:testSenderNotBurnerReverts() (gas: 13359) -BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 54688) -BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 32889) -BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 18127) +BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 57684) +BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 35880) +BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 21869) BurnMintERC677_burnFromAlias:testSenderNotBurnerReverts() (gas: 13379) BurnMintERC677_constructor:testConstructorSuccess() (gas: 1669109) -BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 28520) -BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 120049) -BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 52707) +BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 28537) +BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 120071) +BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 52724) BurnMintERC677_grantRole:testGrantManySuccess() (gas: 935521) -BurnMintERC677_grantRole:testGrantMintAccessSuccess() (gas: 93588) +BurnMintERC677_grantRole:testGrantMintAccessSuccess() (gas: 93605) BurnMintERC677_increaseApproval:testIncreaseApprovalSuccess() (gas: 40911) BurnMintERC677_mint:testBasicMintSuccess() (gas: 149365) -BurnMintERC677_mint:testMaxSupplyExceededReverts() (gas: 46627) +BurnMintERC677_mint:testMaxSupplyExceededReverts() (gas: 50385) BurnMintERC677_mint:testSenderNotMinterReverts() (gas: 11195) BurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 8685) -BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10617) +BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10639) BurnMintERC677_transfer:testTransferSuccess() (gas: 39462) OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1739317) -OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 259440) -OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137935) +OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 263373) +OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957) OpStackBurnMintERC677_interfaceCompatibility:testStaticFunctionsCompatibility() (gas: 10622) OpStackBurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 8961) \ No newline at end of file diff --git a/contracts/gas-snapshots/vrf.gas-snapshot b/contracts/gas-snapshots/vrf.gas-snapshot index 29053204765..44145caadaa 100644 --- a/contracts/gas-snapshots/vrf.gas-snapshot +++ b/contracts/gas-snapshots/vrf.gas-snapshot @@ -1,18 +1,18 @@ TrustedBlockhashStoreTest:testGenericBHSFunctions() (gas: 53507) -TrustedBlockhashStoreTest:testTrustedBHSFunctions() (gas: 49536) +TrustedBlockhashStoreTest:testTrustedBHSFunctions() (gas: 54617) VRFCoordinatorV2Plus_Migration:testDeregister() (gas: 101083) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCaller() (gas: 29421) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCoordinator() (gas: 19855) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenPendingFulfillment() (gas: 237702) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenReentrant() (gas: 354749) -VRFCoordinatorV2Plus_Migration:testMigration() (gas: 471631) -VRFCoordinatorV2Plus_Migration:testMigrationNoLink() (gas: 431052) -VRFV2Plus:testCancelSubWithNoLink() (gas: 160261) +VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCaller() (gas: 33190) +VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCoordinator() (gas: 19877) +VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenPendingFulfillment() (gas: 237679) +VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenReentrant() (gas: 357765) +VRFCoordinatorV2Plus_Migration:testMigration() (gas: 471605) +VRFCoordinatorV2Plus_Migration:testMigrationNoLink() (gas: 431075) +VRFV2Plus:testCancelSubWithNoLink() (gas: 160279) VRFV2Plus:testCreateSubscription() (gas: 181127) -VRFV2Plus:testGetActiveSubscriptionIds() (gas: 3453659) -VRFV2Plus:testRegisterProvingKey() (gas: 101025) -VRFV2Plus:testRequestAndFulfillRandomWordsLINK() (gas: 755178) -VRFV2Plus:testRequestAndFulfillRandomWordsNative() (gas: 705581) +VRFV2Plus:testGetActiveSubscriptionIds() (gas: 3453681) +VRFV2Plus:testRegisterProvingKey() (gas: 101085) +VRFV2Plus:testRequestAndFulfillRandomWordsLINK() (gas: 755144) +VRFV2Plus:testRequestAndFulfillRandomWordsNative() (gas: 705591) VRFV2Plus:testSetConfig() (gas: 73032) -VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsLINKWrapper() (gas: 390063) -VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsNativeWrapper() (gas: 290612) \ No newline at end of file +VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsLINKWrapper() (gas: 393885) +VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsNativeWrapper() (gas: 294434) \ No newline at end of file From 200970a568d644defac958de3212d38fd384da24 Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Mon, 4 Sep 2023 19:21:35 +0300 Subject: [PATCH 13/88] Show job runs for disabled chains (#10401) * Show job runs for disabled chains * Add changelog --- core/services/job/job_orm_test.go | 23 +++++++++++++++++++++++ core/services/job/orm.go | 4 +++- docs/CHANGELOG.md | 4 +++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index 0f70e74b247..de2ee44c2ce 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -1248,6 +1248,7 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) { jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) require.NoError(t, err) + jb.DirectRequestSpec.EVMChainID = utils.NewBigI(0) err = orm.CreateJob(&jb) require.NoError(t, err) @@ -1270,6 +1271,28 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) { require.NoError(t, err) assert.Len(t, jbs, 0) }) + + t.Run("with chainID disabled", func(t *testing.T) { + newCfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.EVM[0] = &evmcfg.EVMConfig{ + ChainID: utils.NewBigI(0), + Enabled: ptr(false), + } + c.EVM = append(c.EVM, &evmcfg.EVMConfig{ + ChainID: utils.NewBigI(123123123), + Enabled: ptr(true), + }) + }) + relayExtenders2 := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: newCfg, KeyStore: keyStore.Eth()}) + legacyChains2, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders2) + + require.NoError(t, err) + orm2 := NewTestORM(t, db, legacyChains2, pipelineORM, bridgesORM, keyStore, config.Database()) + + jbs, err := orm2.FindJobsByPipelineSpecIDs([]int32{jb.PipelineSpecID}) + require.NoError(t, err) + assert.Len(t, jbs, 1) + }) } func Test_FindPipelineRuns(t *testing.T) { diff --git a/core/services/job/orm.go b/core/services/job/orm.go index d7cfbd0fc4a..277b03b24dd 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" "github.com/smartcontractkit/chainlink/v2/core/config" @@ -1185,7 +1186,8 @@ func (o *orm) FindJobsByPipelineSpecIDs(ids []int32) ([]Job, error) { } for i := range jbs { err = o.LoadEnvConfigVars(&jbs[i]) - if err != nil { + //We must return the jobs even if the chainID is disabled + if err != nil && !errors.Is(err, chains.ErrNoSuchChainID) { return err } } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 90d619cd19e..93ae8b611f5 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [dev] -... +### Fixed + - Fixed a bug that was preventing job runs to be displayed when the job `chainID` was disabled. + ## 2.5.0 - UNRELEASED From 2afd9c259658f2a4d857493a92059bfd16608603 Mon Sep 17 00:00:00 2001 From: ferglor <19188060+ferglor@users.noreply.github.com> Date: Mon, 4 Sep 2023 19:16:03 +0100 Subject: [PATCH 14/88] Return all logs even if seen before (#10473) --- .../evm21/transmit/event_provider.go | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go index eccc9304d99..a21cdd25eb0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go @@ -170,52 +170,54 @@ func (c *TransmitEventProvider) processLogs(latestBlock int64, logs ...logpoller // ensure we don't have duplicates continue } - if _, ok := c.cache.get(ocr2keepers.BlockNumber(log.BlockNumber), k); ok { - // ensure we return only unseen logs - continue - } - l, err := c.parseLog(c.registry, log) - if err != nil { - c.logger.Debugw("failed to parse log", "err", err) - continue - } - id := l.Id() - upkeepId := &ocr2keepers.UpkeepIdentifier{} - ok := upkeepId.FromBigInt(id) + + transmitEvent, ok := c.cache.get(ocr2keepers.BlockNumber(log.BlockNumber), k) if !ok { - return nil, core.ErrInvalidUpkeepID + l, err := c.parseLog(c.registry, log) + if err != nil { + c.logger.Debugw("failed to parse log", "err", err) + continue + } + id := l.Id() + upkeepId := &ocr2keepers.UpkeepIdentifier{} + ok := upkeepId.FromBigInt(id) + if !ok { + return nil, core.ErrInvalidUpkeepID + } + triggerW, err := core.UnpackTrigger(id, l.Trigger()) + if err != nil { + return nil, fmt.Errorf("%w: failed to unpack trigger", err) + } + trigger := ocr2keepers.NewTrigger( + ocr2keepers.BlockNumber(triggerW.BlockNum), + triggerW.BlockHash, + ) + switch core.GetUpkeepType(*upkeepId) { + case ocr2keepers.LogTrigger: + trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{} + trigger.LogTriggerExtension.TxHash = triggerW.TxHash + trigger.LogTriggerExtension.Index = triggerW.LogIndex + default: + } + workID := core.UpkeepWorkID(*upkeepId, trigger) + transmitEvent = ocr2keepers.TransmitEvent{ + Type: l.TransmitEventType(), + TransmitBlock: ocr2keepers.BlockNumber(l.BlockNumber), + TransactionHash: l.TxHash, + WorkID: workID, + UpkeepID: *upkeepId, + CheckBlock: trigger.BlockNumber, + } } - triggerW, err := core.UnpackTrigger(id, l.Trigger()) - if err != nil { - return nil, fmt.Errorf("%w: failed to unpack trigger", err) - } - trigger := ocr2keepers.NewTrigger( - ocr2keepers.BlockNumber(triggerW.BlockNum), - triggerW.BlockHash, - ) - switch core.GetUpkeepType(*upkeepId) { - case ocr2keepers.LogTrigger: - trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{} - trigger.LogTriggerExtension.TxHash = triggerW.TxHash - trigger.LogTriggerExtension.Index = triggerW.LogIndex - default: - } - workID := core.UpkeepWorkID(*upkeepId, trigger) - e := ocr2keepers.TransmitEvent{ - Type: l.TransmitEventType(), - TransmitBlock: ocr2keepers.BlockNumber(l.BlockNumber), - Confirmations: latestBlock - l.BlockNumber, - TransactionHash: l.TxHash, - WorkID: workID, - UpkeepID: *upkeepId, - CheckBlock: trigger.BlockNumber, - } - vals = append(vals, e) - visited[k] = e + + transmitEvent.Confirmations = latestBlock - int64(transmitEvent.TransmitBlock) + + vals = append(vals, transmitEvent) + visited[k] = transmitEvent } // adding to the cache only after we've processed all the logs - // the next time we call processLogs we don't want to return these logs + // the next time we call processLogs we don't want to process these logs for k, e := range visited { c.cache.add(k, e) } From c38b8621d3f923082673686bb1ac56940e71702a Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Tue, 5 Sep 2023 00:58:40 -0500 Subject: [PATCH 15/88] Add RequestID field to Transactions (#10363) * Added request_id field to eth_txes to track external component requests * Rearranged logic, added missing validation, and linted * Fixed mocks * Added new TxStore tests * Addressed PR feedback * Updated migration sequencing * Changed RequestID name to IdempotencyKey and updated type to UUID * Switched IdempotencyKey type back to string --- common/txmgr/txmgr.go | 15 +++++++ common/txmgr/types/mocks/tx_store.go | 26 +++++++++++ common/txmgr/types/tx.go | 9 ++++ common/txmgr/types/tx_store.go | 3 ++ core/chains/evm/txmgr/evm_tx_store.go | 23 ++++++++-- core/chains/evm/txmgr/evm_tx_store_test.go | 29 ++++++++++++ core/chains/evm/txmgr/mocks/evm_tx_store.go | 26 +++++++++++ core/chains/evm/txmgr/txmgr_test.go | 45 +++++++++++++++++++ core/internal/cltest/factories.go | 6 +++ ...2_add_request_id_column_eth_txes_table.sql | 7 +++ 10 files changed, 186 insertions(+), 3 deletions(-) create mode 100644 core/store/migrate/migrations/0192_add_request_id_column_eth_txes_table.sql diff --git a/common/txmgr/txmgr.go b/common/txmgr/txmgr.go index 422e1a364b5..0bcf3e482ee 100644 --- a/common/txmgr/txmgr.go +++ b/common/txmgr/txmgr.go @@ -2,6 +2,7 @@ package txmgr import ( "context" + "database/sql" "fmt" "math/big" "sync" @@ -435,6 +436,20 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Trigger(ad // CreateTransaction inserts a new transaction func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) CreateTransaction(txRequest txmgrtypes.TxRequest[ADDR, TX_HASH], qs ...pg.QOpt) (tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) { + // Check for existing Tx with IdempotencyKey. If found, return the Tx and do nothing + // Skipping CreateTransaction to avoid double send + if txRequest.IdempotencyKey != nil { + var existingTx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] + existingTx, err = b.txStore.FindTxWithIdempotencyKey(*txRequest.IdempotencyKey, b.chainID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return tx, errors.Wrap(err, "Failed to search for transaction with IdempotencyKey") + } + if existingTx != nil { + b.logger.Infow("Found a Tx with IdempotencyKey. Returning existing Tx without creating a new one.", "IdempotencyKey", *txRequest.IdempotencyKey) + return *existingTx, nil + } + } + if err = b.checkEnabled(txRequest.FromAddress); err != nil { return tx, err } diff --git a/common/txmgr/types/mocks/tx_store.go b/common/txmgr/types/mocks/tx_store.go index 055d7852bfd..9c812788bf6 100644 --- a/common/txmgr/types/mocks/tx_store.go +++ b/common/txmgr/types/mocks/tx_store.go @@ -322,6 +322,32 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxAttem return r0, r1 } +// FindTxWithIdempotencyKey provides a mock function with given fields: idempotencyKey, chainID +func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxWithIdempotencyKey(idempotencyKey string, chainID CHAIN_ID) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { + ret := _m.Called(idempotencyKey, chainID) + + var r0 *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] + var r1 error + if rf, ok := ret.Get(0).(func(string, CHAIN_ID) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok { + return rf(idempotencyKey, chainID) + } + if rf, ok := ret.Get(0).(func(string, CHAIN_ID) *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { + r0 = rf(idempotencyKey, chainID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) + } + } + + if rf, ok := ret.Get(1).(func(string, CHAIN_ID) error); ok { + r1 = rf(idempotencyKey, chainID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // FindTxWithSequence provides a mock function with given fields: fromAddress, seq func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxWithSequence(fromAddress ADDR, seq SEQ) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { ret := _m.Called(fromAddress, seq) diff --git a/common/txmgr/types/tx.go b/common/txmgr/types/tx.go index a28c72fd363..a0faa81c3aa 100644 --- a/common/txmgr/types/tx.go +++ b/common/txmgr/types/tx.go @@ -66,6 +66,14 @@ func (s TxAttemptState) String() (str string) { } type TxRequest[ADDR types.Hashable, TX_HASH types.Hashable] struct { + // IdempotencyKey is a globally unique ID set by the caller, to prevent accidental creation of duplicated Txs during retries or crash recovery. + // If this field is set, the TXM will first search existing Txs with this field. + // If found, it will return the existing Tx, without creating a new one. TXM will not validate or ensure that existing Tx is same as the incoming TxRequest. + // If not found, TXM will create a new Tx. + // If IdempotencyKey is set to null, TXM will always create a new Tx. + // Since IdempotencyKey has to be globally unique, consider prepending the service or component's name it is being used by + // Such as {service}-{ID}. E.g vrf-12345 + IdempotencyKey *string FromAddress ADDR ToAddress ADDR EncodedPayload []byte @@ -178,6 +186,7 @@ type Tx[ FEE feetypes.Fee, ] struct { ID int64 + IdempotencyKey *string Sequence *SEQ FromAddress ADDR ToAddress ADDR diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go index 41a989fc769..8c56b8a6ed6 100644 --- a/common/txmgr/types/tx_store.go +++ b/common/txmgr/types/tx_store.go @@ -64,6 +64,9 @@ type TransactionStore[ FindTxAttemptsConfirmedMissingReceipt(chainID CHAIN_ID) (attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) FindTxAttemptsRequiringReceiptFetch(chainID CHAIN_ID) (attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) FindTxAttemptsRequiringResend(olderThan time.Time, maxInFlightTransactions uint32, chainID CHAIN_ID, address ADDR) (attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) + // Search for Tx using the idempotencyKey and chainID + FindTxWithIdempotencyKey(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(fromAddress ADDR, seq SEQ) (etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) FindNextUnstartedTransactionFromAddress(etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fromAddress ADDR, chainID CHAIN_ID, qopts ...pg.QOpt) error FindTransactionsConfirmedInBlockRange(highBlockNumber, lowBlockNumber int64, chainID CHAIN_ID) (etxs []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index 1df4073e528..dbd3437aa82 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -152,6 +152,7 @@ func toOnchainReceipt(rs []*evmtypes.Receipt) []rawOnchainReceipt { // This is exported, as tests and other external code still directly reads DB using this schema. type DbEthTx struct { ID int64 + IdempotencyKey *string Nonce *int64 FromAddress common.Address ToAddress common.Address @@ -218,6 +219,7 @@ func DbEthTxToEthTx(dbEthTx DbEthTx, evmEthTx *Tx) { n := evmtypes.Nonce(*dbEthTx.Nonce) evmEthTx.Sequence = &n } + evmEthTx.IdempotencyKey = dbEthTx.IdempotencyKey evmEthTx.FromAddress = dbEthTx.FromAddress evmEthTx.ToAddress = dbEthTx.ToAddress evmEthTx.EncodedPayload = dbEthTx.EncodedPayload @@ -906,6 +908,21 @@ func (o *evmTxStore) FindReceiptsPendingConfirmation(ctx context.Context, blockN return } +// FindTxWithIdempotencyKey returns any broadcast ethtx with the given idempotencyKey and chainID +func (o *evmTxStore) FindTxWithIdempotencyKey(idempotencyKey string, chainID *big.Int) (etx *Tx, err error) { + var dbEtx DbEthTx + err = o.q.Get(&dbEtx, `SELECT * FROM eth_txes WHERE idempotency_key = $1 and evm_chain_id = $2`, idempotencyKey, chainID.String()) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return nil, pkgerrors.Wrap(err, "FindTxWithIdempotencyKey failed to load eth_txes") + } + etx = new(Tx) + DbEthTxToEthTx(dbEtx, etx) + return +} + // FindTxWithSequence returns any broadcast ethtx with the given nonce func (o *evmTxStore) FindTxWithSequence(fromAddress common.Address, nonce evmtypes.Nonce) (etx *Tx, err error) { etx = new(Tx) @@ -1501,12 +1518,12 @@ func (o *evmTxStore) CreateTransaction(txRequest TxRequest, chainID *big.Int, qo } } err = tx.Get(&dbEtx, ` -INSERT INTO eth_txes (from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id, transmit_checker) +INSERT INTO eth_txes (from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id, transmit_checker, idempotency_key) VALUES ( -$1,$2,$3,$4,$5,'unstarted',NOW(),$6,$7,$8,$9,$10,$11 +$1,$2,$3,$4,$5,'unstarted',NOW(),$6,$7,$8,$9,$10,$11,$12 ) RETURNING "eth_txes".* -`, txRequest.FromAddress, txRequest.ToAddress, txRequest.EncodedPayload, assets.Eth(txRequest.Value), txRequest.FeeLimit, txRequest.Meta, txRequest.Strategy.Subject(), chainID.String(), txRequest.MinConfirmations, txRequest.PipelineTaskRunID, txRequest.Checker) +`, txRequest.FromAddress, txRequest.ToAddress, txRequest.EncodedPayload, assets.Eth(txRequest.Value), txRequest.FeeLimit, txRequest.Meta, txRequest.Strategy.Subject(), chainID.String(), txRequest.MinConfirmations, txRequest.PipelineTaskRunID, txRequest.Checker, txRequest.IdempotencyKey) if err != nil { return pkgerrors.Wrap(err, "CreateEthTransaction failed to insert eth_tx") } diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index b4be30063b5..777a179be45 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -666,6 +666,35 @@ func TestORM_FindReceiptsPendingConfirmation(t *testing.T) { assert.Equal(t, tr.ID, receiptsPlus[0].ID) } +func Test_FindTxWithIdempotencyKey(t *testing.T) { + t.Parallel() + db := pgtest.NewSqlxDB(t) + cfg := newTestChainScopedConfig(t) + txStore := cltest.NewTestTxStore(t, db, cfg.Database()) + ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth() + _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore, 0) + + t.Run("returns nil if no results", func(t *testing.T) { + idempotencyKey := "777" + etx, err := txStore.FindTxWithIdempotencyKey(idempotencyKey, big.NewInt(0)) + require.NoError(t, err) + assert.Nil(t, etx) + }) + + t.Run("returns transaction if it exists", func(t *testing.T) { + idempotencyKey := "777" + cfg.EVM().ChainID() + etx := cltest.MustCreateUnstartedGeneratedTx(t, txStore, fromAddress, big.NewInt(0), + cltest.EvmTxRequestWithIdempotencyKey(idempotencyKey)) + require.Equal(t, idempotencyKey, *etx.IdempotencyKey) + + res, err := txStore.FindTxWithIdempotencyKey(idempotencyKey, big.NewInt(0)) + require.NoError(t, err) + assert.Equal(t, etx.Sequence, res.Sequence) + require.Equal(t, idempotencyKey, *res.IdempotencyKey) + }) +} + func TestORM_FindTxWithSequence(t *testing.T) { t.Parallel() diff --git a/core/chains/evm/txmgr/mocks/evm_tx_store.go b/core/chains/evm/txmgr/mocks/evm_tx_store.go index ef481df3b70..4a06741a2f3 100644 --- a/core/chains/evm/txmgr/mocks/evm_tx_store.go +++ b/core/chains/evm/txmgr/mocks/evm_tx_store.go @@ -428,6 +428,32 @@ func (_m *EvmTxStore) FindTxWithAttempts(etxID int64) (types.Tx[*big.Int, common return r0, r1 } +// FindTxWithIdempotencyKey provides a mock function with given fields: idempotencyKey, chainID +func (_m *EvmTxStore) FindTxWithIdempotencyKey(idempotencyKey string, chainID *big.Int) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) { + ret := _m.Called(idempotencyKey, 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(string, *big.Int) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok { + return rf(idempotencyKey, chainID) + } + if rf, ok := ret.Get(0).(func(string, *big.Int) *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok { + r0 = rf(idempotencyKey, chainID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]) + } + } + + if rf, ok := ret.Get(1).(func(string, *big.Int) error); ok { + r1 = rf(idempotencyKey, chainID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // FindTxWithSequence provides a mock function with given fields: fromAddress, seq func (_m *EvmTxStore) FindTxWithSequence(fromAddress common.Address, seq evmtypes.Nonce) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) { ret := _m.Called(fromAddress, seq) diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 00333d7df87..854ccd6a4af 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -323,6 +323,51 @@ func TestTxm_CreateTransaction(t *testing.T) { require.NotNil(t, m.FwdrDestAddress) require.Equal(t, etx.ToAddress.String(), fwdrAddr.String()) }) + + t.Run("insert Tx successfully with a IdempotencyKey", func(t *testing.T) { + evmConfig.maxQueued = uint64(3) + id := uuid.New() + idempotencyKey := "1" + _, err := txm.CreateTransaction(txmgr.TxRequest{ + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + ToAddress: testutils.NewAddress(), + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: 21000, + PipelineTaskRunID: &id, + Strategy: txmgrcommon.NewSendEveryStrategy(), + }) + assert.NoError(t, err) + }) + + t.Run("doesn't insert eth_tx if a matching tx already exists for that IdempotencyKey", func(t *testing.T) { + evmConfig.maxQueued = uint64(3) + id := uuid.New() + idempotencyKey := "2" + tx1, err := txm.CreateTransaction(txmgr.TxRequest{ + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + ToAddress: testutils.NewAddress(), + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: 21000, + PipelineTaskRunID: &id, + Strategy: txmgrcommon.NewSendEveryStrategy(), + }) + assert.NoError(t, err) + + tx2, err := txm.CreateTransaction(txmgr.TxRequest{ + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + ToAddress: testutils.NewAddress(), + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: 21000, + PipelineTaskRunID: &id, + Strategy: txmgrcommon.NewSendEveryStrategy(), + }) + assert.NoError(t, err) + + assert.Equal(t, tx1.GetID(), tx2.GetID()) + }) } func newMockTxStrategy(t *testing.T) *commontxmmocks.TxStrategy { diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go index 800731f74a4..bfa479af624 100644 --- a/core/internal/cltest/factories.go +++ b/core/internal/cltest/factories.go @@ -348,6 +348,12 @@ func EvmTxRequestWithValue(value big.Int) func(*txmgr.TxRequest) { } } +func EvmTxRequestWithIdempotencyKey(idempotencyKey string) func(*txmgr.TxRequest) { + return func(tx *txmgr.TxRequest) { + tx.IdempotencyKey = &idempotencyKey + } +} + func MustCreateUnstartedTx(t testing.TB, txStore txmgr.EvmTxStore, fromAddress common.Address, toAddress common.Address, encodedPayload []byte, gasLimit uint32, value big.Int, chainID *big.Int, opts ...interface{}) (tx txmgr.Tx) { txRequest := txmgr.TxRequest{ FromAddress: fromAddress, diff --git a/core/store/migrate/migrations/0192_add_request_id_column_eth_txes_table.sql b/core/store/migrate/migrations/0192_add_request_id_column_eth_txes_table.sql new file mode 100644 index 00000000000..6a9ab7846d1 --- /dev/null +++ b/core/store/migrate/migrations/0192_add_request_id_column_eth_txes_table.sql @@ -0,0 +1,7 @@ +-- +goose Up + +ALTER TABLE eth_txes ADD COLUMN idempotency_key varchar(2000) UNIQUE; + +-- +goose Down + +ALTER TABLE eth_txes DROP COLUMN idempotency_key; From 0e2d15a6ce5479c3d5109d0864fe737b0fbc5826 Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Tue, 5 Sep 2023 12:58:55 +0100 Subject: [PATCH 16/88] Increase block time sample size (#10482) --- .../ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go index 1d8500bcc61..3af93f873c1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go @@ -11,7 +11,7 @@ import ( ) var ( - defaultSampleSize = int64(10) + defaultSampleSize = int64(200) defaultBlockTime = time.Second * 1 ) From 08e1bae52b773c8995c8e911ff7096426b69d8fa Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Tue, 5 Sep 2023 18:01:41 +0100 Subject: [PATCH 17/88] Small cleanup in event provider for caching behaviour (#10483) * Small cleanup in event provider for caching behaviour * retain duplicate log behaviour * format * format * update * update --- .../ocr2keeper/evm21/transmit/event_provider.go | 14 +------------- .../evm21/transmit/event_provider_test.go | 7 ++++++- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go index a21cdd25eb0..1ea456ed3d5 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go @@ -159,17 +159,11 @@ func (c *TransmitEventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keep } // processLogs will parse the unseen logs and return the corresponding transmit events. -// If a log was seen before it won't be returned. func (c *TransmitEventProvider) processLogs(latestBlock int64, logs ...logpoller.Log) ([]ocr2keepers.TransmitEvent, error) { vals := []ocr2keepers.TransmitEvent{} - visited := make(map[string]ocr2keepers.TransmitEvent) for _, log := range logs { k := c.logKey(log) - if _, ok := visited[k]; ok { - // ensure we don't have duplicates - continue - } transmitEvent, ok := c.cache.get(ocr2keepers.BlockNumber(log.BlockNumber), k) if !ok { @@ -208,18 +202,12 @@ func (c *TransmitEventProvider) processLogs(latestBlock int64, logs ...logpoller UpkeepID: *upkeepId, CheckBlock: trigger.BlockNumber, } + c.cache.add(k, transmitEvent) } transmitEvent.Confirmations = latestBlock - int64(transmitEvent.TransmitBlock) vals = append(vals, transmitEvent) - visited[k] = transmitEvent - } - - // adding to the cache only after we've processed all the logs - // the next time we call processLogs we don't want to process these logs - for k, e := range visited { - c.cache.add(k, e) } return vals, nil diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go index 291614601ff..aa3480c8c26 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go @@ -151,7 +151,7 @@ func TestTransmitEventProvider_ProcessLogs(t *testing.T) { false, }, { - "same log twice", + "same log twice", // shouldn't happen in practice as log poller should not return duplicate logs []transmitEventLog{ { Log: logpoller.Log{ @@ -187,6 +187,11 @@ func TestTransmitEventProvider_ProcessLogs(t *testing.T) { UpkeepID: id, CheckBlock: ocr2keepers.BlockNumber(1), }, + { + Type: ocr2keepers.PerformEvent, + UpkeepID: id, + CheckBlock: ocr2keepers.BlockNumber(1), + }, }, false, }, From 5aadc9c4d8735a0f1abceb637e769859164baf62 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 5 Sep 2023 14:02:55 -0500 Subject: [PATCH 18/88] bump deps google/uuid, shirou/gopsutil/v3, avast/retry-go/v4, jackc/pgconn (#10481) --- core/scripts/go.mod | 12 ++++++------ core/scripts/go.sum | 29 ++++++++++++++--------------- go.mod | 12 ++++++------ go.sum | 28 ++++++++++++++-------------- integration-tests/go.mod | 10 +++++----- integration-tests/go.sum | 22 ++++++++++++---------- 6 files changed, 57 insertions(+), 56 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 8966ac2d2f4..d9f2cc7c9c3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -11,7 +11,7 @@ require ( github.com/docker/go-connections v0.4.0 github.com/ethereum/go-ethereum v1.12.0 github.com/google/go-cmp v0.5.9 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f github.com/montanaflynn/stats v0.7.1 github.com/olekukonko/tablewriter v0.0.5 @@ -52,7 +52,7 @@ require ( github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/ava-labs/avalanchego v1.10.1 // indirect - github.com/avast/retry-go/v4 v4.3.4 // indirect + github.com/avast/retry-go/v4 v4.5.0 // indirect github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect github.com/benbjohnson/clock v1.3.4 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -180,7 +180,7 @@ require ( github.com/ipfs/go-log v1.0.4 // indirect github.com/ipfs/go-log/v2 v2.1.1 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.14.0 // 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 @@ -294,7 +294,7 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/shirou/gopsutil/v3 v3.22.12 // indirect + github.com/shirou/gopsutil/v3 v3.23.8 // 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.20230831132059-42af68994512 // indirect @@ -321,7 +321,7 @@ require ( github.com/tidwall/gjson v1.16.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.11 // 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 @@ -353,7 +353,7 @@ require ( golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.12.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.10.0 // indirect + golang.org/x/sys v0.11.0 // indirect golang.org/x/term v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.3.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 1a4bba2fccc..26a31aafde8 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -128,8 +128,8 @@ github.com/ava-labs/avalanchego v1.10.1 h1:lBeamJ1iNq+p2oKg2nAs+A65m8vhSDjkiTDbw github.com/ava-labs/avalanchego v1.10.1/go.mod h1:ZvSXWlbkUKlbk3BsWx29a+8eVHe/WBsOxh55BSGoeRk= github.com/ava-labs/coreth v0.12.1 h1:EWSkFGHGVUxmu1pnSK/2pdcxaAVHbGspHqO3Ag+i7sA= github.com/ava-labs/coreth v0.12.1/go.mod h1:/5x54QlIKjlPebkdzTA5ic9wXdejbWOnQosztkv9jxo= -github.com/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM= -github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE= +github.com/avast/retry-go/v4 v4.5.0 h1:QoRAZZ90cj5oni2Lsgl2GW8mNTnUCnmpx/iKpwVisHg= +github.com/avast/retry-go/v4 v4.5.0/go.mod h1:7hLEXp0oku2Nir2xBAsg0PTphp9z71bN5Aq1fboC3+I= 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.44.302 h1:ST3ko6GrJKn3Xi+nAvxjG3uk/V1pW8KC52WLeIxqqNk= @@ -548,8 +548,8 @@ github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= 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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= 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= @@ -727,8 +727,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU 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 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= 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= @@ -1356,8 +1357,10 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 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.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs= -github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI= +github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +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= @@ -1477,9 +1480,8 @@ 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.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +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= @@ -1543,7 +1545,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= 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= @@ -1867,13 +1868,11 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc 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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= diff --git a/go.mod b/go.mod index a2007f5bac3..7d5b1757992 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Depado/ginprom v1.7.11 github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/sprig/v3 v3.2.3 - github.com/avast/retry-go/v4 v4.3.4 + github.com/avast/retry-go/v4 v4.5.0 github.com/btcsuite/btcd v0.23.4 github.com/cometbft/cometbft v0.37.2 github.com/cosmos/cosmos-sdk v0.47.4 @@ -25,7 +25,7 @@ require ( github.com/go-webauthn/webauthn v0.8.2 github.com/gogo/protobuf v1.3.3 github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/gorilla/securecookie v1.1.1 github.com/gorilla/sessions v1.2.1 github.com/gorilla/websocket v1.5.0 @@ -34,7 +34,7 @@ require ( github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/go-plugin v1.4.10 github.com/hdevalence/ed25519consensus v0.1.0 - github.com/jackc/pgconn v1.14.0 + github.com/jackc/pgconn v1.14.1 github.com/jackc/pgtype v1.14.0 github.com/jackc/pgx/v4 v4.18.1 github.com/jpillora/backoff v1.0.0 @@ -62,7 +62,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/rogpeppe/go-internal v1.11.0 github.com/scylladb/go-reflectx v1.0.1 - github.com/shirou/gopsutil/v3 v3.22.12 + github.com/shirou/gopsutil/v3 v3.23.8 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512 @@ -332,7 +332,7 @@ require ( github.com/tidwall/btree v1.6.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.11 // 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 @@ -355,7 +355,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/sys v0.10.0 // indirect + golang.org/x/sys v0.11.0 // indirect google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 // indirect diff --git a/go.sum b/go.sum index 4deab41bc40..a0243097bc0 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV 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/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM= -github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE= +github.com/avast/retry-go/v4 v4.5.0 h1:QoRAZZ90cj5oni2Lsgl2GW8mNTnUCnmpx/iKpwVisHg= +github.com/avast/retry-go/v4 v4.5.0/go.mod h1:7hLEXp0oku2Nir2xBAsg0PTphp9z71bN5Aq1fboC3+I= 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.44.302 h1:ST3ko6GrJKn3Xi+nAvxjG3uk/V1pW8KC52WLeIxqqNk= @@ -543,8 +543,8 @@ github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= 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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= 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= @@ -726,8 +726,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU 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 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= 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= @@ -1356,8 +1357,10 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 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.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs= -github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI= +github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +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= @@ -1478,9 +1481,8 @@ 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.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +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= @@ -1544,7 +1546,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= 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= @@ -1869,12 +1870,11 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc 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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 32e13bbd80e..d3a8b5a19cb 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -10,7 +10,7 @@ require ( github.com/cli/go-gh/v2 v2.0.0 github.com/ethereum/go-ethereum v1.12.0 github.com/go-resty/resty/v2 v2.7.0 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.10.9 github.com/manifoldco/promptui v0.9.0 @@ -69,7 +69,7 @@ require ( 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/v4 v4.3.4 // indirect + github.com/avast/retry-go/v4 v4.5.0 // indirect github.com/aws/aws-sdk-go v1.44.276 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect @@ -242,7 +242,7 @@ require ( github.com/ipfs/go-log v1.0.4 // indirect github.com/ipfs/go-log/v2 v2.1.1 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.14.0 // 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 @@ -378,7 +378,7 @@ require ( github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/sercand/kuberesolver v2.4.0+incompatible // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/shirou/gopsutil/v3 v3.22.12 // indirect + github.com/shirou/gopsutil/v3 v3.23.8 // 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 @@ -408,7 +408,7 @@ require ( github.com/tidwall/gjson v1.16.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.11 // 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 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index b5948436181..5e77b2bddcc 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -637,8 +637,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY 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/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM= -github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE= +github.com/avast/retry-go/v4 v4.5.0 h1:QoRAZZ90cj5oni2Lsgl2GW8mNTnUCnmpx/iKpwVisHg= +github.com/avast/retry-go/v4 v4.5.0/go.mod h1:7hLEXp0oku2Nir2xBAsg0PTphp9z71bN5Aq1fboC3+I= 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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -1240,8 +1240,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -1474,8 +1475,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU 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 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= 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= @@ -2224,8 +2226,10 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= 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.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs= -github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI= +github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +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= @@ -2364,9 +2368,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT 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.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +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= @@ -2447,7 +2450,6 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= From c40169c6dffc479a11b0d1e394e5fafcb7312304 Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 6 Sep 2023 08:08:40 -0400 Subject: [PATCH 19/88] fix/gh-actions-setup-postgres: fixing script to be resilient to array or object docker compose output (#10512) --- .../setup-postgres/wait-for-healthy-postgres.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup-postgres/wait-for-healthy-postgres.sh b/.github/actions/setup-postgres/wait-for-healthy-postgres.sh index 3f0efd66f3b..438cfbaff3d 100755 --- a/.github/actions/setup-postgres/wait-for-healthy-postgres.sh +++ b/.github/actions/setup-postgres/wait-for-healthy-postgres.sh @@ -2,10 +2,24 @@ RETRIES=10 until [ $RETRIES -eq 0 ]; do - if docker compose ps postgres --status running --format json | jq >/dev/null -e 'if (.[0].Health == "healthy") then true else false end'; then + DOCKER_OUTPUT=$(docker compose ps postgres --status running --format json) + JSON_TYPE=$(echo "$DOCKER_OUTPUT" | jq -r 'type') + + if [ "$JSON_TYPE" == "array" ]; then + HEALTH_STATUS=$(echo "$DOCKER_OUTPUT" | jq -r '.[0].Health') + elif [ "$JSON_TYPE" == "object" ]; then + HEALTH_STATUS=$(echo "$DOCKER_OUTPUT" | jq -r '.Health') + else + HEALTH_STATUS="Unknown JSON type: $JSON_TYPE" + fi + + echo "postgres health status: $HEALTH_STATUS" + if [ "$HEALTH_STATUS" == "healthy" ]; then exit 0 fi + echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..." sleep 2 done + exit 1 From 19eb5fcd6c830b1ca38b636da4193eca52caa6b9 Mon Sep 17 00:00:00 2001 From: cfal Date: Wed, 6 Sep 2023 19:09:51 +0700 Subject: [PATCH 20/88] core: use loop.Keystore, support arbitrarily prefixed Cosmos addresses (#10416) * core: use loop.Keystore, support arbitrarily prefixed Cosmos addresses * Update core/chains/cosmos/cosmostxm/helpers_test.go Co-authored-by: Jordan Krage --------- Co-authored-by: Jordan Krage --- core/chains/cosmos/chain.go | 6 +- core/chains/cosmos/cosmostxm/helpers_test.go | 13 ++ core/chains/cosmos/cosmostxm/key_wrapper.go | 70 +++++----- .../cosmos/cosmostxm/keystore_adapter.go | 129 ++++++++++++++++++ core/chains/cosmos/cosmostxm/txm.go | 79 ++++++----- .../cosmos/cosmostxm/txm_internal_test.go | 48 ++++--- core/chains/cosmos/cosmostxm/txm_test.go | 14 +- core/services/chainlink/relayer_factory.go | 7 +- core/services/keystore/cosmos.go | 37 +++++ core/services/keystore/keys/cosmoskey/key.go | 5 +- 10 files changed, 305 insertions(+), 103 deletions(-) create mode 100644 core/chains/cosmos/cosmostxm/keystore_adapter.go diff --git a/core/chains/cosmos/chain.go b/core/chains/cosmos/chain.go index 91f5484e877..c73793c1c3a 100644 --- a/core/chains/cosmos/chain.go +++ b/core/chains/cosmos/chain.go @@ -20,13 +20,13 @@ import ( "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db" "github.com/smartcontractkit/chainlink-relay/pkg/logger" + "github.com/smartcontractkit/chainlink-relay/pkg/loop" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/cosmostxm" "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/types" "github.com/smartcontractkit/chainlink/v2/core/chains/internal" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -54,7 +54,7 @@ type ChainOpts struct { QueryConfig pg.QConfig Logger logger.Logger DB *sqlx.DB - KeyStore keystore.Cosmos + KeyStore loop.Keystore EventBroadcaster pg.EventBroadcaster Configs types.Configs } @@ -112,7 +112,7 @@ type chain struct { lggr logger.Logger } -func newChain(id string, cfg *CosmosConfig, db *sqlx.DB, ks keystore.Cosmos, logCfg pg.QConfig, eb pg.EventBroadcaster, cfgs types.Configs, lggr logger.Logger) (*chain, error) { +func newChain(id string, cfg *CosmosConfig, db *sqlx.DB, ks loop.Keystore, logCfg pg.QConfig, eb pg.EventBroadcaster, cfgs types.Configs, lggr logger.Logger) (*chain, error) { lggr = logger.With(lggr, "cosmosChainID", id) var ch = chain{ id: id, diff --git a/core/chains/cosmos/cosmostxm/helpers_test.go b/core/chains/cosmos/cosmostxm/helpers_test.go index 217160c3e80..ad93189082e 100644 --- a/core/chains/cosmos/cosmostxm/helpers_test.go +++ b/core/chains/cosmos/cosmostxm/helpers_test.go @@ -5,6 +5,7 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" + "golang.org/x/exp/maps" cosmosclient "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/client" ) @@ -28,3 +29,15 @@ func (txm *Txm) MarshalMsg(msg sdk.Msg) (string, []byte, error) { func (txm *Txm) SendMsgBatch(ctx context.Context) { txm.sendMsgBatch(ctx) } + +func (ka *KeystoreAdapter) Accounts(ctx context.Context) ([]string, error) { + ka.mutex.Lock() + defer ka.mutex.Unlock() + err := ka.updateMappingLocked() + if err != nil { + return nil, err + } + addresses := maps.Keys(ka.addressToPubKey) + + return addresses, nil +} diff --git a/core/chains/cosmos/cosmostxm/key_wrapper.go b/core/chains/cosmos/cosmostxm/key_wrapper.go index 6bc36f5aea7..1d2d686c8c0 100644 --- a/core/chains/cosmos/cosmostxm/key_wrapper.go +++ b/core/chains/cosmos/cosmostxm/key_wrapper.go @@ -1,56 +1,62 @@ package cosmostxm import ( - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "bytes" + "context" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) -var _ cryptotypes.PrivKey = KeyWrapper{} - -// KeyWrapper wrapper around a cosmos transmitter key -// for use in the cosmos txbuilder and client, see chainlink-cosmos. +// KeyWrapper uses a KeystoreAdapter to implement the cosmos-sdk PrivKey interface for a specific key. type KeyWrapper struct { - key cosmoskey.Key + adapter *KeystoreAdapter + account string } -// NewKeyWrapper create a key wrapper -func NewKeyWrapper(key cosmoskey.Key) KeyWrapper { - return KeyWrapper{key: key} +var _ cryptotypes.PrivKey = &KeyWrapper{} + +func NewKeyWrapper(adapter *KeystoreAdapter, account string) *KeyWrapper { + return &KeyWrapper{ + adapter: adapter, + account: account, + } } -// Reset nop -func (k KeyWrapper) Reset() {} +func (a *KeyWrapper) Bytes() []byte { + // don't expose the private key. + return nil +} -// ProtoMessage nop -func (k KeyWrapper) ProtoMessage() {} +func (a *KeyWrapper) Sign(msg []byte) ([]byte, error) { + return a.adapter.Sign(context.Background(), a.account, msg) +} -// String nop -func (k KeyWrapper) String() string { - return "" +func (a *KeyWrapper) PubKey() cryptotypes.PubKey { + pubKey, err := a.adapter.PubKey(a.account) + if err != nil { + // return an empty pubkey if it's not found. + return &secp256k1.PubKey{Key: []byte{}} + } + return pubKey } -// Bytes does not expose private key -func (k KeyWrapper) Bytes() []byte { - return []byte{} +func (a *KeyWrapper) Equals(other cryptotypes.LedgerPrivKey) bool { + return bytes.Equal(a.PubKey().Bytes(), other.PubKey().Bytes()) } -// Sign sign a message with key -func (k KeyWrapper) Sign(msg []byte) ([]byte, error) { - return k.key.ToPrivKey().Sign(msg) +func (a *KeyWrapper) Type() string { + return "secp256k1" } -// PubKey get the pubkey -func (k KeyWrapper) PubKey() cryptotypes.PubKey { - return k.key.PublicKey() +func (a *KeyWrapper) Reset() { + // no-op } -// Equals compare against another key -func (k KeyWrapper) Equals(a cryptotypes.LedgerPrivKey) bool { - return k.PubKey().Address().String() == a.PubKey().Address().String() +func (a *KeyWrapper) String() string { + return "" } -// Type nop -func (k KeyWrapper) Type() string { - return "" +func (a *KeyWrapper) ProtoMessage() { + // no-op } diff --git a/core/chains/cosmos/cosmostxm/keystore_adapter.go b/core/chains/cosmos/cosmostxm/keystore_adapter.go new file mode 100644 index 00000000000..c8556015c6e --- /dev/null +++ b/core/chains/cosmos/cosmostxm/keystore_adapter.go @@ -0,0 +1,129 @@ +package cosmostxm + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "sync" + + "github.com/cometbft/cometbft/crypto" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/types/bech32" + "github.com/pkg/errors" + "golang.org/x/crypto/ripemd160" //nolint: staticcheck + + "github.com/smartcontractkit/chainlink-relay/pkg/loop" +) + +type accountInfo struct { + Account string + PubKey *secp256k1.PubKey +} + +// An adapter for a Cosmos loop.Keystore to translate public keys into bech32-prefixed account addresses. +type KeystoreAdapter struct { + keystore loop.Keystore + accountPrefix string + mutex sync.RWMutex + addressToPubKey map[string]*accountInfo +} + +func NewKeystoreAdapter(keystore loop.Keystore, accountPrefix string) *KeystoreAdapter { + return &KeystoreAdapter{ + keystore: keystore, + accountPrefix: accountPrefix, + addressToPubKey: make(map[string]*accountInfo), + } +} + +func (ka *KeystoreAdapter) updateMappingLocked() error { + accounts, err := ka.keystore.Accounts(context.Background()) + if err != nil { + return err + } + + // similar to cosmos-sdk, cache and re-use calculated bech32 addresses to prevent duplicated work. + // ref: https://github.com/cosmos/cosmos-sdk/blob/3b509c187e1643757f5ef8a0b5ae3decca0c7719/types/address.go#L705 + + type cacheEntry struct { + bech32Addr string + accountInfo *accountInfo + } + accountCache := make(map[string]cacheEntry, len(ka.addressToPubKey)) + for bech32Addr, accountInfo := range ka.addressToPubKey { + accountCache[accountInfo.Account] = cacheEntry{bech32Addr: bech32Addr, accountInfo: accountInfo} + } + + addressToPubKey := make(map[string]*accountInfo, len(accounts)) + for _, account := range accounts { + if prevEntry, ok := accountCache[account]; ok { + addressToPubKey[prevEntry.bech32Addr] = prevEntry.accountInfo + continue + } + pubKeyBytes, err := hex.DecodeString(account) + if err != nil { + return err + } + + if len(pubKeyBytes) != secp256k1.PubKeySize { + return errors.New("length of pubkey is incorrect") + } + + sha := sha256.Sum256(pubKeyBytes) + hasherRIPEMD160 := ripemd160.New() + _, _ = hasherRIPEMD160.Write(sha[:]) + address := crypto.Address(hasherRIPEMD160.Sum(nil)) + + bech32Addr, err := bech32.ConvertAndEncode(ka.accountPrefix, address) + if err != nil { + return err + } + + addressToPubKey[bech32Addr] = &accountInfo{ + Account: account, + PubKey: &secp256k1.PubKey{Key: pubKeyBytes}, + } + } + + ka.addressToPubKey = addressToPubKey + return nil +} + +func (ka *KeystoreAdapter) lookup(id string) (*accountInfo, error) { + ka.mutex.RLock() + ai, ok := ka.addressToPubKey[id] + ka.mutex.RUnlock() + if !ok { + // try updating the mapping once, incase there was an update on the keystore. + ka.mutex.Lock() + err := ka.updateMappingLocked() + if err != nil { + ka.mutex.Unlock() + return nil, err + } + ai, ok = ka.addressToPubKey[id] + ka.mutex.Unlock() + if !ok { + return nil, errors.New("No such id") + } + } + return ai, nil +} + +func (ka *KeystoreAdapter) Sign(ctx context.Context, id string, hash []byte) ([]byte, error) { + accountInfo, err := ka.lookup(id) + if err != nil { + return nil, err + } + return ka.keystore.Sign(ctx, accountInfo.Account, hash) +} + +// Returns the cosmos PubKey associated with the prefixed address. +func (ka *KeystoreAdapter) PubKey(address string) (cryptotypes.PubKey, error) { + accountInfo, err := ka.lookup(address) + if err != nil { + return nil, err + } + return accountInfo.PubKey, nil +} diff --git a/core/chains/cosmos/cosmostxm/txm.go b/core/chains/cosmos/cosmostxm/txm.go index 7b0e2ad2887..84118b9381b 100644 --- a/core/chains/cosmos/cosmostxm/txm.go +++ b/core/chains/cosmos/cosmostxm/txm.go @@ -25,10 +25,9 @@ import ( "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db" "github.com/smartcontractkit/chainlink-relay/pkg/logger" + "github.com/smartcontractkit/chainlink-relay/pkg/loop" "github.com/smartcontractkit/chainlink/v2/core/services" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -40,32 +39,33 @@ var ( // Txm manages transactions for the cosmos blockchain. type Txm struct { - starter utils.StartStopOnce - eb pg.EventBroadcaster - sub pg.Subscription - orm *ORM - lggr logger.Logger - tc func() (cosmosclient.ReaderWriter, error) - ks keystore.Cosmos - stop, done chan struct{} - cfg coscfg.Config - gpe cosmosclient.ComposedGasPriceEstimator + starter utils.StartStopOnce + eb pg.EventBroadcaster + sub pg.Subscription + orm *ORM + lggr logger.Logger + tc func() (cosmosclient.ReaderWriter, error) + keystoreAdapter *KeystoreAdapter + stop, done chan struct{} + cfg coscfg.Config + gpe cosmosclient.ComposedGasPriceEstimator } // NewTxm creates a txm. Uses simulation so should only be used to send txes to trusted contracts i.e. OCR. -func NewTxm(db *sqlx.DB, tc func() (cosmosclient.ReaderWriter, error), gpe cosmosclient.ComposedGasPriceEstimator, chainID string, cfg coscfg.Config, ks keystore.Cosmos, lggr logger.Logger, logCfg pg.QConfig, eb pg.EventBroadcaster) *Txm { +func NewTxm(db *sqlx.DB, tc func() (cosmosclient.ReaderWriter, error), gpe cosmosclient.ComposedGasPriceEstimator, chainID string, cfg coscfg.Config, ks loop.Keystore, lggr logger.Logger, logCfg pg.QConfig, eb pg.EventBroadcaster) *Txm { lggr = logger.Named(lggr, "Txm") + keystoreAdapter := NewKeystoreAdapter(ks, cfg.Bech32Prefix()) return &Txm{ - starter: utils.StartStopOnce{}, - eb: eb, - orm: NewORM(chainID, db, lggr, logCfg), - ks: ks, - tc: tc, - lggr: lggr, - stop: make(chan struct{}), - done: make(chan struct{}), - cfg: cfg, - gpe: gpe, + starter: utils.StartStopOnce{}, + eb: eb, + orm: NewORM(chainID, db, lggr, logCfg), + lggr: lggr, + tc: tc, + keystoreAdapter: keystoreAdapter, + stop: make(chan struct{}), + done: make(chan struct{}), + cfg: cfg, + gpe: gpe, } } @@ -259,14 +259,11 @@ func (txm *Txm) sendMsgBatch(ctx context.Context) { } for s, msgs := range msgsByFrom { sender, _ := sdk.AccAddressFromBech32(s) // Already checked validity above - key, err := txm.ks.Get(sender.String()) + err := txm.sendMsgBatchFromAddress(ctx, gasPrice, sender, msgs) if err != nil { - txm.lggr.Errorw("unable to find key for from address", "err", err, "from", sender.String()) - // We check the transmitter key exists when the job is added. So it would have to be deleted - // after it was added for this to happen. Retry on next poll should the key be re-added. + txm.lggr.Errorw("Could not send message batch", "err", err, "from", sender.String()) continue } - txm.sendMsgBatchFromAddress(ctx, gasPrice, sender, key, msgs) if ctx.Err() != nil { return } @@ -274,18 +271,18 @@ func (txm *Txm) sendMsgBatch(ctx context.Context) { } -func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoin, sender sdk.AccAddress, key cosmoskey.Key, msgs adapters.Msgs) { +func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoin, sender sdk.AccAddress, msgs adapters.Msgs) error { tc, err := txm.tc() if err != nil { logger.Criticalw(txm.lggr, "unable to get client", "err", err) - return + return err } an, sn, err := tc.Account(sender) if err != nil { txm.lggr.Warnw("unable to read account", "err", err, "from", sender.String()) // If we can't read the account, assume transient api issues and leave msgs unstarted // to retry on next poll. - return + return err } txm.lggr.Debugw("simulating batch", "from", sender, "msgs", msgs, "seqnum", sn) @@ -296,27 +293,27 @@ func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoi // Note one rare scenario in which this can happen: the cosmos node misbehaves // in that it confirms a txhash is present but still gives an old seq num. // This is benign as the next retry will succeeds. - return + return err } txm.lggr.Debugw("simulation results", "from", sender, "succeeded", simResults.Succeeded, "failed", simResults.Failed) err = txm.orm.UpdateMsgs(simResults.Failed.GetSimMsgsIDs(), db.Errored, nil) if err != nil { txm.lggr.Errorw("unable to mark failed sim txes as errored", "err", err, "from", sender.String()) // If we can't mark them as failed retry on next poll. Presumably same ones will fail. - return + return err } // Continue if there are no successful txes if len(simResults.Succeeded) == 0 { txm.lggr.Warnw("all sim msgs errored, not sending tx", "from", sender.String()) - return + return errors.New("all sim msgs errored") } // Get the gas limit for the successful batch s, err := tc.SimulateUnsigned(simResults.Succeeded.GetMsgs(), sn) if err != nil { // In the OCR context this should only happen upon stale report txm.lggr.Warnw("unexpected failure after successful simulation", "err", err) - return + return err } gasLimit := s.GasInfo.GasUsed @@ -324,14 +321,14 @@ func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoi if err != nil { txm.lggr.Warnw("unable to get latest block", "err", err, "from", sender.String()) // Assume transient api issue and retry. - return + return err } timeoutHeight := uint64(lb.Block.Header.Height) + uint64(txm.cfg.BlocksUntilTxTimeout()) signedTx, err := tc.CreateAndSign(simResults.Succeeded.GetMsgs(), an, sn, gasLimit, txm.cfg.GasLimitMultiplier(), - gasPrice, NewKeyWrapper(key), timeoutHeight) + gasPrice, NewKeyWrapper(txm.keystoreAdapter, sender.String()), timeoutHeight) if err != nil { txm.lggr.Errorw("unable to sign tx", "err", err, "from", sender.String()) - return + return err } // We need to ensure that we either broadcast successfully and mark the tx as @@ -367,14 +364,16 @@ func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoi if err != nil { txm.lggr.Errorw("error broadcasting tx", "err", err, "from", sender.String()) // Was unable to broadcast, retry on next poll - return + return err } maxPolls, pollPeriod := txm.confirmPollConfig() if err := txm.confirmTx(ctx, tc, resp.TxResponse.TxHash, simResults.Succeeded.GetSimMsgsIDs(), maxPolls, pollPeriod); err != nil { txm.lggr.Errorw("error confirming tx", "err", err, "hash", resp.TxResponse.TxHash) - return + return err } + + return nil } func (txm *Txm) confirmPollConfig() (maxPolls int, pollPeriod time.Duration) { diff --git a/core/chains/cosmos/cosmostxm/txm_internal_test.go b/core/chains/cosmos/cosmostxm/txm_internal_test.go index 6a9944a1a53..17eeb74421a 100644 --- a/core/chains/cosmos/cosmostxm/txm_internal_test.go +++ b/core/chains/cosmos/cosmostxm/txm_internal_test.go @@ -54,22 +54,27 @@ func TestTxm(t *testing.T) { lggr := testutils.LoggerAssertMaxLevel(t, zapcore.ErrorLevel) ks := keystore.New(db, utils.FastScryptParams, lggr, pgtest.NewQConfig(true)) require.NoError(t, ks.Unlock("blah")) - k1, err := ks.Cosmos().Create() - require.NoError(t, err) - sender1, err := cosmostypes.AccAddressFromBech32(k1.PublicKeyStr()) - require.NoError(t, err) - k2, err := ks.Cosmos().Create() - require.NoError(t, err) - sender2, err := cosmostypes.AccAddressFromBech32(k2.PublicKeyStr()) + + for i := 0; i < 4; i++ { + _, err := ks.Cosmos().Create() + require.NoError(t, err) + } + + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + adapter := cosmostxm.NewKeystoreAdapter(loopKs, "wasm") + accounts, err := adapter.Accounts(testutils.Context(t)) require.NoError(t, err) - k3, err := ks.Cosmos().Create() + require.Equal(t, len(accounts), 4) + + sender1, err := cosmostypes.AccAddressFromBech32(accounts[0]) require.NoError(t, err) - contract, err := cosmostypes.AccAddressFromBech32(k3.PublicKeyStr()) + sender2, err := cosmostypes.AccAddressFromBech32(accounts[1]) require.NoError(t, err) - k4, err := ks.Cosmos().Create() + contract, err := cosmostypes.AccAddressFromBech32(accounts[2]) require.NoError(t, err) - contract2, err := cosmostypes.AccAddressFromBech32(k4.PublicKeyStr()) + contract2, err := cosmostypes.AccAddressFromBech32(accounts[3]) require.NoError(t, err) + logCfg := pgtest.NewQConfig(true) chainID := cosmostest.RandomChainID() two := int64(2) @@ -90,7 +95,8 @@ func TestTxm(t *testing.T) { t.Run("single msg", func(t *testing.T) { tc := newReaderWriterMock(t) tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil } - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, logCfg, nil) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, logCfg, nil) // Enqueue a single msg, then send it in a batch id1, err := txm.Enqueue(contract.String(), generateExecuteMsg(t, []byte(`1`), sender1, contract)) @@ -126,7 +132,8 @@ func TestTxm(t *testing.T) { t.Run("two msgs different accounts", func(t *testing.T) { tc := newReaderWriterMock(t) tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil } - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil) id1, err := txm.Enqueue(contract.String(), generateExecuteMsg(t, []byte(`0`), sender1, contract)) require.NoError(t, err) @@ -181,7 +188,8 @@ func TestTxm(t *testing.T) { t.Run("two msgs different contracts", func(t *testing.T) { tc := newReaderWriterMock(t) tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil } - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil) id1, err := txm.Enqueue(contract.String(), generateExecuteMsg(t, []byte(`0`), sender1, contract)) require.NoError(t, err) @@ -244,7 +252,8 @@ func TestTxm(t *testing.T) { TxResponse: &cosmostypes.TxResponse{TxHash: "0x123"}, }, errors.New("not found")).Twice() tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil } - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil) i, err := txm.ORM().InsertMsg("blah", "", []byte{0x01}) require.NoError(t, err) txh := "0x123" @@ -274,7 +283,8 @@ func TestTxm(t *testing.T) { TxResponse: &cosmostypes.TxResponse{TxHash: txHash3}, }, nil).Once() tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil } - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil) // Insert and broadcast 3 msgs with different txhashes. id1, err := txm.ORM().InsertMsg("blah", "", []byte{0x01}) @@ -317,7 +327,8 @@ func TestTxm(t *testing.T) { TxMsgTimeout: &timeout, }} cfgShortExpiry.SetDefaults() - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgShortExpiry, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgShortExpiry, loopKs, lggr, pgtest.NewQConfig(true), nil) // Send a single one expired id1, err := txm.ORM().InsertMsg("blah", "", []byte{0x03}) @@ -362,7 +373,8 @@ func TestTxm(t *testing.T) { MaxMsgsPerBatch: &two, }} cfgMaxMsgs.SetDefaults() - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgMaxMsgs, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgMaxMsgs, loopKs, lggr, pgtest.NewQConfig(true), nil) // Leftover started is processed msg1 := generateExecuteMsg(t, []byte{0x03}, sender1, contract) diff --git a/core/chains/cosmos/cosmostxm/txm_test.go b/core/chains/cosmos/cosmostxm/txm_test.go index 7bfd76e1d8c..9966ff44a5b 100644 --- a/core/chains/cosmos/cosmostxm/txm_test.go +++ b/core/chains/cosmos/cosmostxm/txm_test.go @@ -63,11 +63,17 @@ func TestTxm_Integration(t *testing.T) { tc, err := cosmosclient.NewClient(chainID, tendermintURL, cosmos.DefaultRequestTimeout, lggr) require.NoError(t, err) + loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()} + keystoreAdapter := cosmostxm.NewKeystoreAdapter(loopKs, *cosmosChain.Bech32Prefix) + // First create a transmitter key and fund it with 1k native tokens require.NoError(t, ks.Unlock("blah")) - transmitterKey, err := ks.Cosmos().Create() + err = ks.Cosmos().EnsureKey() + require.NoError(t, err) + ksAccounts, err := keystoreAdapter.Accounts(testutils.Context(t)) require.NoError(t, err) - transmitterID, err := sdk.AccAddressFromBech32(transmitterKey.PublicKeyStr()) + transmitterAddress := ksAccounts[0] + transmitterID, err := sdk.AccAddressFromBech32(transmitterAddress) require.NoError(t, err) an, sn, err := tc.Account(accounts[0].Address) require.NoError(t, err) @@ -82,13 +88,13 @@ func TestTxm_Integration(t *testing.T) { // the chainlink-cosmos repo instead of copying it to cores testdata contractID := cosmosclient.DeployTestContract(t, tendermintURL, chainID, *cosmosChain.FeeToken, accounts[0], cosmosclient.Account{ Name: "transmitter", - PrivateKey: cosmostxm.NewKeyWrapper(transmitterKey), + PrivateKey: cosmostxm.NewKeyWrapper(keystoreAdapter, transmitterAddress), Address: transmitterID, }, tc, testdir, "../../../testdata/cosmos/my_first_contract.wasm") tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil } // Start txm - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, &chainConfig, ks.Cosmos(), lggr, pgtest.NewQConfig(true), eb) + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, &chainConfig, loopKs, lggr, pgtest.NewQConfig(true), eb) require.NoError(t, txm.Start(testutils.Context(t))) // Change the contract state diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 6321b575b13..94d0e43403a 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -227,7 +227,10 @@ type CosmosFactoryConfig struct { func (r *RelayerFactory) NewCosmos(ctx context.Context, config CosmosFactoryConfig) (map[relay.ID]cosmos.LoopRelayerChainer, error) { relayers := make(map[relay.ID]cosmos.LoopRelayerChainer) - var lggr = r.Logger.Named("Cosmos") + var ( + lggr = r.Logger.Named("Cosmos") + loopKs = &keystore.CosmosLoopKeystore{Cosmos: config.Keystore} + ) // create one relayer per chain id for _, chainCfg := range config.CosmosConfigs { @@ -237,7 +240,7 @@ func (r *RelayerFactory) NewCosmos(ctx context.Context, config CosmosFactoryConf QueryConfig: r.QConfig, Logger: lggr.Named(relayId.ChainID.String()), DB: r.DB, - KeyStore: config.Keystore, + KeyStore: loopKs, EventBroadcaster: config.EventBroadcaster, } opts.Configs = cosmos.NewConfigs(cosmos.CosmosConfigs{chainCfg}) diff --git a/core/services/keystore/cosmos.go b/core/services/keystore/cosmos.go index 07abafa3efd..c06dfcdbcea 100644 --- a/core/services/keystore/cosmos.go +++ b/core/services/keystore/cosmos.go @@ -1,10 +1,12 @@ package keystore import ( + "context" "fmt" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-relay/pkg/loop" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" ) @@ -144,3 +146,38 @@ func (ks *cosmos) getByID(id string) (cosmoskey.Key, error) { } return key, nil } + +// CosmosLoopKeystore implements the [github.com/smartcontractkit/chainlink-relay/pkg/loop.Keystore] interface and +// handles signing for Cosmos messages. +type CosmosLoopKeystore struct { + Cosmos +} + +var _ loop.Keystore = &CosmosLoopKeystore{} + +func (lk *CosmosLoopKeystore) Sign(ctx context.Context, id string, hash []byte) ([]byte, error) { + k, err := lk.Get(id) + if err != nil { + return nil, err + } + // loopp spec requires passing nil hash to check existence of id + if hash == nil { + return nil, nil + } + + return k.ToPrivKey().Sign(hash) +} + +func (lk *CosmosLoopKeystore) Accounts(ctx context.Context) ([]string, error) { + keys, err := lk.GetAll() + if err != nil { + return nil, err + } + + accounts := []string{} + for _, k := range keys { + accounts = append(accounts, k.PublicKeyStr()) + } + + return accounts, nil +} diff --git a/core/services/keystore/keys/cosmoskey/key.go b/core/services/keystore/keys/cosmoskey/key.go index 6783232e8b7..3e516a21ab5 100644 --- a/core/services/keystore/keys/cosmoskey/key.go +++ b/core/services/keystore/keys/cosmoskey/key.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/types" ) var secpSigningAlgo, _ = keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), []keyring.SignatureAlgo{hd.Secp256k1}) @@ -78,10 +77,8 @@ func (key Key) PublicKey() (pubKey cryptotypes.PubKey) { return key.k.PubKey() } -// PublicKeyStr returns the cosmos address of the public key func (key Key) PublicKeyStr() string { - addr := types.AccAddress(key.k.PubKey().Address()) - return addr.String() + return fmt.Sprintf("%X", key.k.PubKey().Bytes()) } func (key Key) Raw() Raw { From 43030bdc6fa314c47f02b076e3f32d408f6eeb9e Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 6 Sep 2023 07:10:04 -0500 Subject: [PATCH 21/88] shadow: declaration of err shadows declaration at line * (govet) (#10468) --- core/chains/evm/chain.go | 9 +-- core/chains/evm/chain_test.go | 11 +-- core/chains/evm/log/helpers_test.go | 3 +- core/chains/evm/txmgr/broadcaster_test.go | 68 +++++++------------ core/internal/cltest/job_factories.go | 4 +- core/internal/cltest/mocks.go | 8 +-- core/internal/features/features_test.go | 3 +- core/services/blockhashstore/bhs_test.go | 3 +- core/services/blockhashstore/delegate_test.go | 3 +- .../chainlink/relayer_chain_interoperators.go | 7 +- core/services/chainlink/relayer_factory.go | 5 +- core/services/cron/cron_test.go | 6 +- core/services/directrequest/delegate_test.go | 9 +-- core/services/feeds/orm_test.go | 3 +- core/services/feeds/service_test.go | 3 +- core/services/fluxmonitorv2/orm_test.go | 6 +- core/services/functions/listener_test.go | 6 +- core/services/job/helpers_test.go | 5 +- core/services/job/job_orm_test.go | 60 ++++++---------- .../job/job_pipeline_orm_integration_test.go | 9 +-- core/services/job/runner_integration_test.go | 29 ++++---- core/services/job/spawner_test.go | 8 +-- .../registry_synchronizer_helper_test.go | 3 +- core/services/keeper/upkeep_executer_test.go | 6 +- core/services/ocr2/delegate.go | 2 +- core/services/ocr2/delegate_test.go | 3 +- .../v1/internal/testutils.go | 16 ++--- core/services/pipeline/orm_test.go | 10 ++- core/services/pipeline/runner_test.go | 6 +- core/services/pipeline/task.eth_call_test.go | 4 +- core/services/pipeline/task.eth_tx_test.go | 3 +- core/services/relay/evm/relayer_extender.go | 10 +-- core/services/vrf/delegate_test.go | 3 +- core/web/resolver/eth_key_test.go | 4 +- 34 files changed, 123 insertions(+), 215 deletions(-) diff --git a/core/chains/evm/chain.go b/core/chains/evm/chain.go index f63983a3d5c..524e84fd51b 100644 --- a/core/chains/evm/chain.go +++ b/core/chains/evm/chain.go @@ -96,14 +96,11 @@ type LegacyChainContainer interface { var _ LegacyChainContainer = &LegacyChains{} -func NewLegacyChains(cfg AppConfig, m map[string]Chain) (*LegacyChains, error) { - if cfg == nil { - return nil, fmt.Errorf("must provide non-nil app config") - } +func NewLegacyChains(m map[string]Chain, evmCfgs toml.EVMConfigs) *LegacyChains { return &LegacyChains{ ChainsKV: chains.NewChainsKV[Chain](m), - cfgs: chains.NewConfigs[utils.Big, evmtypes.Node](cfg.EVMConfigs()), - }, nil + cfgs: chains.NewConfigs[utils.Big, evmtypes.Node](evmCfgs), + } } func (c *LegacyChains) ChainNodeConfigs() evmtypes.Configs { diff --git a/core/chains/evm/chain_test.go b/core/chains/evm/chain_test.go index e80bfc02934..3ae8a74bfe2 100644 --- a/core/chains/evm/chain_test.go +++ b/core/chains/evm/chain_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" @@ -20,16 +21,16 @@ func TestLegacyChains(t *testing.T) { c.On("ID").Return(big.NewInt(7)) m := map[string]evm.Chain{c.ID().String(): c} - l, err := evm.NewLegacyChains(evmCfg, m) - assert.NoError(t, err) + l := evm.NewLegacyChains(m, evmCfg.EVMConfigs()) assert.NotNil(t, l.ChainNodeConfigs()) got, err := l.Get(c.ID().String()) assert.NoError(t, err) assert.Equal(t, c, got) - l, err = evm.NewLegacyChains(nil, m) - assert.Error(t, err) - assert.Nil(t, l) + require.NotPanics(t, func() { + l = evm.NewLegacyChains(m, nil) + assert.NotNil(t, l.ChainNodeConfigs()) + }) } func TestRelayConfigInit(t *testing.T) { diff --git a/core/chains/evm/log/helpers_test.go b/core/chains/evm/log/helpers_test.go index e11c9faaf46..d55a44373f2 100644 --- a/core/chains/evm/log/helpers_test.go +++ b/core/chains/evm/log/helpers_test.go @@ -121,8 +121,7 @@ func (c broadcasterHelperCfg) newWithEthClient(t *testing.T, ethClient evmclient LogBroadcaster: &log.NullBroadcaster{}, MailMon: mailMon, }) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) pipelineHelper := cltest.NewJobPipelineV2(t, config.WebServer(), config.JobPipeline(), config.Database(), legacyChains, c.db, kst, nil, nil) return &broadcasterHelper{ diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 2e3a1e0f731..2e665bc3c8f 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -58,24 +58,25 @@ func NewTestEthBroadcaster( config evmconfig.ChainScopedConfig, checkerFactory txmgr.TransmitCheckerFactory, nonceAutoSync bool, -) (*txmgr.Broadcaster, error) { +) *txmgr.Broadcaster { t.Helper() - eventBroadcaster := cltest.NewEventBroadcaster(t, config.Database().URL()) - err := eventBroadcaster.Start(testutils.Context(t.(*testing.T))) - require.NoError(t, err) - t.Cleanup(func() { assert.NoError(t, eventBroadcaster.Close()) }) + eb := cltest.NewEventBroadcaster(t, config.Database().URL()) + ctx := testutils.Context(t) + require.NoError(t, eb.Start(ctx)) + t.Cleanup(func() { assert.NoError(t, eb.Close()) }) + lggr := logger.TestLogger(t) ge := config.EVM().GasEstimator() estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), ge.BlockHistory(), lggr), ge.EIP1559DynamicFees()) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator) txNonceSyncer := txmgr.NewNonceSyncer(txStore, lggr, ethClient, keyStore) - ethBroadcaster := txmgr.NewEvmBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), config.Database().Listener(), keyStore, eventBroadcaster, txBuilder, txNonceSyncer, lggr, checkerFactory, nonceAutoSync) + ethBroadcaster := txmgr.NewEvmBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), config.Database().Listener(), keyStore, eb, txBuilder, txNonceSyncer, lggr, checkerFactory, nonceAutoSync) // Mark instance as test ethBroadcaster.XXXTestDisableUnstartedTxAutoProcessing() - err = ethBroadcaster.Start(testutils.Context(t)) + require.NoError(t, ethBroadcaster.Start(ctx)) t.Cleanup(func() { assert.NoError(t, ethBroadcaster.Close()) }) - return ethBroadcaster, err + return ethBroadcaster } func TestEthBroadcaster_Lifecycle(t *testing.T) { @@ -150,8 +151,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { evmcfg := evmtest.NewChainScopedConfig(t, cfg) checkerFactory := &txmgr.CheckerFactory{Client: ethClient} - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false) toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") timeNow := time.Now() @@ -351,8 +351,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { c.EVM[0].GasEstimator.PriceMax = assets.NewWeiI(rnd + 2) }) evmcfg = evmtest.NewChainScopedConfig(t, cfg) - eb, err = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false) - require.NoError(t, err) + eb = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false) t.Run("sends transactions with type 0x2 in EIP-1559 mode", func(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { @@ -500,8 +499,7 @@ func TestEthBroadcaster_TransmitChecking(t *testing.T) { evmcfg := evmtest.NewChainScopedConfig(t, cfg) checkerFactory := &testCheckerFactory{} - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false) checker := txmgr.TransmitCheckerSpec{ CheckerType: txmgr.TransmitCheckerTypeSimulate, @@ -648,8 +646,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success_WithMultiplier(t *testing ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { assert.Equal(t, int(1600), int(tx.Gas())) @@ -729,8 +726,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) // Crashed right after we commit the database transaction that saved // the nonce to the eth_tx so evm_key_states.next_nonce has not been @@ -768,8 +764,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) // Crashed right after we commit the database transaction that saved // the nonce to the eth_tx so keys.next_nonce has not been @@ -807,8 +802,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) // Crashed right after we commit the database transaction that saved // the nonce to the eth_tx so keys.next_nonce has not been @@ -845,8 +839,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) // Crashed right after we commit the database transaction that saved // the nonce to the eth_tx so keys.next_nonce has not been @@ -885,8 +878,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) // Crashed right after we commit the database transaction that saved // the nonce to the eth_tx so keys.next_nonce has not been @@ -929,8 +921,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) // Crashed right after we commit the database transaction that saved // the nonce to the eth_tx so keys.next_nonce has not been @@ -996,8 +987,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { evmcfg := evmtest.NewChainScopedConfig(t, cfg) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false) require.NoError(t, utils.JustError(db.Exec(`SET CONSTRAINTS pipeline_runs_pipeline_spec_id_fkey DEFERRED`))) @@ -1474,8 +1464,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { c.EVM[0].GasEstimator.BumpMin = assets.NewWeiI(0) c.EVM[0].GasEstimator.BumpPercent = ptr[uint16](0) })) - eb2, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) - require.NoError(t, err) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) cltest.MustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID) // First was underpriced @@ -1565,8 +1554,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { c.EVM[0].GasEstimator.BumpMin = assets.NewWeiI(0) c.EVM[0].GasEstimator.BumpPercent = ptr[uint16](0) })) - eb2, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) - require.NoError(t, err) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) cltest.MustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID) underpricedError := "transaction underpriced" localNextNonce := getLocalNextNonce(t, ethKeyStore, fromAddress) @@ -1596,8 +1584,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true) c.EVM[0].GasEstimator.TipCapDefault = assets.NewWeiI(0) })) - eb2, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) - require.NoError(t, err) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) retryable, err := eb2.ProcessUnstartedTxs(testutils.Context(t), fromAddress) require.Error(t, err) @@ -1610,8 +1597,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true) c.EVM[0].GasEstimator.TipCapDefault = gasTipCapDefault })) - eb2, err = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) - require.NoError(t, err) + eb2 = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false) // Second was underpriced but above minimum ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { @@ -1659,8 +1645,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { next, err := realKeystore.Eth().NextSequence(fromAddress, testutils.FixtureChainID) require.NoError(t, err) kst.On("NextSequence", fromAddress, testutils.FixtureChainID, mock.Anything).Return(next, nil).Once() - eb, err := NewTestEthBroadcaster(t, txStore, ethClient, kst, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, ethClient, kst, evmcfg, &testCheckerFactory{}, false) t.Run("tx signing fails", func(t *testing.T) { etx := cltest.MustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID) @@ -1734,8 +1719,7 @@ func TestEthBroadcaster_Trigger(t *testing.T) { txStore := cltest.NewTestTxStore(t, db, cfg.Database()) evmcfg := evmtest.NewChainScopedConfig(t, cfg) ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth() - eb, err := NewTestEthBroadcaster(t, txStore, evmtest.NewEthClientMockWithDefaultChain(t), ethKeyStore, evmcfg, &testCheckerFactory{}, false) - require.NoError(t, err) + eb := NewTestEthBroadcaster(t, txStore, evmtest.NewEthClientMockWithDefaultChain(t), ethKeyStore, evmcfg, &testCheckerFactory{}, false) eb.Trigger(testutils.NewAddress()) eb.Trigger(testutils.NewAddress()) diff --git a/core/internal/cltest/job_factories.go b/core/internal/cltest/job_factories.go index fd496c5f972..ef59a9d312c 100644 --- a/core/internal/cltest/job_factories.go +++ b/core/internal/cltest/job_factories.go @@ -6,7 +6,6 @@ import ( "github.com/google/uuid" "github.com/smartcontractkit/sqlx" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -66,8 +65,7 @@ func getORMs(t *testing.T, db *sqlx.DB) (jobORM job.ORM, pipelineORM pipeline.OR pipelineORM = pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(db, lggr, config.Database()) cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) - assert.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) jobORM = job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, config.Database()) t.Cleanup(func() { jobORM.Close() }) return diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index 4984b8157f1..423791f716c 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -27,7 +27,6 @@ import ( gethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/robfig/cron/v3" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // MockSubscription a mock subscription @@ -424,14 +423,13 @@ func NewLegacyChainsWithMockChain(t testing.TB, ethClient evmclient.Client, cfg ch.On("ID").Return(scopedCfg.EVM().ChainID()) ch.On("Config").Return(scopedCfg) - return NewLegacyChainsWithChain(t, ch, cfg) + return NewLegacyChainsWithChain(ch, cfg) } -func NewLegacyChainsWithChain(t testing.TB, ch evm.Chain, cfg evm.AppConfig) evm.LegacyChainContainer { +func NewLegacyChainsWithChain(ch evm.Chain, cfg evm.AppConfig) evm.LegacyChainContainer { m := map[string]evm.Chain{ch.ID().String(): ch} - legacyChains, err := evm.NewLegacyChains(cfg, m) - require.NoError(t, err) + legacyChains := evm.NewLegacyChains(m, cfg.EVMConfigs()) legacyChains.SetDefault(ch) return legacyChains } diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index e730ec5f3a0..2e2d29c248d 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -1380,8 +1380,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { ethClient.On("HeadByHash", mock.Anything, h41.Hash).Return(&h41, nil).Maybe() ethClient.On("HeadByHash", mock.Anything, h42.Hash).Return(&h42, nil).Maybe() - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) for _, re := range cc.Slice() { require.NoError(t, re.Start(testutils.Context(t))) } diff --git a/core/services/blockhashstore/bhs_test.go b/core/services/blockhashstore/bhs_test.go index d0e5ac71a7b..79494ea41f6 100644 --- a/core/services/blockhashstore/bhs_test.go +++ b/core/services/blockhashstore/bhs_test.go @@ -30,8 +30,7 @@ func TestStoreRotatesFromAddresses(t *testing.T) { kst := cltest.NewKeyStore(t, db, cfg.Database()) require.NoError(t, kst.Unlock(cltest.Password)) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), GeneralConfig: cfg, Client: ethClient}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) chain, err := legacyChains.Get(cltest.FixtureChainID.String()) require.NoError(t, err) lggr := logger.TestLogger(t) diff --git a/core/services/blockhashstore/delegate_test.go b/core/services/blockhashstore/delegate_test.go index 3a9c01ae399..78242d519d7 100644 --- a/core/services/blockhashstore/delegate_test.go +++ b/core/services/blockhashstore/delegate_test.go @@ -70,8 +70,7 @@ func createTestDelegate(t *testing.T) (*blockhashstore.Delegate, *testData) { LogPoller: lp, }, ) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) return blockhashstore.NewDelegate(lggr, legacyChains, kst), &testData{ ethClient: ethClient, ethKeyStore: kst, diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 01c46c691ff..65859338b6c 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -9,6 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-relay/pkg/loop" "github.com/smartcontractkit/chainlink-relay/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" @@ -117,11 +118,7 @@ func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfi } } - legacy, err := evm.NewLegacyChains(config.AppConfig, legacyMap) - if err != nil { - return err - } - op.legacyChains.EVMChains = legacy + op.legacyChains.EVMChains = evm.NewLegacyChains(legacyMap, config.AppConfig.EVMConfigs()) // TODO BCF-2510 this may not be necessary if EVM is not enabled by default if defaultChain != nil { op.legacyChains.EVMChains.SetDefault(defaultChain) diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 94d0e43403a..4ff70a585ac 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -55,10 +55,7 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m if err != nil { return nil, err } - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(evmRelayExtenders) - if err != nil { - return nil, err - } + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(evmRelayExtenders) for _, ext := range evmRelayExtenders.Slice() { relayID := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(ext.Chain().ID().String())} chain, err := legacyChains.Get(relayID.ChainID.String()) diff --git a/core/services/cron/cron_test.go b/core/services/cron/cron_test.go index 1d89248d4a5..174f80586ae 100644 --- a/core/services/cron/cron_test.go +++ b/core/services/cron/cron_test.go @@ -32,8 +32,7 @@ func TestCronV2Pipeline(t *testing.T) { lggr := logger.TestLogger(t) orm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db, lggr, cfg.Database()) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders) jobORM := job.NewORM(db, legacyChains, orm, btORM, keyStore, lggr, cfg.Database()) jb := &job.Job{ @@ -45,8 +44,7 @@ func TestCronV2Pipeline(t *testing.T) { } delegate := cron.NewDelegate(runner, lggr) - err = jobORM.CreateJob(jb) - require.NoError(t, err) + require.NoError(t, jobORM.CreateJob(jb)) serviceArray, err := delegate.ServicesForSpec(*jb) require.NoError(t, err) assert.Len(t, serviceArray, 1) diff --git a/core/services/directrequest/delegate_test.go b/core/services/directrequest/delegate_test.go index 8a453dbe9db..0a4334e8693 100644 --- a/core/services/directrequest/delegate_test.go +++ b/core/services/directrequest/delegate_test.go @@ -47,8 +47,7 @@ func TestDelegate_ServicesForSpec(t *testing.T) { relayerExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, MailMon: mailMon, KeyStore: keyStore.Eth()}) lggr := logger.TestLogger(t) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders) delegate := directrequest.NewDelegate(lggr, runner, nil, legacyChains, mailMon) t.Run("Spec without DirectRequestSpec", func(t *testing.T) { @@ -89,8 +88,7 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi lggr := logger.TestLogger(t) orm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db, lggr, cfg.Database()) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jobORM := job.NewORM(db, legacyChains, orm, btORM, keyStore, lggr, cfg.Database()) delegate := directrequest.NewDelegate(lggr, runner, orm, legacyChains, mailMon) @@ -99,8 +97,7 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi if specF != nil { specF(jb) } - err = jobORM.CreateJob(jb) - require.NoError(t, err) + require.NoError(t, jobORM.CreateJob(jb)) serviceArray, err := delegate.ServicesForSpec(*jb) require.NoError(t, err) assert.Len(t, serviceArray, 1) diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go index 5294028b352..f2dacc4f02f 100644 --- a/core/services/feeds/orm_test.go +++ b/core/services/feeds/orm_test.go @@ -1479,8 +1479,7 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job { bridgeORM = bridges.NewORM(db, lggr, config.Database()) relayExtenders = evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) ) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, config.Database()) require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey)) require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey)) diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index a2d57338c5c..c864b8c1922 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -181,8 +181,7 @@ func setupTestServiceCfg(t *testing.T, overrideCfg func(c *chainlink.Config, s * ethKeyStore := cltest.NewKeyStore(t, db, gcfg.Database()).Eth() relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{GeneralConfig: gcfg, HeadTracker: headtracker.NullTracker, KeyStore: ethKeyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) keyStore.On("Eth").Return(ethKeyStore) keyStore.On("CSA").Return(csaKeystore) keyStore.On("P2P").Return(p2pKeystore) diff --git a/core/services/fluxmonitorv2/orm_test.go b/core/services/fluxmonitorv2/orm_test.go index e7185efa7bd..caaea838517 100644 --- a/core/services/fluxmonitorv2/orm_test.go +++ b/core/services/fluxmonitorv2/orm_test.go @@ -95,8 +95,7 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) { bridgeORM := bridges.NewORM(db, lggr, cfg.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{GeneralConfig: cfg, DB: db, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) // Instantiate a real job ORM because we need to create a job to satisfy // a check in pipeline.CreateRun jobORM := job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, cfg.Database()) @@ -106,8 +105,7 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) { var roundID uint32 = 1 jb := makeJob(t) - err = jobORM.CreateJob(jb) - require.NoError(t, err) + require.NoError(t, jobORM.CreateJob(jb)) for expectedCount := uint64(1); expectedCount < 4; expectedCount++ { f := time.Now() diff --git a/core/services/functions/listener_test.go b/core/services/functions/listener_test.go index 0c74b0563f4..a06fcf3e3b2 100644 --- a/core/services/functions/listener_test.go +++ b/core/services/functions/listener_test.go @@ -90,8 +90,7 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe db := pgtest.NewSqlxDB(t) kst := cltest.NewKeyStore(t, db, cfg.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, KeyStore: kst.Eth(), LogBroadcaster: broadcaster, MailMon: mailMon}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) chain := legacyChains.Slice()[0] lggr := logger.TestLogger(t) @@ -127,8 +126,7 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe decryptor := threshold_mocks.NewDecryptor(t) var pluginConfig config.PluginConfig - err = json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(jsonConfig.Bytes(), &pluginConfig)) contractAddress := "0xa" diff --git a/core/services/job/helpers_test.go b/core/services/job/helpers_test.go index 106ba8d27c7..21f3a8daa99 100644 --- a/core/services/job/helpers_test.go +++ b/core/services/job/helpers_test.go @@ -220,9 +220,8 @@ func makeMinimalHTTPOracleSpec(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralC s := fmt.Sprintf(minimalNonBootstrapTemplate, contractAddress, transmitterAddress, keyBundle, fetchUrl, timeout) keyStore := cltest.NewKeyStore(t, db, pgtest.NewQConfig(true)) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: evmtest.NewEthClientMockWithDefaultChain(t), GeneralConfig: cfg, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) - _, err = ocr.ValidatedOracleSpecToml(legacyChains, s) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + _, err := ocr.ValidatedOracleSpecToml(legacyChains, s) require.NoError(t, err) err = toml.Unmarshal([]byte(s), &os) require.NoError(t, err) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index de2ee44c2ce..1f5dba452fe 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -83,8 +83,7 @@ func TestORM(t *testing.T) { bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: ethKeyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) borm := bridges.NewORM(db, logger.TestLogger(t), config.Database()) @@ -317,8 +316,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) scopedConfig := evmtest.NewChainScopedConfig(t, config) korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database()) @@ -418,8 +416,7 @@ func TestORM_CreateJob_VRFV2(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) @@ -502,8 +499,7 @@ func TestORM_CreateJob_VRFV2Plus(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) fromAddresses := []string{cltest.NewEIP55Address().String(), cltest.NewEIP55Address().String()} @@ -588,8 +584,7 @@ func TestORM_CreateJob_OCRBootstrap(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := ocrbootstrap.ValidatedBootstrapSpecToml(testspecs.OCRBootstrapSpec) @@ -629,8 +624,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { bridgesORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) defaultChainID := config.DefaultChainID() @@ -764,8 +758,7 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) { bridgesORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) @@ -829,8 +822,7 @@ func TestORM_CreateJob_OCR2_Sending_Keys_Transmitter_Keys_Validations(t *testing relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) require.True(t, relayExtenders.Len() > 0) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := ocr2validate.ValidatedOracleSpecToml(config.OCR2(), config.Insecure(), testspecs.OCR2EVMSpecMinimal) @@ -942,8 +934,7 @@ func Test_FindJobs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) @@ -1024,8 +1015,7 @@ func Test_FindJob(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) @@ -1242,8 +1232,7 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) @@ -1284,9 +1273,8 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) { }) }) relayExtenders2 := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: newCfg, KeyStore: keyStore.Eth()}) - legacyChains2, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders2) + legacyChains2 := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders2) - require.NoError(t, err) orm2 := NewTestORM(t, db, legacyChains2, pipelineORM, bridgesORM, keyStore, config.Database()) jbs, err := orm2.FindJobsByPipelineSpecIDs([]int32{jb.PipelineSpecID}) @@ -1307,8 +1295,7 @@ func Test_FindPipelineRuns(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) @@ -1369,8 +1356,7 @@ func Test_PipelineRunsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) @@ -1431,8 +1417,7 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) @@ -1540,8 +1525,7 @@ func Test_FindPipelineRunsByIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) @@ -1599,8 +1583,7 @@ func Test_FindPipelineRunByID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) @@ -1645,8 +1628,7 @@ func Test_FindJobWithoutSpecErrors(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) @@ -1685,8 +1667,7 @@ func Test_FindSpecErrorsByJobIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) @@ -1722,8 +1703,7 @@ func Test_CountPipelineRunsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) diff --git a/core/services/job/job_pipeline_orm_integration_test.go b/core/services/job/job_pipeline_orm_integration_test.go index ff1cab4f3c6..a5d3ee984da 100644 --- a/core/services/job/job_pipeline_orm_integration_test.go +++ b/core/services/job/job_pipeline_orm_integration_test.go @@ -152,8 +152,7 @@ func TestPipelineORM_Integration(t *testing.T) { orm := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db, logger.TestLogger(t), cfg.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{Client: evmtest.NewEthClientMockWithDefaultChain(t), DB: db, GeneralConfig: config, KeyStore: ethKeyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) runner := pipeline.NewRunner(orm, btORM, config.JobPipeline(), cfg.WebServer(), legacyChains, nil, nil, lggr, nil, nil) jobORM := NewTestORM(t, db, legacyChains, orm, btORM, keyStore, cfg.Database()) @@ -161,13 +160,11 @@ func TestPipelineORM_Integration(t *testing.T) { dbSpec := makeVoterTurnoutOCRJobSpec(t, transmitterAddress, bridge.Name.String(), bridge2.Name.String()) // Need a job in order to create a run - err = jobORM.CreateJob(dbSpec) - require.NoError(t, err) + require.NoError(t, jobORM.CreateJob(dbSpec)) var pipelineSpecs []pipeline.Spec sql := `SELECT * FROM pipeline_specs;` - err = db.Select(&pipelineSpecs, sql) - require.NoError(t, err) + require.NoError(t, db.Select(&pipelineSpecs, sql)) require.Len(t, pipelineSpecs, 1) require.Equal(t, dbSpec.PipelineSpecID, pipelineSpecs[0].ID) pipelineSpecID := pipelineSpecs[0].ID diff --git a/core/services/job/runner_integration_test.go b/core/services/job/runner_integration_test.go index 8418ae999bb..72a20a476e3 100644 --- a/core/services/job/runner_integration_test.go +++ b/core/services/job/runner_integration_test.go @@ -53,19 +53,19 @@ var monitoringEndpoint = telemetry.MonitoringEndpointGenerator(&telemetry.NoopAg func TestRunner(t *testing.T) { db := pgtest.NewSqlxDB(t) keyStore := cltest.NewKeyStore(t, db, pgtest.NewQConfig(true)) - kb, err := keyStore.OCR().Create() - require.NoError(t, err) + ethKeyStore := keyStore.Eth() _, transmitterAddress := cltest.MustInsertRandomKey(t, ethKeyStore, 0) require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey)) config := configtest2.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - t := true - c.P2P.V1.Enabled = &t + c.P2P.V1.Enabled = ptr(true) c.P2P.V1.DefaultBootstrapPeers = &[]string{ "/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju", "/dns4/chain.link/tcp/1235/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju", } + kb, err := keyStore.OCR().Create() + require.NoError(t, err) kbid := models.MustSha256HashFromHex(kb.ID()) c.OCR.KeyBundleID = &kbid taddress := ethkey.EIP55AddressFromAddress(transmitterAddress) @@ -82,8 +82,7 @@ func TestRunner(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) c := clhttptest.NewTestLocalOnlyHTTPClient() runner := pipeline.NewRunner(pipelineORM, btORM, config.JobPipeline(), config.WebServer(), legacyChains, nil, nil, logger.TestLogger(t), c, c) @@ -119,8 +118,7 @@ func TestRunner(t *testing.T) { // Need a job in order to create a run jb := MakeVoterTurnoutOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, bridgeVT.Name.String(), bridgeER.Name.String()) - err = jobORM.CreateJob(jb) - require.NoError(t, err) + require.NoError(t, jobORM.CreateJob(jb)) require.NotNil(t, jb.PipelineSpec) m, err := bridges.MarshalBridgeMetaData(big.NewInt(10), big.NewInt(100)) @@ -175,8 +173,7 @@ func TestRunner(t *testing.T) { ds1 [type=bridge name="%s"]; """ `, bridge.Name.String())) - err = jobORM.CreateJob(jb) - require.NoError(t, err) + require.NoError(t, jobORM.CreateJob(jb)) // Should not be able to delete a bridge in use. jids, err := jobORM.FindJobIDsWithBridge(bridge.Name.String()) require.NoError(t, err) @@ -196,7 +193,7 @@ func TestRunner(t *testing.T) { // Reference a different one legacyChains := cltest.NewLegacyChainsWithMockChain(t, nil, config) - jb, err2 := ocr.ValidatedOracleSpecToml(legacyChains, fmt.Sprintf(` + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, fmt.Sprintf(` type = "offchainreporting" schemaVersion = 1 evmChainID = 0 @@ -219,7 +216,7 @@ func TestRunner(t *testing.T) { answer1 [type=median index=0]; """ `, placeHolderAddress.String())) - require.NoError(t, err2) + require.NoError(t, err) // Should error creating it err = jobORM.CreateJob(&jb) require.Error(t, err) @@ -689,7 +686,7 @@ ds1 -> ds1_parse; serv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { time.Sleep(1 * time.Millisecond) res.WriteHeader(http.StatusOK) - _, err = res.Write([]byte(`{"USD":10.1}`)) + _, err := res.Write([]byte(`{"USD":10.1}`)) require.NoError(t, err) })) defer serv.Close() @@ -767,8 +764,7 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) { app := cltest.NewApplicationWithConfig(t, cfg, ethClient, cltest.UseRealExternalInitiatorManager) keyStore := cltest.NewKeyStore(t, app.GetSqlxDB(), pgtest.NewQConfig(true)) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) require.NoError(t, app.Start(testutils.Context(t))) var ( @@ -950,8 +946,7 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) { app := cltest.NewApplicationWithConfig(t, cfg, ethClient, cltest.UseRealExternalInitiatorManager) keyStore := cltest.NewKeyStore(t, app.GetSqlxDB(), pgtest.NewQConfig(true)) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) require.NoError(t, app.Start(testutils.Context(t))) diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index de6ca541e59..f35aa50ba4d 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -94,8 +94,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { Return(nil).Maybe() relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) t.Run("should respect its dependents", func(t *testing.T) { lggr := logger.TestLogger(t) orm := NewTestORM(t, db, legacyChains, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) @@ -280,8 +279,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { lggr := logger.TestLogger(t) relayExtenders := evmtest.NewChainRelayExtenders(t, testopts) assert.Equal(t, relayExtenders.Len(), 1) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) chain := evmtest.MustGetDefaultChain(t, legacyChains) evmRelayer := evmrelayer.NewRelayer(testopts.DB, chain, testopts.GeneralConfig.Database(), lggr, keyStore, pg.NewNullEventBroadcaster()) @@ -306,7 +304,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { jobOCR2VRF.Type: delegateOCR2, }, db, lggr, nil) - err = spawner.CreateJob(jobOCR2VRF) + err := spawner.CreateJob(jobOCR2VRF) require.NoError(t, err) jobSpecID := jobOCR2VRF.ID delegateOCR2.jobID = jobOCR2VRF.ID diff --git a/core/services/keeper/registry_synchronizer_helper_test.go b/core/services/keeper/registry_synchronizer_helper_test.go index c3fadc8bcf4..6b9bb815a89 100644 --- a/core/services/keeper/registry_synchronizer_helper_test.go +++ b/core/services/keeper/registry_synchronizer_helper_test.go @@ -44,8 +44,7 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) ( lbMock.On("AddDependents", 1).Maybe() j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, LogBroadcaster: lbMock, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) ch := evmtest.MustGetDefaultChain(t, legacyChains) jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil) contractAddress := j.KeeperSpec.ContractAddress.Address() diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index 0f15f3949ba..c971152df3a 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -76,8 +76,7 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Maybe().Return(&evmtypes.Head{Number: 1, Hash: utils.NewHash()}, nil) txm := txmmocks.NewMockEvmTxManager(t) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{TxManager: txm, DB: db, Client: ethClient, KeyStore: keyStore.Eth(), GeneralConfig: cfg, GasEstimator: estimator}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil) ch := evmtest.MustGetDefaultChain(t, legacyChains) orm := keeper.NewORM(db, logger.TestLogger(t), ch.Config().Database()) @@ -85,9 +84,8 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain lggr := logger.TestLogger(t) executer := keeper.NewUpkeepExecuter(job, orm, jpv2.Pr, ethClient, ch.HeadBroadcaster(), ch.GasEstimator(), lggr, ch.Config().Keeper(), job.KeeperSpec.FromAddress.Address()) upkeep := cltest.MustInsertUpkeepForRegistry(t, db, ch.Config().Database(), registry) - err = executer.Start(testutils.Context(t)) + require.NoError(t, executer.Start(testutils.Context(t))) t.Cleanup(func() { executer.Close() }) - require.NoError(t, err) return db, cfg, ethClient, executer, registry, upkeep, job, jpv2, txm, keyStore, ch, orm } diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 9c1faca0c30..2a8fea38efe 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -371,7 +371,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC if err != nil { return nil, err } - if err := libocr2.SanityCheckLocalConfig(lc); err != nil { + if err = libocr2.SanityCheckLocalConfig(lc); err != nil { return nil, err } lggr.Infow("OCR2 job using local config", diff --git a/core/services/ocr2/delegate_test.go b/core/services/ocr2/delegate_test.go index bd442e67c00..e78af2e19b4 100644 --- a/core/services/ocr2/delegate_test.go +++ b/core/services/ocr2/delegate_test.go @@ -45,8 +45,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { txManager := txmmocks.NewMockEvmTxManager(t) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth(), TxManager: txManager}) require.True(t, relayExtenders.Len() > 0) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) type testCase struct { name string 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 47351327db3..bedfdc92d19 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 @@ -113,19 +113,19 @@ func CreateAndFundSubscriptions(t *testing.T, b *backends.SimulatedBackend, owne allowed, err := allowListContract.HasAccess(nilOpts, owner.From, []byte{}) require.NoError(t, err) if !allowed { - message, err := allowListContract.GetMessage(nilOpts, owner.From, owner.From) - require.NoError(t, err) - privateKey, err := crypto.HexToECDSA(allowListPrivateKey[2:]) - require.NoError(t, err) - flatSignature, err := crypto.Sign(message[:], privateKey) - require.NoError(t, err) + message, err2 := allowListContract.GetMessage(nilOpts, owner.From, owner.From) + require.NoError(t, err2) + privateKey, err2 := crypto.HexToECDSA(allowListPrivateKey[2:]) + require.NoError(t, err2) + flatSignature, err2 := crypto.Sign(message[:], privateKey) + require.NoError(t, err2) var r [32]byte copy(r[:], flatSignature[:32]) var s [32]byte copy(s[:], flatSignature[32:64]) v := flatSignature[65] - _, err = allowListContract.AcceptTermsOfService(owner, owner.From, owner.From, r, s, v) - require.NoError(t, err) + _, err2 = allowListContract.AcceptTermsOfService(owner, owner.From, owner.From, r, s, v) + require.NoError(t, err2) } _, err = routerContract.CreateSubscription(owner) diff --git a/core/services/pipeline/orm_test.go b/core/services/pipeline/orm_test.go index 0863226e647..4c03ce16ef8 100644 --- a/core/services/pipeline/orm_test.go +++ b/core/services/pipeline/orm_test.go @@ -522,8 +522,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) { bridgeORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jorm := job.NewORM(db, legacyChains, porm, bridgeORM, keyStore, lggr, config.Database()) defer func() { assert.NoError(t, jorm.Close()) }() @@ -548,7 +547,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) { MaxTaskDuration: models.Interval(1 * time.Minute), } - err = jorm.CreateJob(&keeperJob) + err := jorm.CreateJob(&keeperJob) require.NoError(t, err) require.Equal(t, job.Keeper, keeperJob.Type) @@ -625,8 +624,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) { bridgeORM := bridges.NewORM(db, lggr, config.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jorm := job.NewORM(db, legacyChains, porm, bridgeORM, keyStore, lggr, config.Database()) defer func() { assert.NoError(t, jorm.Close()) }() @@ -650,7 +648,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) { MaxTaskDuration: models.Interval(1 * time.Minute), } - err = jorm.CreateJob(&drJob) + err := jorm.CreateJob(&drJob) require.NoError(t, err) require.Equal(t, job.DirectRequest, drJob.Type) diff --git a/core/services/pipeline/runner_test.go b/core/services/pipeline/runner_test.go index 1b13289289e..2554315a46c 100644 --- a/core/services/pipeline/runner_test.go +++ b/core/services/pipeline/runner_test.go @@ -44,8 +44,7 @@ func newRunner(t testing.TB, db *sqlx.DB, bridgeORM bridges.ORM, cfg chainlink.G lggr := logger.TestLogger(t) ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth() relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := mocks.NewORM(t) q := pg.NewQ(db, lggr, cfg.Database()) @@ -482,8 +481,7 @@ func Test_PipelineRunner_HandleFaultsPersistRun(t *testing.T) { cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth() relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) lggr := logger.TestLogger(t) r := pipeline.NewRunner(orm, btORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ethKeyStore, nil, lggr, nil, nil) diff --git a/core/services/pipeline/task.eth_call_test.go b/core/services/pipeline/task.eth_call_test.go index 8d7f128a0d4..b8896488e2d 100644 --- a/core/services/pipeline/task.eth_call_test.go +++ b/core/services/pipeline/task.eth_call_test.go @@ -258,11 +258,9 @@ func TestETHCallTask(t *testing.T) { db := pgtest.NewSqlxDB(t) var legacyChains evm.LegacyChainContainer - var err error if test.expectedErrorCause != nil || test.expectedErrorContains != "" { exts := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, TxManager: txManager, KeyStore: keyStore}) - legacyChains, err = evmrelay.NewLegacyChainsFromRelayerExtenders(exts) - require.NoError(t, err) + legacyChains = evmrelay.NewLegacyChainsFromRelayerExtenders(exts) } else { legacyChains = cltest.NewLegacyChainsWithMockChain(t, ethClient, cfg) } diff --git a/core/services/pipeline/task.eth_tx_test.go b/core/services/pipeline/task.eth_tx_test.go index 83f855c9982..d465c16f8fd 100644 --- a/core/services/pipeline/task.eth_tx_test.go +++ b/core/services/pipeline/task.eth_tx_test.go @@ -575,8 +575,7 @@ func TestETHTxTask(t *testing.T) { relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, TxManager: txManager, KeyStore: keyStore}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) test.setupClientMocks(keyStore, txManager) task.HelperSetDependencies(legacyChains, keyStore, test.specGasLimit, pipeline.DirectRequestJobType) diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index 499494c2211..5b3a3535c51 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -42,8 +42,7 @@ type ChainRelayerExtenders struct { var _ EVMChainRelayerExtenderSlicer = &ChainRelayerExtenders{} -func NewLegacyChainsFromRelayerExtenders(exts EVMChainRelayerExtenderSlicer) (*evmchain.LegacyChains, error) { - +func NewLegacyChainsFromRelayerExtenders(exts EVMChainRelayerExtenderSlicer) *evmchain.LegacyChains { m := make(map[string]evmchain.Chain) var dflt evmchain.Chain for _, r := range exts.Slice() { @@ -52,14 +51,11 @@ func NewLegacyChainsFromRelayerExtenders(exts EVMChainRelayerExtenderSlicer) (*e dflt = r.Chain() } } - l, err := evmchain.NewLegacyChains(exts.AppConfig(), m) - if err != nil { - return nil, err - } + l := evmchain.NewLegacyChains(m, exts.AppConfig().EVMConfigs()) if dflt != nil { l.SetDefault(dflt) } - return l, nil + return l } func newChainRelayerExtsFromSlice(exts []*ChainRelayerExt, appConfig evm.AppConfig) *ChainRelayerExtenders { diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go index dba1d818ed4..b26e5511c16 100644 --- a/core/services/vrf/delegate_test.go +++ b/core/services/vrf/delegate_test.go @@ -79,8 +79,7 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv txm := txmmocks.NewMockEvmTxManager(t) ks := keystore.New(db, utils.FastScryptParams, lggr, cfg.Database()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{LogBroadcaster: lb, KeyStore: ks.Eth(), Client: ec, DB: db, GeneralConfig: cfg, TxManager: txm}) - legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - require.NoError(t, err) + legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) jrm := job.NewORM(db, legacyChains, prm, btORM, ks, lggr, cfg.Database()) t.Cleanup(func() { jrm.Close() }) pr := pipeline.NewRunner(prm, btORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ks.Eth(), ks.VRF(), lggr, nil, nil) diff --git a/core/web/resolver/eth_key_test.go b/core/web/resolver/eth_key_test.go index 557ceb7b7ce..26e061b164f 100644 --- a/core/web/resolver/eth_key_test.go +++ b/core/web/resolver/eth_key_test.go @@ -8,7 +8,6 @@ import ( gqlerrors "github.com/graph-gophers/graphql-go/errors" "github.com/pkg/errors" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" @@ -91,8 +90,7 @@ func TestResolver_ETHKeys(t *testing.T) { cfg := configtest.NewGeneralConfig(t, nil) m := map[string]evm.Chain{states[0].EVMChainID.String(): f.Mocks.chain} - legacyEVMChains, err := evm.NewLegacyChains(cfg, m) - require.NoError(t, err) + legacyEVMChains := evm.NewLegacyChains(m, cfg.EVMConfigs()) f.Mocks.ethKs.On("GetStatesForKeys", keys).Return(states, nil) f.Mocks.ethKs.On("Get", keys[0].Address.Hex()).Return(keys[0], nil) From 3bf936a88c277191227e9175c756305e84b16bd2 Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Wed, 6 Sep 2023 15:16:56 +0300 Subject: [PATCH 22/88] HasFilter to check whether some filter was loaded by the poller (#10469) Co-authored-by: Domino Valdano <2644901+reductionista@users.noreply.github.com> --- core/chains/evm/logpoller/disabled.go | 2 ++ core/chains/evm/logpoller/log_poller.go | 10 ++++++++++ core/chains/evm/logpoller/log_poller_test.go | 7 +++++++ core/chains/evm/logpoller/mocks/log_poller.go | 14 ++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/core/chains/evm/logpoller/disabled.go b/core/chains/evm/logpoller/disabled.go index 80a5550b0a5..602bd5cec27 100644 --- a/core/chains/evm/logpoller/disabled.go +++ b/core/chains/evm/logpoller/disabled.go @@ -37,6 +37,8 @@ func (disabled) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { return E func (disabled) UnregisterFilter(name string, qopts ...pg.QOpt) error { return ErrDisabled } +func (disabled) HasFilter(name string) bool { return false } + func (disabled) LatestBlock(qopts ...pg.QOpt) (int64, error) { return -1, ErrDisabled } func (disabled) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 60767970289..69a3143859f 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -36,6 +36,7 @@ type LogPoller interface { ReplayAsync(fromBlock int64) RegisterFilter(filter Filter, qopts ...pg.QOpt) error UnregisterFilter(name string, qopts ...pg.QOpt) error + HasFilter(name string) bool LatestBlock(qopts ...pg.QOpt) (int64, error) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) @@ -258,6 +259,15 @@ func (lp *logPoller) UnregisterFilter(name string, qopts ...pg.QOpt) error { return nil } +// HasFilter returns true if the log poller has an active filter with the given name. +func (lp *logPoller) HasFilter(name string) bool { + lp.filterMu.RLock() + defer lp.filterMu.RUnlock() + + _, ok := lp.filters[name] + return ok +} + func (lp *logPoller) Filter(from, to *big.Int, bh *common.Hash) ethereum.FilterQuery { lp.filterMu.Lock() defer lp.filterMu.Unlock() diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 17df4dc6291..c434d18c999 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -760,6 +760,13 @@ func TestLogPoller_LoadFilters(t *testing.T) { require.True(t, ok) assert.True(t, filter.Contains(&filter3)) assert.True(t, filter3.Contains(&filter)) + + t.Run("HasFilter", func(t *testing.T) { + assert.True(t, th.LogPoller.HasFilter("first Filter")) + assert.True(t, th.LogPoller.HasFilter("second Filter")) + assert.True(t, th.LogPoller.HasFilter("third Filter")) + assert.False(t, th.LogPoller.HasFilter("fourth Filter")) + }) } func TestLogPoller_GetBlocks_Range(t *testing.T) { diff --git a/core/chains/evm/logpoller/mocks/log_poller.go b/core/chains/evm/logpoller/mocks/log_poller.go index 9e96947abc7..3c30454a4f7 100644 --- a/core/chains/evm/logpoller/mocks/log_poller.go +++ b/core/chains/evm/logpoller/mocks/log_poller.go @@ -68,6 +68,20 @@ func (_m *LogPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts return r0, r1 } +// HasFilter provides a mock function with given fields: name +func (_m *LogPoller) HasFilter(name string) bool { + ret := _m.Called(name) + + var r0 bool + if rf, ok := ret.Get(0).(func(string) bool); ok { + r0 = rf(name) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + // HealthReport provides a mock function with given fields: func (_m *LogPoller) HealthReport() map[string]error { ret := _m.Called() From 94d05b789a97ba71b233f1cce9ef020f50720c4b Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:55:25 +0100 Subject: [PATCH 23/88] Allow burst in log recoverer when it lags (#10479) * Allow burst in log recoverer when it lags * add test * more tests * update * improve test * update test messages --- .../ocr2keeper/evm21/logprovider/recoverer.go | 9 +- .../evm21/logprovider/recoverer_test.go | 86 ++++++++++++++++++- 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go index 5acfa1ee0c8..7a7dbbe46be 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -29,7 +29,8 @@ var ( GCInterval = RecoveryCacheTTL recoveryBatchSize = 10 - recoveryLogsBuffer = int64(50) + recoveryLogsBuffer = int64(200) + recoveryLogsBurst = int64(500) ) type LogRecoverer interface { @@ -318,6 +319,12 @@ func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startB start = startBlock } end := start + recoveryLogsBuffer + if offsetBlock-end > 100*recoveryLogsBuffer { + // If recoverer is lagging by a lot (more than 100x recoveryLogsBuffer), allow + // a range of recoveryLogsBurst + // Exploratory: Store lastRePollBlock in DB to prevent bursts during restarts + end = start + recoveryLogsBurst + } if end > offsetBlock { end = offsetBlock } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go index 7f01434c2b9..0a993831b7b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go @@ -226,6 +226,7 @@ func TestLogRecoverer_Recover(t *testing.T) { logsErr error recoverErr error proposalsWorkIDs []string + lastRePollBlocks []int64 }{ { "no filters", @@ -239,6 +240,7 @@ func TestLogRecoverer_Recover(t *testing.T) { nil, nil, []string{}, + []int64{}, }, { "latest block error", @@ -252,6 +254,7 @@ func TestLogRecoverer_Recover(t *testing.T) { nil, fmt.Errorf("test error"), []string{}, + []int64{}, }, { "states error", @@ -280,6 +283,7 @@ func TestLogRecoverer_Recover(t *testing.T) { nil, nil, []string{}, + []int64{0}, }, { "get logs error", @@ -301,11 +305,12 @@ func TestLogRecoverer_Recover(t *testing.T) { fmt.Errorf("test error"), nil, []string{}, + []int64{0}, }, { "happy flow", 100, - 200, + 500, nil, []upkeepFilter{ { @@ -321,7 +326,15 @@ func TestLogRecoverer_Recover(t *testing.T) { topics: []common.Hash{ common.HexToHash("0x2"), }, - configUpdateBlock: 150, // should be filtered out + configUpdateBlock: 450, // should be filtered out + }, + { + upkeepID: big.NewInt(3), + addr: common.HexToAddress("0x2").Bytes(), + topics: []common.Hash{ + common.HexToHash("0x2"), + }, + lastRePollBlock: 450, // should be filtered out, as its higher than latest-lookback }, }, []ocr2keepers.UpkeepState{ocr2keepers.UnknownState}, @@ -337,6 +350,68 @@ func TestLogRecoverer_Recover(t *testing.T) { nil, nil, []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"}, + []int64{200, 0, 450}, + }, + { + "lastRePollBlock updated with burst when lagging behind", + 100, + 50000, + nil, + []upkeepFilter{ + { + upkeepID: big.NewInt(1), + addr: common.HexToAddress("0x1").Bytes(), + topics: []common.Hash{ + common.HexToHash("0x1"), + }, + lastRePollBlock: 100, // Should be updated with burst + }, + }, + []ocr2keepers.UpkeepState{ocr2keepers.UnknownState}, + nil, + []logpoller.Log{ + { + BlockNumber: 2, + TxHash: common.HexToHash("0x111"), + LogIndex: 1, + BlockHash: common.HexToHash("0x2"), + }, + }, + nil, + nil, + []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"}, + []int64{600}, + }, + { + "recovery starts at configUpdateBlock if higher than lastRePollBlock", + 100, + 5000, + nil, + []upkeepFilter{ + { + upkeepID: big.NewInt(1), + addr: common.HexToAddress("0x1").Bytes(), + topics: []common.Hash{ + common.HexToHash("0x1"), + }, + lastRePollBlock: 100, + configUpdateBlock: 500, + }, + }, + []ocr2keepers.UpkeepState{ocr2keepers.UnknownState}, + nil, + []logpoller.Log{ + { + BlockNumber: 2, + TxHash: common.HexToHash("0x111"), + LogIndex: 1, + BlockHash: common.HexToHash("0x2"), + }, + }, + nil, + nil, + []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"}, + []int64{700}, // should be configUpdateBlock + recoveryLogsBuffer }, } @@ -356,6 +431,13 @@ func TestLogRecoverer_Recover(t *testing.T) { return } require.NoError(t, err) + for i, active := range tc.active { + filters := filterStore.GetFilters(func(f upkeepFilter) bool { + return f.upkeepID.String() == active.upkeepID.String() + }) + require.Equal(t, 1, len(filters)) + require.Equal(t, tc.lastRePollBlocks[i], filters[0].lastRePollBlock) + } proposals, err := recoverer.GetRecoveryProposals(ctx) require.NoError(t, err) From e43bdf46327f6d76c7d87602a0793cc94f211d2b Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Wed, 6 Sep 2023 16:47:35 +0300 Subject: [PATCH 24/88] Update ocr2keepers v0.7.20 (#10486) * update ocr2keepers * go mod tidy --- 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 d9f2cc7c9c3..4fb609f851a 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,7 +19,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.19 + github.com/smartcontractkit/ocr2keepers v0.7.20 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/spf13/cobra v1.6.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 26a31aafde8..fbd5868834b 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1387,8 +1387,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.19 h1:w9CMs1V8pmxdRX6ME98goIRPMuN9DOkfMmZHeDPDQXY= -github.com/smartcontractkit/ocr2keepers v0.7.19/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.20 h1:1FOeJ0p4mWHqJiX01v/J2S1C1LhU8iqJM1hDcD38aZU= +github.com/smartcontractkit/ocr2keepers v0.7.20/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/go.mod b/go.mod index 7d5b1757992..2f7c8aca670 100644 --- a/go.mod +++ b/go.mod @@ -70,7 +70,7 @@ require ( github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.19 + github.com/smartcontractkit/ocr2keepers v0.7.20 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e diff --git a/go.sum b/go.sum index a0243097bc0..ea1158e13df 100644 --- a/go.sum +++ b/go.sum @@ -1387,8 +1387,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.19 h1:w9CMs1V8pmxdRX6ME98goIRPMuN9DOkfMmZHeDPDQXY= -github.com/smartcontractkit/ocr2keepers v0.7.19/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.20 h1:1FOeJ0p4mWHqJiX01v/J2S1C1LhU8iqJM1hDcD38aZU= +github.com/smartcontractkit/ocr2keepers v0.7.20/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d3a8b5a19cb..47e74c46dd3 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -23,7 +23,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230829222228-4afd1b3d385c github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.19 + github.com/smartcontractkit/ocr2keepers v0.7.20 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230829114801-14bf715f805e github.com/smartcontractkit/wasp v0.3.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 5e77b2bddcc..8c5bb51f27c 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2264,8 +2264,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.19 h1:w9CMs1V8pmxdRX6ME98goIRPMuN9DOkfMmZHeDPDQXY= -github.com/smartcontractkit/ocr2keepers v0.7.19/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.20 h1:1FOeJ0p4mWHqJiX01v/J2S1C1LhU8iqJM1hDcD38aZU= +github.com/smartcontractkit/ocr2keepers v0.7.20/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= From 3c9cf014f5449a9403408112cc11e8360687c68e Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:58:05 +0100 Subject: [PATCH 25/88] Remove explicit checkblock too old check and rely on rpc, add a check for checkBlock too new (#10484) * Remove explicit checkblock too old check and rely on rpc * update * update * fix test * fix * update test --- .../ocr2keeper/evm21/encoding/interface.go | 1 + .../evm21/registry_check_pipeline.go | 30 ++++++++++--------- .../evm21/registry_check_pipeline_test.go | 13 ++++---- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go index 4b559e9104e..e0c31f2beea 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go @@ -41,6 +41,7 @@ const ( MercuryUnmarshalError PipelineExecutionState = 6 InvalidMercuryRequest PipelineExecutionState = 7 InvalidMercuryResponse PipelineExecutionState = 8 // this will only happen if Mercury server sends bad responses + CheckBlockTooNew PipelineExecutionState = 9 ) type UpkeepInfo = iregistry21.KeeperRegistryBase21UpkeepInfo diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go index 5cf2dfa0981..bf57ce496a3 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go @@ -15,12 +15,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" ) -const ( - // validCheckBlockRange decides the max distance between the check block and the current block - // allowed in checkPipeline - validCheckBlockRange = 128 -) - type checkResult struct { cr []ocr2keepers.CheckResult err error @@ -99,11 +93,11 @@ func (r *EvmRegistry) getBlockHash(blockNumber *big.Int) (common.Hash, error) { // verifyCheckBlock checks that the check block and hash are valid, returns the pipeline execution state and retryable func (r *EvmRegistry) verifyCheckBlock(ctx context.Context, checkBlock, upkeepId *big.Int, checkHash common.Hash) (state encoding.PipelineExecutionState, retryable bool) { - // verify check block number is not too old + // verify check block number is not in future (can happen when this node is lagging the other members in DON) latestBlock := r.bs.latestBlock.Load() - if int64(latestBlock.Number)-checkBlock.Int64() > validCheckBlockRange { - r.lggr.Warnf("latest block is %d, check block number %s is too old for upkeepId %s", r.bs.latestBlock.Load(), checkBlock, upkeepId) - return encoding.CheckBlockTooOld, false + if checkBlock.Int64() > int64(latestBlock.Number) { + r.lggr.Warnf("latest block is %d, check block number %s is in future for upkeepId %s", r.bs.latestBlock.Load(), checkBlock, upkeepId) + return encoding.CheckBlockTooNew, true // retryable since the block can be found in future } var h string @@ -240,10 +234,18 @@ func (r *EvmRegistry) checkUpkeeps(ctx context.Context, payloads []ocr2keepers.U for i, req := range checkReqs { index := indices[i] if req.Error != nil { - // individual upkeep failed in a batch call, retryable - r.lggr.Warnf("error encountered in check result for upkeepId %s: %s", results[index].UpkeepID.String(), req.Error) - results[index].Retryable = true - results[index].PipelineExecutionState = uint8(encoding.RpcFlakyFailure) + // primitive way of checking errors + if strings.Contains(req.Error.Error(), "header not found") { + // Check block not found in RPC, non-retryable error + r.lggr.Warnf("header not found error encountered in check result for upkeepId %s: %s", results[index].UpkeepID.String(), req.Error) + results[index].Retryable = false + results[index].PipelineExecutionState = uint8(encoding.CheckBlockTooOld) + } else { + // individual upkeep failed in a batch call, likely a flay RPC error, consider retryable + r.lggr.Warnf("rpc error encountered in check result for upkeepId %s: %s", results[index].UpkeepID.String(), req.Error) + results[index].Retryable = true + results[index].PipelineExecutionState = uint8(encoding.RpcFlakyFailure) + } } else { var err error results[index], err = r.packer.UnpackCheckResult(payloads[index], *checkResults[i]) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go index 69364396e8b..0cd1a11fcce 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go @@ -86,9 +86,9 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { makeEthCall bool }{ { - name: "check block number too told", + name: "check block number too new", checkBlock: big.NewInt(500), - latestBlock: ocr2keepers.BlockKey{Number: 800}, + latestBlock: ocr2keepers.BlockKey{Number: 400}, upkeepId: big.NewInt(12345), checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), payload: ocr2keepers.UpkeepPayload{ @@ -96,7 +96,8 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")), WorkID: "work", }, - state: encoding.CheckBlockTooOld, + state: encoding.CheckBlockTooNew, + retryable: true, }, { name: "for an invalid check block number, if hash does not match the check hash, return CheckBlockInvalid", @@ -368,7 +369,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { BlockNumber: 550, } - trigger0 := ocr2keepers.NewTrigger(150, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0")) + trigger0 := ocr2keepers.NewTrigger(590, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0")) trigger1 := ocr2keepers.NewLogTrigger(560, common.HexToHash("0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857"), extension1) trigger2 := ocr2keepers.NewLogTrigger(570, common.HexToHash("0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc"), extension2) @@ -412,8 +413,8 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { latestBlock: ocr2keepers.BlockKey{Number: 580}, results: []ocr2keepers.CheckResult{ { - PipelineExecutionState: uint8(encoding.CheckBlockTooOld), - Retryable: false, + PipelineExecutionState: uint8(encoding.CheckBlockTooNew), + Retryable: true, Eligible: false, IneligibilityReason: 0, UpkeepID: uid0, From 37f38803fb4d39a63284401ed6b60a89eb66b572 Mon Sep 17 00:00:00 2001 From: Sergei Drugalev Date: Wed, 6 Sep 2023 16:27:53 +0200 Subject: [PATCH 26/88] Using minmax heap for Mercury transmission queue to evict oldest transmission correctly (#10427) * Using minmax heap for Mercury transmission queue to evict oldest transmission correctly * go mod tidy * go mod tidy everywhere --- core/scripts/go.mod | 1 + core/scripts/go.sum | 2 ++ core/services/relay/evm/mercury/queue.go | 29 ++++++------------- core/services/relay/evm/mercury/queue_test.go | 14 ++++----- go.mod | 1 + go.sum | 2 ++ integration-tests/go.mod | 1 + integration-tests/go.sum | 2 ++ 8 files changed, 23 insertions(+), 29 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 4fb609f851a..738d21ddb73 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -98,6 +98,7 @@ require ( 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/esote/minmaxheap v1.0.0 // indirect github.com/fatih/color v1.15.0 // indirect github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index fbd5868834b..9d919d1ac72 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -320,6 +320,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 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/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/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= diff --git a/core/services/relay/evm/mercury/queue.go b/core/services/relay/evm/mercury/queue.go index 743a6553dff..44042c57725 100644 --- a/core/services/relay/evm/mercury/queue.go +++ b/core/services/relay/evm/mercury/queue.go @@ -1,13 +1,13 @@ package mercury import ( - "container/heap" "context" "errors" "fmt" "sync" "time" + heap "github.com/esote/minmaxheap" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -59,11 +59,6 @@ type TransmitQueue struct { type Transmission struct { Req *pb.TransmitRequest // the payload to transmit ReportCtx ocrtypes.ReportContext // contains priority information (latest epoch/round wins) - - // The index is needed by update and is maintained by the heap.Interface - // methods - // It should NOT be set manually - index int // the index of the item in the heap } // maxlen controls how many items will be stored in the queue @@ -97,13 +92,13 @@ func (tq *TransmitQueue) Push(req *pb.TransmitRequest, reportCtx ocrtypes.Report if tq.maxlen != 0 && tq.pq.Len() == tq.maxlen { // evict oldest entry to make room tq.lggr.Criticalf("Transmit queue is full; dropping oldest transmission (reached max length of %d)", tq.maxlen) - removed := heap.Remove(tq.pq, tq.pq.Len()-1) + removed := heap.PopMax(tq.pq) if transmission, ok := removed.(*Transmission); ok { tq.asyncDeleter.AsyncDelete(transmission.Req) } } - heap.Push(tq.pq, &Transmission{req, reportCtx, -1}) + heap.Push(tq.pq, &Transmission{req, reportCtx}) tq.cond.Signal() return true @@ -231,6 +226,10 @@ func (pq priorityQueue) Less(i, j int) bool { pq[i].ReportCtx.ReportTimestamp.Round > pq[j].ReportCtx.ReportTimestamp.Round } +func (pq priorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] +} + func (pq *priorityQueue) Pop() any { n := len(*pq) if n == 0 { @@ -238,21 +237,11 @@ func (pq *priorityQueue) Pop() any { } old := *pq item := old[n-1] - old[n-1] = nil // avoid memory leak - item.index = -1 // for safety + old[n-1] = nil // avoid memory leak *pq = old[0 : n-1] return item } func (pq *priorityQueue) Push(x any) { - n := len(*pq) - item := x.(*Transmission) - item.index = n - *pq = append(*pq, item) -} - -func (pq priorityQueue) Swap(i, j int) { - pq[i], pq[j] = pq[j], pq[i] - pq[i].index = i - pq[j].index = j + *pq = append(*pq, x.(*Transmission)) } diff --git a/core/services/relay/evm/mercury/queue_test.go b/core/services/relay/evm/mercury/queue_test.go index 9fa2520147d..de2f64f9fe9 100644 --- a/core/services/relay/evm/mercury/queue_test.go +++ b/core/services/relay/evm/mercury/queue_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" @@ -81,7 +80,7 @@ func Test_Queue(t *testing.T) { }) t.Run("transmit queue is more than 50% full", func(t *testing.T) { - transmitQueue.Push(testTransmissions[2].tr, testTransmissions[0].ctx) + transmitQueue.Push(testTransmissions[2].tr, testTransmissions[2].ctx) report := transmitQueue.HealthReport() assert.Equal(t, report[transmitQueue.Name()].Error(), "transmit priority queue is greater than 50% full (4/7)") }) @@ -92,21 +91,18 @@ func Test_Queue(t *testing.T) { }) t.Run("transmit queue is full and evicts the oldest transmission", func(t *testing.T) { - // There is a bug with queue eviction where the evicted transmission is NOT the oldest. - // TODO: MERC-1049 Once this bug is fixed, replace the expectation with the one below. - // deleter.On("AsyncDelete", testTransmissions[0].tr).Once() - deleter.On("AsyncDelete", mock.Anything).Once() + deleter.On("AsyncDelete", testTransmissions[0].tr).Once() - // add 5 more transmissions to overflow the queue + // add 5 more transmissions to overflow the queue by 1 for i := 0; i < 5; i++ { transmitQueue.Push(testTransmissions[1].tr, testTransmissions[1].ctx) } + // expecting testTransmissions[0] to get evicted and not present in the queue anymore testutils.WaitForLogMessage(t, observedLogs, "Transmit queue is full; dropping oldest transmission (reached max length of 7)") for i := 0; i < 7; i++ { tr := transmitQueue.BlockingPop() - // TODO: Should be tr.Req instead of tr. - assert.NotEqual(t, tr, testTransmissions[0].tr) + assert.NotEqual(t, tr.Req, testTransmissions[0].tr) } }) diff --git a/go.mod b/go.mod index 2f7c8aca670..730a30daa16 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/cometbft/cometbft v0.37.2 github.com/cosmos/cosmos-sdk v0.47.4 github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e + github.com/esote/minmaxheap v1.0.0 github.com/ethereum/go-ethereum v1.12.0 github.com/fatih/color v1.15.0 github.com/fxamacker/cbor/v2 v2.4.0 diff --git a/go.sum b/go.sum index ea1158e13df..152a27cad3e 100644 --- a/go.sum +++ b/go.sum @@ -314,6 +314,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 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/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/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 47e74c46dd3..c7e8ec794a2 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -131,6 +131,7 @@ require ( 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.1 // indirect + github.com/esote/minmaxheap v1.0.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 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8c5bb51f27c..d43c4163142 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -896,6 +896,8 @@ github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= +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/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= From 1176a8cd6da53cad6b4f3bfeb2e42aa23b469deb Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Wed, 6 Sep 2023 17:40:16 +0300 Subject: [PATCH 27/88] Upkeep filters life cycle: avoid replying logs for existing filters (#10470) * filters life cycle: avoid replying logs for existing filters TODO: tests * fix test * use config update block if not too old * small fix + align tests and logs * added mocks for HasFilter --- .../evm21/logprovider/provider_life_cycle.go | 27 +++++++++---- .../logprovider/provider_life_cycle_test.go | 40 +++++++++++++++---- .../evm21/logprovider/provider_test.go | 1 + 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go index 8a21637241a..0e2c0068bab 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go @@ -83,11 +83,6 @@ func (p *logEventProvider) RegisterFilter(ctx context.Context, opts FilterOption p.lggr.Debugf("filter for upkeep with id %s already registered with the same config", upkeepID.String()) return nil } - // removing filter so we can recreate it with updated values - err := p.poller.UnregisterFilter(p.filterName(currentFilter.upkeepID)) - if err != nil { - return fmt.Errorf("failed to unregister upkeep filter %s for update: %w", upkeepID.String(), err) - } filter = *currentFilter } else { // new filter filter = upkeepFilter{ @@ -115,17 +110,35 @@ func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filt if err != nil { return fmt.Errorf("failed to get latest block while registering filter: %w", err) } + lggr := p.lggr.With("upkeepID", ufilter.upkeepID.String()) + logPollerHasFilter := p.poller.HasFilter(lpFilter.Name) + if logPollerHasFilter { + lggr.Debugw("Upserting upkeep filter") + // removing filter so we can recreate it with updated values + err := p.poller.UnregisterFilter(lpFilter.Name) + if err != nil { + return fmt.Errorf("failed to upsert (unregister) upkeep filter %s: %w", ufilter.upkeepID.String(), err) + } + } if err := p.poller.RegisterFilter(lpFilter); err != nil { return err } p.filterStore.AddActiveUpkeeps(ufilter) + if logPollerHasFilter { + // already registered, no need to backfill + return nil + } backfillBlock := latest - int64(LogBackfillBuffer) if backfillBlock < 1 { // New chain, backfill from start backfillBlock = 1 } - // TODO: Optimise to do backfill from ufilter.configUpdateBlock only for new filters - // if it is not too old + if int64(ufilter.configUpdateBlock) > backfillBlock { + // backfill from config update block in case it is not too old + backfillBlock = int64(ufilter.configUpdateBlock) + } + // NOTE: replys are planned to be done as part of RegisterFilter within logpoller + lggr.Debugw("Backfilling logs for new upkeep filter", "backfillBlock", backfillBlock) p.poller.ReplayAsync(backfillBlock) return nil diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go index c42e1c3bac3..e51871c4784 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go @@ -23,6 +23,8 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { errored bool upkeepID *big.Int upkeepCfg LogTriggerConfig + hasFilter bool + replyed bool cfgUpdateBlock uint64 mockPoller bool unregister bool @@ -35,6 +37,8 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), }, + false, + true, uint64(1), true, false, @@ -44,6 +48,8 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { true, big.NewInt(111), LogTriggerConfig{}, + false, + false, uint64(0), false, false, @@ -56,18 +62,22 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{}, 20)), Topic0: common.BytesToHash(common.LeftPadBytes([]byte{}, 32)), }, + false, + false, uint64(2), false, false, }, { - "existing config", + "existing config with old block", true, big.NewInt(111), LogTriggerConfig{ ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), }, + true, + false, uint64(0), true, false, @@ -80,23 +90,37 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), }, + true, + false, uint64(2), true, true, }, } - mp := new(mocks.LogPoller) - mp.On("RegisterFilter", mock.Anything).Return(nil) - mp.On("UnregisterFilter", mock.Anything).Return(nil) - mp.On("LatestBlock", mock.Anything).Return(int64(0), nil) - mp.On("ReplayAsync", mock.Anything).Return(nil) - p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200)) + p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200)) for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + + if tc.mockPoller { + lp := new(mocks.LogPoller) + lp.On("RegisterFilter", mock.Anything).Return(nil) + lp.On("UnregisterFilter", mock.Anything).Return(nil) + lp.On("LatestBlock", mock.Anything).Return(int64(0), nil) + lp.On("HasFilter", p.filterName(tc.upkeepID)).Return(tc.hasFilter).Times(1) + if tc.replyed { + lp.On("ReplayAsync", mock.Anything).Return(nil).Times(1) + } else { + lp.On("ReplayAsync", mock.Anything).Return(nil).Times(0) + } + p.lock.Lock() + p.poller = lp + p.lock.Unlock() + } + err := p.RegisterFilter(ctx, FilterOptions{ UpkeepID: tc.upkeepID, TriggerConfig: tc.upkeepCfg, @@ -120,6 +144,7 @@ func TestEventLogProvider_RefreshActiveUpkeeps(t *testing.T) { mp := new(mocks.LogPoller) mp.On("RegisterFilter", mock.Anything).Return(nil) mp.On("UnregisterFilter", mock.Anything).Return(nil) + mp.On("HasFilter", mock.Anything).Return(false) mp.On("LatestBlock", mock.Anything).Return(int64(0), nil) mp.On("ReplayAsync", mock.Anything).Return(nil) @@ -146,6 +171,7 @@ func TestEventLogProvider_RefreshActiveUpkeeps(t *testing.T) { newIds, err := p.RefreshActiveUpkeeps() require.NoError(t, err) require.Len(t, newIds, 0) + mp.On("HasFilter", p.filterName(core.GenUpkeepID(ocr2keepers.LogTrigger, "2222").BigInt())).Return(true) newIds, err = p.RefreshActiveUpkeeps( core.GenUpkeepID(ocr2keepers.LogTrigger, "2222").BigInt(), core.GenUpkeepID(ocr2keepers.LogTrigger, "1234").BigInt(), diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go index 159e229a2ff..47070d71aed 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go @@ -246,6 +246,7 @@ func TestLogEventProvider_ReadLogs(t *testing.T) { mp.On("RegisterFilter", mock.Anything).Return(nil) mp.On("ReplayAsync", mock.Anything).Return() + mp.On("HasFilter", mock.Anything).Return(false) mp.On("UnregisterFilter", mock.Anything, mock.Anything).Return(nil) mp.On("LatestBlock", mock.Anything).Return(int64(1), nil) mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{ From 2ff674b728ff8a1d4d1acafac29cd5b58a1bc5b4 Mon Sep 17 00:00:00 2001 From: Michael Fletcher <36506122+Fletch153@users.noreply.github.com> Date: Wed, 6 Sep 2023 15:46:38 +0100 Subject: [PATCH 28/88] Additional even emitting + sanity checks + version (#10419) * Additional even emitting + sanity checks + version * Cherry picked changes from bugfix/MERC-1618 * Wrappers + gas * Fixed issue with getAvailableRewardPoolIds --------- Co-authored-by: Austin Born --- .../gas-snapshots/llo-feeds.gas-snapshot | 332 +++++++++--------- .../src/v0.8/llo-feeds/VerifierProxy.sol | 15 +- .../src/v0.8/llo-feeds/dev/FeeManager.sol | 90 +++-- .../src/v0.8/llo-feeds/dev/RewardManager.sol | 33 +- .../llo-feeds/dev/interfaces/IFeeManager.sol | 49 +-- .../dev/interfaces/IRewardManager.sol | 8 +- .../interfaces/IVerifierFeeManager.sol | 4 +- .../llo-feeds/interfaces/IVerifierProxy.sol | 2 +- .../test/fee-manager/BaseFeeManager.t.sol | 28 +- .../test/fee-manager/FeeManager.general.t.sol | 10 +- .../FeeManager.getFeeAndReward.t.sol | 36 ++ .../fee-manager/FeeManager.processFee.t.sol | 42 +++ .../reward-manager/BaseRewardManager.t.sol | 1 + .../reward-manager/RewardManager.claim.t.sol | 40 ++- .../test/verifier/VerifierProxyTest.t.sol | 10 + .../generated/fee_manager/fee_manager.go | 185 +++++++++- .../reward_manager/reward_manager.go | 34 +- .../verifier_proxy/verifier_proxy.go | 4 +- ...rapper-dependency-versions-do-not-edit.txt | 6 +- 19 files changed, 646 insertions(+), 283 deletions(-) rename contracts/src/v0.8/llo-feeds/{ => dev}/interfaces/IVerifierFeeManager.sol (87%) diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 18499e0f6c2..1a2df6b93e5 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -1,135 +1,143 @@ -FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52609) -FeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 25927) -FeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 57240) -FeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 120182) -FeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 28588) -FeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 74518) -FeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 71365) -FeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56167) -FeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 25300) -FeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 14621) -FeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 17579) -FeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 90869) -FeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56477) -FeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52755) -FeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49580) -FeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78792) -FeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 46384) +FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52634) +FeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52566) +FeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78769) +FeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 25961) +FeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 57252) +FeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 118189) +FeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 28568) +FeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 72501) +FeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 71670) +FeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56292) +FeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 25344) +FeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 14623) +FeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 17581) +FeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 90945) +FeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56524) +FeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52803) +FeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49627) +FeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78817) +FeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 46428) FeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17568) -FeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54523) -FeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12361) -FeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41347) -FeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 260960) -FeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 68464) -FeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49645) -FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67562) -FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 64156) -FeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 51987) -FeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 14641) -FeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49771) -FeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55510) -FeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82724) -FeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49623) -FeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49581) -FeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 17579) -FeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50760) +FeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54571) +FeeManagerProcessFeeTest:test_discountIsReturnedForLink() (gas: 49581) +FeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12392) +FeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41412) +FeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 259447) +FeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 69018) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49706) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67635) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 64232) +FeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 52012) +FeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 14621) +FeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49774) +FeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55561) +FeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82702) +FeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49602) +FeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49604) +FeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 17601) +FeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50826) FeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 52375) -FeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30789) -FeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50802) -FeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17188) +FeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30814) +FeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50827) +FeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17166) FeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41370) -FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51832) -FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78015) -FeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 24103) -FeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19814) -FeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 197190) -FeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17338) -FeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 218523) -FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 201471) -FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 120576) -FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 26799) -FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 163879) -FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 27360) -FeeManagerProcessFeeTest:test_processFeeNative() (gas: 176574) -FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 121514) -FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 29118) -FeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30602) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 184105) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 135624) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 159487) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 94615) -FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 191065) -FeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 28471) -FeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 28939) -FeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 29928) -FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 35144) -FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 156485) -FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 55585) -FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 120542) -FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 37846) -FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeUnwrappedReports() (gas: 296517) -FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeWrappedReports() (gas: 279759) -FeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 236449) -FeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 270220) -FeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 71195) -FeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 253350) -FeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 283979) -FeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 300708) -FeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 11011) -FeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19570) +FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51879) +FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78062) +FeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 21892) +FeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19836) +FeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 195521) +FeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17360) +FeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 216708) +FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 199820) +FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 118561) +FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 26811) +FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 163961) +FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 27362) +FeeManagerProcessFeeTest:test_processFeeNative() (gas: 174559) +FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 119521) +FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 29175) +FeeManagerProcessFeeTest:test_processFeeWithDiscountEmitsEvent() (gas: 244302) +FeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30610) +FeeManagerProcessFeeTest:test_processFeeWithNoDiscountDoesNotEmitEvent() (gas: 168476) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 182111) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 133607) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 157494) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 94743) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 189049) +FeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 28473) +FeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 28919) +FeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 29914) +FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 35154) +FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 154448) +FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 55617) +FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 118462) +FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 37856) +FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeUnwrappedReports() (gas: 295021) +FeeManagerProcessFeeTest:test_processMultipleLinkAndNativeWrappedReports() (gas: 278263) +FeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 235077) +FeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 268847) +FeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 71419) +FeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 251978) +FeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 282317) +FeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 299043) +FeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 11038) +FeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19548) FeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46281) -FeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 51089) -FeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 51057) -FeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79188) -FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 46960) -FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49837) -FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78208) -FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 15198) +FeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 51157) +FeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 51082) +FeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79236) +FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47004) +FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49862) +FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78233) +FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 15251) RewardManagerClaimTest:test_claimAllRecipients() (gas: 275763) RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 153306) -RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330467) +RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 328322) RewardManagerClaimTest:test_claimSingleRecipient() (gas: 88340) -RewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 315671) +RewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 313526) RewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 34461) RewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 40491) RewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86069) RewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 24700) -RewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 385336) -RewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 138411) +RewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 383191) +RewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 136266) RewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 489469) -RewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 13550) -RewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 55574) -RewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 249515) -RewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20518) -RewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 249761) -RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 260965) -RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 264101) -RewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28592) -RewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 25013) -RewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31098) -RewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84397) -RewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 197492) +RewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 11405) +RewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 53858) +RewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 249449) +RewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20452) +RewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 249695) +RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 260899) +RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 264035) +RewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28526) +RewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 24947) +RewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31032) +RewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84331) +RewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 197426) RewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 279714) RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 509889) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 281833) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 291618) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 281811) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 291640) RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 261589) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 153390) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 153434) RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 131911) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 105334) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 578510) -RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 63533) -RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 28864) -RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 146842) -RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 18363) -RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 24381) -RewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 389786) -RewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 138427) -RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 200572) -RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 220442) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 105312) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 576243) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 63555) +RewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorAndTotalPoolsEqual() (gas: 10202) +RewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() (gas: 12680) +RewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorSingleResult() (gas: 19606) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 29052) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 147218) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 18532) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 24569) +RewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 387641) +RewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 136305) +RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 198427) +RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 218297) RewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 191821) RewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 126091) -RewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 193950) +RewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 193972) RewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 21452) RewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 193416) RewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 180711) @@ -138,28 +146,28 @@ RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 183 RewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 185681) RewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 87113) RewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 110394) -RewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 21366) -RewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259335) -RewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59390) -RewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17016) -RewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 373819) -RewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 279281) -RewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19727) -RewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 219095) -RewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 273103) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 245309) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259381) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 148982) -RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259455) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 369300) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 258597) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288735) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 261406) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 259384) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 260794) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 259524) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 251916) -RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 250201) +RewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 21388) +RewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259190) +RewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59418) +RewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17038) +RewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 373696) +RewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 279303) +RewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19749) +RewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 218972) +RewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 273125) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 245331) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259403) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 149004) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259477) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 369177) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 258619) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288757) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 261428) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 259406) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 260816) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 259546) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 251938) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 250223) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesAMiddleDigest() (gas: 24155) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesTheFirstDigest() (gas: 24122) VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyUnsetsDigestsInSequence() (gas: 44043) @@ -174,32 +182,34 @@ VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13157) VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 17098) VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 17153) -VerifierBulkVerifyBillingReport:test_verifyBulkReportWithUnwrappedAndWrappedNativeDefaultsToUnwrapped() (gas: 391227) -VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndUnwrappedNative() (gas: 702466) -VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndWrappedNative() (gas: 687045) -VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 570309) -VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 783120) -VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 579516) -VerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 581327) -VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 588801) -VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 595828) +VerifierBulkVerifyBillingReport:test_verifyBulkReportWithUnwrappedAndWrappedNativeDefaultsToUnwrapped() (gas: 391378) +VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndUnwrappedNative() (gas: 700956) +VerifierBulkVerifyBillingReport:test_verifyBulkWithLinkAndWrappedNative() (gas: 685536) +VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 568369) +VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 781180) +VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 578147) +VerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 581753) +VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 589227) +VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 596254) VerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 59939) VerifierConstructorTest:test_setsTheCorrectProperties() (gas: 1788491) VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas: 192062) VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 113377) VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 99613) VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 69932) -VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 204824) +VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 204836) VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 109546) -VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1357299) -VerifierProxyConstructorTest:test_correctlySetsTheOwner() (gas: 1337313) +VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1439877) +VerifierProxyConstructorTest:test_correctlySetsTheOwner() (gas: 1419891) VerifierProxyConstructorTest:test_correctlySetsVersion() (gas: 6873) VerifierProxyInitializeVerifierTest:test_revertsIfDigestAlreadySet() (gas: 54085) VerifierProxyInitializeVerifierTest:test_revertsIfNotCorrectVerifier() (gas: 13572) VerifierProxyInitializeVerifierTest:test_revertsIfNotOwner() (gas: 17179) VerifierProxyInitializeVerifierTest:test_revertsIfVerifierAlreadyInitialized() (gas: 42069) VerifierProxyInitializeVerifierTest:test_revertsIfZeroAddress() (gas: 10970) -VerifierProxyInitializeVerifierTest:test_setFeeManagerZeroAddress() (gas: 10935) +VerifierProxyInitializeVerifierTest:test_setFeeManagerWhichDoesntHonourIERC165Interface() (gas: 13815) +VerifierProxyInitializeVerifierTest:test_setFeeManagerWhichDoesntHonourInterface() (gas: 16301) +VerifierProxyInitializeVerifierTest:test_setFeeManagerZeroAddress() (gas: 10947) VerifierProxyInitializeVerifierTest:test_updatesVerifierIfVerifier() (gas: 53315) VerifierProxySetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35384) VerifierProxySetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 15105) @@ -209,8 +219,8 @@ VerifierProxyUnsetVerifierTest:test_revertsIfDigestDoesNotExist() (gas: 13141) VerifierProxyUnsetVerifierTest:test_revertsIfNotAdmin() (gas: 14965) VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVerifier() (gas: 12697) VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17965) -VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 198408) -VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 116307) +VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 198420) +VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 116319) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538582) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 964048) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 520140) @@ -227,10 +237,10 @@ VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesDigestsOnM VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 519921) VerifierSupportsInterfaceTest:test_falseIfIsNotCorrectInterface() (gas: 5590) VerifierSupportsInterfaceTest:test_trueIfIsCorrectInterface() (gas: 5633) -VerifierTestBillingReport:test_verifyWithLink() (gas: 280557) -VerifierTestBillingReport:test_verifyWithNative() (gas: 321248) -VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 323491) -VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 330557) +VerifierTestBillingReport:test_verifyWithLink() (gas: 278542) +VerifierTestBillingReport:test_verifyWithNative() (gas: 319232) +VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 321475) +VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 328541) VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 131228) VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 187132) VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 88205) @@ -245,11 +255,11 @@ VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 10 VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 184066) VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 110031) VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 194270) -Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 208841) -Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 542038) -Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 565410) +Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 208853) +Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 540669) +Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 564041) Verifier_setConfig:testSetConfigSuccess_gas() (gas: 922428) -Verifier_verify:testVerifyProxySuccess_gas() (gas: 195530) +Verifier_verify:testVerifyProxySuccess_gas() (gas: 195542) Verifier_verify:testVerifySuccess_gas() (gas: 186725) -Verifier_verifyWithFee:testVerifyProxyWithLinkFeeSuccess_gas() (gas: 244506) -Verifier_verifyWithFee:testVerifyProxyWithNativeFeeSuccess_gas() (gas: 262984) \ No newline at end of file +Verifier_verifyWithFee:testVerifyProxyWithLinkFeeSuccess_gas() (gas: 242491) +Verifier_verifyWithFee:testVerifyProxyWithNativeFeeSuccess_gas() (gas: 260968) \ No newline at end of file diff --git a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol b/contracts/src/v0.8/llo-feeds/VerifierProxy.sol index be2f411c0e9..4df6691b6ac 100644 --- a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/VerifierProxy.sol @@ -7,7 +7,7 @@ import {IVerifier} from "./interfaces/IVerifier.sol"; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {AccessControllerInterface} from "../shared/interfaces/AccessControllerInterface.sol"; import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; -import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol"; +import {IVerifierFeeManager} from "./dev/interfaces/IVerifierFeeManager.sol"; import {Common} from "../libraries/Common.sol"; /** @@ -65,6 +65,10 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac /// not conform to the verifier interface error VerifierInvalid(); + /// @notice This error is thrown when the fee manager at an address does + /// not conform to the fee manager interface + error FeeManagerInvalid(); + /// @notice This error is thrown whenever a verifier is not found /// @param configDigest The digest for which a verifier is not found error VerifierNotFound(bytes32 configDigest); @@ -117,7 +121,7 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac } /// @inheritdoc IVerifierProxy - function verify(bytes calldata payload) external payable checkAccess returns (bytes memory verifiedReport) { + function verify(bytes calldata payload) external payable checkAccess returns (bytes memory) { IVerifierFeeManager feeManager = s_feeManager; // Bill the verifier @@ -192,7 +196,7 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac } /// @inheritdoc IVerifierProxy - function getVerifier(bytes32 configDigest) external view override returns (address verifierAddress) { + function getVerifier(bytes32 configDigest) external view override returns (address) { return s_verifiersByConfig[configDigest]; } @@ -207,6 +211,11 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac function setFeeManager(IVerifierFeeManager feeManager) external onlyOwner { if (address(feeManager) == address(0)) revert ZeroAddress(); + if ( + !IERC165(feeManager).supportsInterface(IVerifierFeeManager.processFee.selector) || + !IERC165(feeManager).supportsInterface(IVerifierFeeManager.processFeeBulk.selector) + ) revert FeeManagerInvalid(); + address oldFeeManager = address(s_feeManager); s_feeManager = IVerifierFeeManager(feeManager); emit FeeManagerSet(oldFeeManager, address(feeManager)); diff --git a/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol b/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol index 341ac19762e..2e5d060dca6 100644 --- a/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol @@ -11,6 +11,7 @@ import {IWERC20} from "../../shared/interfaces/IWERC20.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol"; import {Math} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol"; import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol"; /** * @title FeeManager @@ -75,6 +76,9 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { // @notice thrown when trying to clear a zero deficit error ZeroDeficit(); + /// @notice thrown when trying to pay an address that cannot except funds + error InvalidReceivingAddress(); + /// @notice Emitted whenever a subscriber's discount is updated /// @param subscriber address of the subscriber to update discounts for /// @param feedId Feed ID for the discount @@ -91,15 +95,31 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { event InsufficientLink(IRewardManager.FeePayment[] rewards); /// @notice Emitted when funds are withdrawn + /// @param adminAddress Address of the admin + /// @param recipient Address of the recipient /// @param assetAddress Address of the asset withdrawn /// @param quantity Amount of the asset withdrawn - event Withdraw(address adminAddress, address assetAddress, uint192 quantity); + event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity); /// @notice Emits when a deficit has been cleared for a particular config digest /// @param configDigest Config digest of the deficit cleared /// @param linkQuantity Amount of LINK required to pay the deficit event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + /// @notice Emits when a fee has been processed + /// @param configDigest Config digest of the fee processed + /// @param subscriber Address of the subscriber who paid the fee + /// @param fee Fee paid + /// @param reward Reward paid + /// @param appliedDiscount Discount applied to the fee + event DiscountApplied( + bytes32 indexed configDigest, + address indexed subscriber, + Common.Asset fee, + Common.Asset reward, + uint256 appliedDiscount + ); + /** * @notice Construct the FeeManager contract * @param _linkAddress The address of the LINK token @@ -133,9 +153,14 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { _; } + modifier onlyProxy() { + if (msg.sender != i_proxyAddress) revert Unauthorized(); + _; + } + /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "FeeManager 0.0.1"; + return "FeeManager 1.0.0"; } /// @inheritdoc IERC165 @@ -143,9 +168,9 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { return interfaceId == this.processFee.selector || interfaceId == this.processFeeBulk.selector; } - /// @inheritdoc IFeeManager - function processFee(bytes calldata payload, address subscriber) external payable override onlyOwnerOrProxy { - (Common.Asset memory fee, Common.Asset memory reward) = _processFee(payload, subscriber); + /// @inheritdoc IVerifierFeeManager + function processFee(bytes calldata payload, address subscriber) external payable override onlyProxy { + (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _processFee(payload, subscriber); if (fee.amount == 0) { _tryReturnChange(subscriber, msg.value); @@ -153,7 +178,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { } IFeeManager.FeeAndReward[] memory feeAndReward = new IFeeManager.FeeAndReward[](1); - feeAndReward[0] = IFeeManager.FeeAndReward(bytes32(payload), fee, reward); + feeAndReward[0] = IFeeManager.FeeAndReward(bytes32(payload), fee, reward, appliedDiscount); if (fee.assetAddress == i_linkAddress) { _handleFeesAndRewards(subscriber, feeAndReward, 1, 0); @@ -162,8 +187,8 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { } } - /// @inheritdoc IFeeManager - function processFeeBulk(bytes[] calldata payloads, address subscriber) external payable override onlyOwnerOrProxy { + /// @inheritdoc IVerifierFeeManager + function processFeeBulk(bytes[] calldata payloads, address subscriber) external payable override onlyProxy { FeeAndReward[] memory feesAndRewards = new IFeeManager.FeeAndReward[](payloads.length); //keep track of the number of fees to prevent over initialising the FeePayment array within _convertToLinkAndNativeFees @@ -172,10 +197,18 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { uint256 feesAndRewardsIndex; for (uint256 i; i < payloads.length; ++i) { - (Common.Asset memory fee, Common.Asset memory reward) = _processFee(payloads[i], subscriber); + (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _processFee( + payloads[i], + subscriber + ); if (fee.amount != 0) { - feesAndRewards[feesAndRewardsIndex++] = IFeeManager.FeeAndReward(bytes32(payloads[i]), fee, reward); + feesAndRewards[feesAndRewardsIndex++] = IFeeManager.FeeAndReward( + bytes32(payloads[i]), + fee, + reward, + appliedDiscount + ); unchecked { //keep track of some tallys to make downstream calculations more efficient @@ -200,7 +233,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { address subscriber, bytes memory report, Quote memory quote - ) public view returns (Common.Asset memory, Common.Asset memory) { + ) public view returns (Common.Asset memory, Common.Asset memory, uint256) { Common.Asset memory fee; Common.Asset memory reward; @@ -214,7 +247,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { if (reportVersion == REPORT_V1) { fee.assetAddress = i_nativeAddress; reward.assetAddress = i_linkAddress; - return (fee, reward); + return (fee, reward, 0); } //verify the quote payload is a supported token @@ -255,10 +288,10 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { } //return the fee - return (fee, reward); + return (fee, reward, discount); } - /// @inheritdoc IFeeManager + /// @inheritdoc IVerifierFeeManager function setFeeRecipients( bytes32 configDigest, Common.AddressAndWeight[] calldata rewardRecipientAndWeights @@ -293,18 +326,20 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { } /// @inheritdoc IFeeManager - function withdraw(address assetAddress, uint192 quantity) external onlyOwner { + function withdraw(address assetAddress, address recipient, uint192 quantity) external onlyOwner { //address 0 is used to withdraw native in the context of withdrawing if (assetAddress == address(0)) { - payable(owner()).transfer(quantity); + (bool success, ) = payable(recipient).call{value: quantity}(""); + + if (!success) revert InvalidReceivingAddress(); return; } //withdraw the requested asset - IERC20(assetAddress).safeTransfer(owner(), quantity); + IERC20(assetAddress).safeTransfer(recipient, quantity); //emit event when funds are withdrawn - emit Withdraw(msg.sender, assetAddress, quantity); + emit Withdraw(msg.sender, recipient, assetAddress, uint192(quantity)); } /// @inheritdoc IFeeManager @@ -324,7 +359,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { function _processFee( bytes calldata payload, address subscriber - ) internal view returns (Common.Asset memory, Common.Asset memory) { + ) internal view returns (Common.Asset memory, Common.Asset memory, uint256) { if (subscriber == address(this)) revert InvalidAddress(); //decode the report from the payload @@ -381,6 +416,16 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { totalNativeFee += feesAndRewards[i].fee.amount; totalNativeFeeLinkValue += feesAndRewards[i].reward.amount; } + + if (feesAndRewards[i].appliedDiscount != 0) { + emit DiscountApplied( + feesAndRewards[i].configDigest, + subscriber, + feesAndRewards[i].fee, + feesAndRewards[i].reward, + feesAndRewards[i].appliedDiscount + ); + } } //keep track of change in case of any over payment @@ -390,7 +435,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { //there must be enough to cover the fee if (totalNativeFee > msg.value) revert InvalidDeposit(); - //wrap the amount required to pay the fee & approve as the subscriber paid in unwrapped native + //wrap the amount required to pay the fee & approve as the subscriber paid in wrapped native IWERC20(i_nativeAddress).deposit{value: totalNativeFee}(); unchecked { @@ -413,7 +458,10 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { if (totalNativeFeeLinkValue > IERC20(i_linkAddress).balanceOf(address(this))) { // If not enough LINK on this contract to forward for rewards, tally the deficit to be paid by out-of-band LINK for (uint256 i; i < nativeFeeLinkRewards.length; ++i) { - s_linkDeficit[nativeFeeLinkRewards[i].poolId] += nativeFeeLinkRewards[i].amount; + unchecked { + //we have previously tallied the fees, any overflows would have already reverted + s_linkDeficit[nativeFeeLinkRewards[i].poolId] += nativeFeeLinkRewards[i].amount; + } } emit InsufficientLink(nativeFeeLinkRewards); diff --git a/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol b/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol index 8858f82c958..3f7e524c02b 100644 --- a/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol +++ b/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol @@ -54,11 +54,14 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac // @notice Thrown when the calling contract is not within the authorized contracts error Unauthorized(); + // @notice Thrown when getAvailableRewardPoolIds parameters are incorrectly set + error InvalidPoolLength(); + // Events emitted upon state change event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint192 quantity); event FeeManagerUpdated(address newFeeManagerAddress); - event FeePaid(FeePayment[] payments, address payee); + event FeePaid(FeePayment[] payments, address payer); /** * @notice Constructor @@ -73,7 +76,7 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac // @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "RewardManager 0.0.1"; + return "RewardManager 1.0.0"; } // @inheritdoc IERC165 @@ -91,8 +94,13 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac _; } + modifier onlyFeeManager() { + if (msg.sender != s_feeManagerAddress) revert Unauthorized(); + _; + } + /// @inheritdoc IRewardManager - function onFeePaid(FeePayment[] calldata payments, address payee) external override onlyOwnerOrFeeManager { + function onFeePaid(FeePayment[] calldata payments, address payer) external override onlyFeeManager { uint256 totalFeeAmount; for (uint256 i; i < payments.length; ++i) { unchecked { @@ -105,9 +113,9 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac } //transfer the fees to this contract - IERC20(i_linkAddress).safeTransferFrom(payee, address(this), totalFeeAmount); + IERC20(i_linkAddress).safeTransferFrom(payer, address(this), totalFeeAmount); - emit FeePaid(payments, payee); + emit FeePaid(payments, payer); } /// @inheritdoc IRewardManager @@ -276,19 +284,28 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac } /// @inheritdoc IRewardManager - function getAvailableRewardPoolIds(address recipient) external view returns (bytes32[] memory) { + function getAvailableRewardPoolIds( + address recipient, + uint256 startIndex, + uint256 endIndex + ) external view returns (bytes32[] memory) { //get the length of the pool ids which we will loop through and potentially return uint256 registeredPoolIdsLength = s_registeredPoolIds.length; + uint256 lastIndex = endIndex > registeredPoolIdsLength ? registeredPoolIdsLength : endIndex; + + if (startIndex > lastIndex) revert InvalidPoolLength(); + //create a new array with the maximum amount of potential pool ids - bytes32[] memory claimablePoolIds = new bytes32[](registeredPoolIdsLength); + bytes32[] memory claimablePoolIds = new bytes32[](lastIndex - startIndex); //we want the pools which a recipient has funds for to be sequential, so we need to keep track of the index uint256 poolIdArrayIndex; //loop all the pool ids, and check if the recipient has a registered weight and a claimable amount - for (uint256 i; i < registeredPoolIdsLength; ++i) { + for (uint256 i = startIndex; i < lastIndex; ++i) { //get the poolId bytes32 poolId = s_registeredPoolIds[i]; + //if the recipient has a weight, they are a recipient of this poolId if (s_rewardRecipientWeights[poolId][recipient] != 0) { //get the total in this pool diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol index ff81aafe5d3..49fd7f95587 100644 --- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol @@ -3,49 +3,21 @@ pragma solidity 0.8.16; import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; import {Common} from "../../../libraries/Common.sol"; -import {IVerifierFeeManager} from "../../interfaces/IVerifierFeeManager.sol"; +import {IVerifierFeeManager} from "./IVerifierFeeManager.sol"; interface IFeeManager is IERC165, IVerifierFeeManager { - struct Quote { - address quoteAddress; - } - - /** - * @notice Processes the fee for a report, billing the subscriber and paying the reward manager - * @param payload report and quote data to process the fee for - * @param subscriber address of the user to process fee for - */ - function processFee(bytes calldata payload, address subscriber) external payable; - - /** - * @notice Processes the fees for each report in the payload, billing the subscriber and paying the reward manager - * @param payloads reports and quotes to process - * @param subscriber address of the user to process fee for - */ - function processFeeBulk(bytes[] calldata payloads, address subscriber) external payable; - /** * @notice Calculate the applied fee and the reward from a report. If the sender is a subscriber, they will receive a discount. * @param subscriber address trying to verify * @param report report to calculate the fee for * @param quote any metadata required to fetch the fee - * @return (fee, reward) fee and the reward data + * @return (fee, reward, totalDiscount) fee and the reward data with the discount applied */ function getFeeAndReward( address subscriber, bytes memory report, Quote memory quote - ) external returns (Common.Asset memory, Common.Asset memory); - - /** - * @notice Sets the fee recipients within the reward manager - * @param configDigest digest of the configuration - * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards - */ - function setFeeRecipients( - bytes32 configDigest, - Common.AddressAndWeight[] calldata rewardRecipientAndWeights - ) external; + ) external returns (Common.Asset memory, Common.Asset memory, uint256); /** * @notice Sets the native surcharge @@ -64,10 +36,11 @@ interface IFeeManager is IERC165, IVerifierFeeManager { /** * @notice Withdraws any native or LINK rewards to the owner address - * @param quantity quantity of tokens to withdraw, address(0) is native + * @param assetAddress address of the asset to withdraw + * @param recipientAddress address to withdraw to * @param quantity quantity to withdraw */ - function withdraw(address assetAddress, uint192 quantity) external; + function withdraw(address assetAddress, address recipientAddress, uint192 quantity) external; /** * @notice Returns the link balance of the fee manager @@ -86,10 +59,20 @@ interface IFeeManager is IERC165, IVerifierFeeManager { * @param digest the digest linked to the fee and reward * @param fee the fee paid to verify the report * @param reward the reward paid upon verification + & @param appliedDiscount the discount applied to the reward */ struct FeeAndReward { bytes32 configDigest; Common.Asset fee; Common.Asset reward; + uint256 appliedDiscount; + } + + /** + * @notice The structure to hold quote metadata + * @param quoteAddress the address of the quote + */ + struct Quote { + address quoteAddress; } } diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol index e9b351c935c..8f6b1921e94 100644 --- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol @@ -48,8 +48,14 @@ interface IRewardManager is IERC165 { /** * @notice Gets a list of pool ids which have reward for a specific recipient. * @param recipient address of the recipient to get pool ids for + * @param startIndex the index to start from + * @param endIndex the index to stop at */ - function getAvailableRewardPoolIds(address recipient) external view returns (bytes32[] memory); + function getAvailableRewardPoolIds( + address recipient, + uint256 startIndex, + uint256 endIndex + ) external view returns (bytes32[] memory); /** * @notice The structure to hold a fee payment notice diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IVerifierFeeManager.sol similarity index 87% rename from contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol rename to contracts/src/v0.8/llo-feeds/dev/interfaces/IVerifierFeeManager.sol index 92220582ba4..c9b1a821746 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IVerifierFeeManager.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.16; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; -import {Common} from "../../libraries/Common.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../../libraries/Common.sol"; interface IVerifierFeeManager is IERC165 { /** diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol index be221263c56..82ac492f5c3 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.16; import {Common} from "../../libraries/Common.sol"; import {AccessControllerInterface} from "../../shared/interfaces/AccessControllerInterface.sol"; -import {IVerifierFeeManager} from "./IVerifierFeeManager.sol"; +import {IVerifierFeeManager} from "./../dev/interfaces/IVerifierFeeManager.sol"; interface IVerifierProxy { /** diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol index 10bd89331f1..6b8858fc93f 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol @@ -75,8 +75,15 @@ contract BaseFeeManagerTest is Test { event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint64 discount); event NativeSurchargeUpdated(uint64 newSurcharge); event InsufficientLink(IRewardManager.FeePayment[] feesAndRewards); - event Withdraw(address adminAddress, address assetAddress, uint192 quantity); + event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity); event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + event DiscountApplied( + bytes32 indexed configDigest, + address indexed subscriber, + Common.Asset fee, + Common.Asset reward, + uint256 appliedDiscountQuantity + ); function setUp() public virtual { //change to admin user @@ -153,7 +160,7 @@ contract BaseFeeManagerTest is Test { address subscriber ) public view returns (Common.Asset memory) { //get the fee - (Common.Asset memory fee, ) = feeManager.getFeeAndReward(subscriber, report, quote); + (Common.Asset memory fee, , ) = feeManager.getFeeAndReward(subscriber, report, quote); return fee; } @@ -164,11 +171,22 @@ contract BaseFeeManagerTest is Test { address subscriber ) public view returns (Common.Asset memory) { //get the reward - (, Common.Asset memory reward) = feeManager.getFeeAndReward(subscriber, report, quote); + (, Common.Asset memory reward, ) = feeManager.getFeeAndReward(subscriber, report, quote); return reward; } + function getAppliedDiscount( + bytes memory report, + IFeeManager.Quote memory quote, + address subscriber + ) public view returns (uint256) { + //get the reward + (, , uint256 appliedDiscount) = feeManager.getFeeAndReward(subscriber, report, quote); + + return appliedDiscount; + } + function getV1Report(bytes32 feedId) public pure returns (bytes memory) { return abi.encode(feedId, uint32(0), int192(0), int192(0), int192(0), uint64(0), bytes32(0), uint64(0), uint64(0)); } @@ -229,13 +247,13 @@ contract BaseFeeManagerTest is Test { return IFeeManager.Quote(getNativeAddress()); } - function withdraw(address assetAddress, uint256 amount, address sender) public { + function withdraw(address assetAddress, address recipient, uint256 amount, address sender) public { //record the current address and switch to the recipient address originalAddr = msg.sender; changePrank(sender); //set the surcharge - feeManager.withdraw(assetAddress, uint192(amount)); + feeManager.withdraw(assetAddress, recipient, uint192(amount)); //change back to the original address changePrank(originalAddr); diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol index 2e5d6cf15e7..d776c54eb36 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol @@ -28,7 +28,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { uint256 withdrawAmount = contractBalance / 2; //withdraw some balance - withdraw(getLinkAddress(), withdrawAmount, ADMIN); + withdraw(getLinkAddress(), ADMIN, withdrawAmount, ADMIN); //check the balance has been reduced uint256 newContractBalance = getLinkBalance(address(feeManager)); @@ -54,7 +54,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { uint256 withdrawAmount = contractBalance / 2; //withdraw some balance - withdraw(NATIVE_WITHDRAW_ADDRESS, withdrawAmount, ADMIN); + withdraw(NATIVE_WITHDRAW_ADDRESS, ADMIN, withdrawAmount, ADMIN); //check the balance has been reduced uint256 newContractBalance = getNativeUnwrappedBalance(address(feeManager)); @@ -76,7 +76,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); //withdraw some balance - withdraw(getLinkAddress(), DEFAULT_LINK_MINT_QUANTITY, USER); + withdraw(getLinkAddress(), ADMIN, DEFAULT_LINK_MINT_QUANTITY, USER); } function test_eventIsEmittedAfterSurchargeIsSet() public { @@ -118,10 +118,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { vm.expectEmit(); //the event to be emitted - emit Withdraw(ADMIN, getLinkAddress(), withdrawAmount); + emit Withdraw(ADMIN, ADMIN, getLinkAddress(), withdrawAmount); //withdraw some balance - withdraw(getLinkAddress(), withdrawAmount, ADMIN); + withdraw(getLinkAddress(), ADMIN, withdrawAmount, ADMIN); } function test_linkAvailableForPaymentReturnsLinkBalance() public { diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol index d59ced1a237..f31c06bd41e 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol @@ -570,4 +570,40 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { USER ); } + + function test_discountIsReturnedForLink() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_DiscountIsReturnedForNative() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_DiscountIsReturnedForNativeWithSurcharge() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR / 5, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } } diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol index ab13a60c371..aa0ca063d85 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol @@ -455,4 +455,46 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { //check the unused native passed in is returned assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); } + + function test_processFeeWithDiscountEmitsEvent() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE / 2, USER); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + uint256 appliedDiscount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + vm.expectEmit(); + + emit DiscountApplied(DEFAULT_CONFIG_DIGEST, USER, fee, reward, appliedDiscount); + + //call processFee should not revert as the fee is 0 + processFee(payload, USER, 0); + } + + function test_processFeeWithNoDiscountDoesNotEmitEvent() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + //call processFee should not revert as the fee is 0 + processFee(payload, USER, 0); + + //no logs should have been emitted + assertEq(vm.getRecordedLogs().length, 0); + } } diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol index a54431b64a2..a82859df624 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol @@ -67,6 +67,7 @@ contract BaseRewardManagerTest is Test { bytes4 internal immutable INVALID_WEIGHT_ERROR_SELECTOR = RewardManager.InvalidWeights.selector; bytes4 internal immutable INVALID_POOL_ID_ERROR_SELECTOR = RewardManager.InvalidPoolId.selector; bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner"; + bytes4 internal immutable INVALID_POOL_LENGTH_SELECTOR = RewardManager.InvalidPoolLength.selector; // Events emitted within the reward manager event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol index db514c5dd8a..9a3749d1dde 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol @@ -550,7 +550,11 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { function test_getRewardsAvailableToRecipientInBothPools() public { //get index 0 as this recipient is in both default pools - bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr); + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[0].addr, + 0, + type(uint256).max + ); //check the recipient is in both pools assertEq(poolIds[0], PRIMARY_POOL_ID); @@ -559,7 +563,11 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { function test_getRewardsAvailableToRecipientInSinglePool() public { //get index 0 as this recipient is in both default pools - bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[1].addr); + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[1].addr, + 0, + type(uint256).max + ); //check the recipient is in both pools assertEq(poolIds[0], PRIMARY_POOL_ID); @@ -568,7 +576,7 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { function test_getRewardsAvailableToRecipientInNoPools() public { //get index 0 as this recipient is in both default pools - bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER); + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, 0, type(uint256).max); //check the recipient is in neither pool assertEq(poolIds[0], ZERO_POOL_ID); @@ -577,7 +585,11 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { function test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() public { //get index 0 as this recipient is in both default pools - bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr); + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[0].addr, + 0, + type(uint256).max + ); //check the recipient is in both pools assertEq(poolIds[0], PRIMARY_POOL_ID); @@ -588,12 +600,30 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); //get the available pools again - poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr); + poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, type(uint256).max); //user should not be in any pool assertEq(poolIds[0], ZERO_POOL_ID); assertEq(poolIds[1], ZERO_POOL_ID); } + + function test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() public { + vm.expectRevert(INVALID_POOL_LENGTH_SELECTOR); + + rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, type(uint256).max, 0); + } + + function test_getAvailableRewardsCursorAndTotalPoolsEqual() public { + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 2, 2); + + assertEq(poolIds.length, 0); + } + + function test_getAvailableRewardsCursorSingleResult() public { + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, 1); + + assertEq(poolIds[0], PRIMARY_POOL_ID); + } } contract RewardManagerRecipientClaimDifferentWeightsTest is BaseRewardManagerTest { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol index 4d1c57cd822..0aae95b3da2 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol @@ -14,4 +14,14 @@ contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAn vm.expectRevert(abi.encodeWithSelector(VerifierProxy.ZeroAddress.selector)); s_verifierProxy.setFeeManager(FeeManager(address(0))); } + + function test_setFeeManagerWhichDoesntHonourInterface() public { + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.FeeManagerInvalid.selector)); + s_verifierProxy.setFeeManager(FeeManager(address(s_verifier))); + } + + function test_setFeeManagerWhichDoesntHonourIERC165Interface() public { + vm.expectRevert(); + s_verifierProxy.setFeeManager(FeeManager(address(1))); + } } diff --git a/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go b/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go index 75fcba1ce41..d8fdd50e6ed 100644 --- a/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go +++ b/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go @@ -50,8 +50,8 @@ type IRewardManagerFeePayment struct { } var FeeManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"rewards\",\"type\":\"tuple[]\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSurcharge\",\"type\":\"uint64\"}],\"name\":\"NativeSurchargeUpdated\",\"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\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"internalType\":\"structIFeeManager.Quote\",\"name\":\"quote\",\"type\":\"tuple\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFeeBulk\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"surcharge\",\"type\":\"uint64\"}],\"name\":\"setNativeSurcharge\",\"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\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620033c1380380620033c1833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e051612feb620003d6600039600081816111250152818161146e01528181611b770152611dd201526000818161059f015281816111e501526113b4015260008181610a2101528181610a7401528181610d2b01528181610e3701528181611a9d0152611b4601526000818161073301528181610a4601528181610acf01528181610c1901528181610c8801528181610cc701528181610de001528181610f770152818161130a015281816118460152611c380152612feb6000f3fe60806040526004361061010e5760003560e01c806387d6d843116100a5578063d09dc33911610074578063f1387e1611610059578063f1387e1614610345578063f2fde38b14610358578063f65df9621461037857600080fd5b8063d09dc33914610310578063e389d9a41461032557600080fd5b806387d6d8431461024f5780638da5cb5b1461028d578063c541cbde146102c2578063ce7817d1146102f057600080fd5b806332f5f746116100e157806332f5f746146101f157806340d7f78e14610207578063505380941461021a57806379ba50971461023a57600080fd5b8063013f542b1461011357806301ffc9a7146101535780631791dc5e14610183578063181f5a77146101a5575b600080fd5b34801561011f57600080fd5b5061014061012e3660046123ce565b60036020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561015f57600080fd5b5061017361016e3660046123e7565b610398565b604051901515815260200161014a565b34801561018f57600080fd5b506101a361019e366004612471565b610431565b005b3480156101b157600080fd5b50604080518082018252601081527f4665654d616e6167657220302e302e31000000000000000000000000000000006020820152905161014a91906124ce565b3480156101fd57600080fd5b5061014060045481565b6101a361021536600461251f565b610587565b34801561022657600080fd5b506101a36102353660046125c2565b6107e4565b34801561024657600080fd5b506101a361087e565b34801561025b57600080fd5b5061014061026a3660046125dd565b600260209081526000938452604080852082529284528284209052825290205481565b34801561029957600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014a565b3480156102ce57600080fd5b506102e26102dd366004612749565b610980565b60405161014a9291906127ea565b3480156102fc57600080fd5b506101a361030b36600461283e565b610d8a565b34801561031c57600080fd5b50610140610f46565b34801561033157600080fd5b506101a36103403660046123ce565b610ffc565b6101a361035336600461288f565b6111cd565b34801561036457600080fd5b506101a36103733660046128f1565b611388565b34801561038457600080fd5b506101a361039336600461290e565b61139c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167ff1387e1600000000000000000000000000000000000000000000000000000000148061042b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f40d7f78e00000000000000000000000000000000000000000000000000000000145b92915050565b6104396114d5565b73ffffffffffffffffffffffffffffffffffffffff82166104ba576000805460405173ffffffffffffffffffffffffffffffffffffffff9091169177ffffffffffffffffffffffffffffffffffffffffffffffff841680156108fc02929091818181858888f193505050501580156104b5573d6000803e3d6000fd5b505050565b6105146104dc60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff84169077ffffffffffffffffffffffffffffffffffffffffffffffff8416611558565b6040805133815273ffffffffffffffffffffffffffffffffffffffff8416602082015277ffffffffffffffffffffffffffffffffffffffffffffffff83168183015290517f72608e45b52a95a12c2ac7f15ff53f92fc9572c9d84b6e6b5d7f0f7826cf32719181900360600190a15b5050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015906105e5575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561061c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008267ffffffffffffffff81111561063757610637612614565b60405190808252806020026020018201604052801561067057816020015b61065d612349565b8152602001906001900390816106555790505b5090506000806000805b868110156107ad576000806106b28a8a8581811061069a5761069a61298d565b90506020028101906106ac91906129bc565b8a61162c565b91509150816020015160001461079a5760405180606001604052808b8b868181106106df576106df61298d565b90506020028101906106f191906129bc565b6106fa91612a28565b815260208101849052604001829052878561071481612a93565b9650815181106107265761072661298d565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16036107935785600101955061079a565b8460010194505b5050806107a690612a93565b905061067a565b50821515806107bb57508115155b156107d1576107cc85858585611761565b6107db565b6107db8534611e54565b50505050505050565b6107ec6114d5565b670de0b6b3a764000067ffffffffffffffff82161115610838576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660048190556040519081527f08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d6399060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314610904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080518082019091526000808252602082015260408051808201909152600080825260208201526040805180820190915260008082526020820152604080518082019091526000808252602082015260006109db87612acb565b90507fffff000000000000000000000000000000000000000000000000000000000000808216908101610a7257505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f00000000000000000000000000000000000000000000000000000000000000001681529092509050610d82565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff1614158015610b2257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff1614155b15610b59576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008a806020019051810190610b729190612b24565b77ffffffffffffffffffffffffffffffffffffffffffffffff92831698509116955063ffffffff1693505050428210159050610bda576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808d16600090815260026020908152604080832089845282528083208e51851684529091529020547f00000000000000000000000000000000000000000000000000000000000000009091168752610c6a610c5282670de0b6b3a7640000612b96565b610c5c9086612ba9565b670de0b6b3a7640000611e9d565b60208801528a5173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116911603610cf85773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016885260208088015190890152610d75565b600454600090610d1490610c5290670de0b6b3a7640000612be6565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a529050610d6e610d6483670de0b6b3a7640000612b96565b610c5c9083612ba9565b60208a0152505b5095975093955050505050505b935093915050565b610d926114d5565b670de0b6b3a764000067ffffffffffffffff82161115610dde576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015610e8657507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15610ebd576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff848116600081815260026020908152604080832088845282528083209487168084529482529182902067ffffffffffffffff86169081905582519485529084015285927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a350505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610fd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff79190612bf9565b905090565b6110046114d5565b6000818152600360205260408120549081900361104d576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600360205260408082208290558051600180825281830190925290816020015b604080518082019091526000808252602082015281526020019060019003908161107257905050905060405180604001604052808481526020018377ffffffffffffffffffffffffffffffffffffffffffffffff16815250816000815181106110dd576110dd61298d565b60209081029190910101526040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa199061115c9084903090600401612c72565b600060405180830381600087803b15801561117657600080fd5b505af115801561118a573d6000803e3d6000fd5b50505050827f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd9895836040516111c091815260200190565b60405180910390a2505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480159061122b575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611262576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061127085858561162c565b9150915081602001516000036112915761128a8334611e54565b5050505050565b604080516001808252818301909252600091816020015b6112b0612349565b8152602001906001900390816112a85750506040805160608101909152909150806112db8789612a28565b815260200184815260200183815250816000815181106112fd576112fd61298d565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16036113725761136d848260016000611761565b611380565b611380848260006001611761565b505050505050565b6113906114d5565b61139981611ed5565b50565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015906113fa575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611431576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f14060f2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906314060f23906114a790869086908690600401612caa565b600060405180830381600087803b1580156114c157600080fd5b505af11580156107db573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314611556576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108fb565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104b59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611fca565b604080518082019091526000808252602082015260408051808201909152600080825260208201523073ffffffffffffffffffffffffffffffffffffffff8416036116a3576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116b185870187612d98565b9150506000816116c090612acb565b6040805160208101909152600081529091507e010000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000831614611747576000611728888a018a612e5c565b95505050505050808060200190518101906117439190612f24565b9150505b611752868483610980565b94509450505050935093915050565b60008267ffffffffffffffff81111561177c5761177c612614565b6040519080825280602002602001820160405280156117c157816020015b604080518082019091526000808252602082015281526020019060019003908161179a5790505b50905060008267ffffffffffffffff8111156117df576117df612614565b60405190808252806020026020018201604052801561182457816020015b60408051808201909152600080825260208201528152602001906001900390816117fd5790505b509050600080808080611837888a612be6565b905060005b81811015611a58577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b828151811061188d5761188d61298d565b6020026020010151602001516000015173ffffffffffffffffffffffffffffffffffffffff16036119535760405180604001604052808c83815181106118d5576118d561298d565b60200260200101516000015181526020018c83815181106118f8576118f861298d565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff1681525088858061193190612a93565b9650815181106119435761194361298d565b6020026020010181905250611a48565b60405180604001604052808c83815181106119705761197061298d565b60200260200101516000015181526020018c83815181106119935761199361298d565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff168152508784806119cc90612a93565b9550815181106119de576119de61298d565b60200260200101819052508a81815181106119fb576119fb61298d565b6020026020010151602001516020015186611a169190612be6565b95508a8181518110611a2a57611a2a61298d565b6020026020010151604001516020015185611a459190612be6565b94505b611a5181612a93565b905061183c565b5060003415611b265734861115611a9b576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b50505050508534039050611b6e565b8515611b6e57611b6e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168d30896120d6565b875115611c03577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b0d9fa19898e6040518363ffffffff1660e01b8152600401611bd0929190612c72565b600060405180830381600087803b158015611bea57600080fd5b505af1158015611bfe573d6000803e3d6000fd5b505050505b865115611e3c576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb89190612bf9565b851115611d955760005b8751811015611d5857878181518110611cdd57611cdd61298d565b60200260200101516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16600360008a8481518110611d1957611d1961298d565b60200260200101516000015181526020019081526020016000206000828254611d429190612be6565b90915550611d51905081612a93565b9050611cc2565b507ff52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b6787604051611d889190612f52565b60405180910390a1611e3c565b6040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa1990611e09908a903090600401612c72565b600060405180830381600087803b158015611e2357600080fd5b505af1158015611e37573d6000803e3d6000fd5b505050505b611e468c82611e54565b505050505050505050505050565b80156105835760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156104b5573d6000803e3d6000fd5b60008215611ecb5781611eb1600185612b96565b611ebb9190612f65565b611ec6906001612be6565b611ece565b60005b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611f54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108fb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061202c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661213a9092919063ffffffff16565b8051909150156104b5578080602001905181019061204a9190612fa0565b6104b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108fb565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526121349085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016115aa565b50505050565b60606121498484600085612151565b949350505050565b6060824710156121e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108fb565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161220c9190612fc2565b60006040518083038185875af1925050503d8060008114612249576040519150601f19603f3d011682016040523d82523d6000602084013e61224e565b606091505b509150915061225f8783838761226a565b979650505050505050565b606083156123005782516000036122f95773ffffffffffffffffffffffffffffffffffffffff85163b6122f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108fb565b5081612149565b61214983838151156123155781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fb91906124ce565b6040518060600160405280600080191681526020016123916040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b81526020016123c96040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b905290565b6000602082840312156123e057600080fd5b5035919050565b6000602082840312156123f957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ece57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461139957600080fd5b77ffffffffffffffffffffffffffffffffffffffffffffffff8116811461139957600080fd5b6000806040838503121561248457600080fd5b823561248f81612429565b9150602083013561249f8161244b565b809150509250929050565b60005b838110156124c55781810151838201526020016124ad565b50506000910152565b60208152600082518060208401526124ed8160408501602087016124aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060006040848603121561253457600080fd5b833567ffffffffffffffff8082111561254c57600080fd5b818601915086601f83011261256057600080fd5b81358181111561256f57600080fd5b8760208260051b850101111561258457600080fd5b6020928301955093505084013561259a81612429565b809150509250925092565b803567ffffffffffffffff811681146125bd57600080fd5b919050565b6000602082840312156125d457600080fd5b611ece826125a5565b6000806000606084860312156125f257600080fd5b83356125fd81612429565b925060208401359150604084013561259a81612429565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810167ffffffffffffffff8111828210171561266657612666612614565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156126b3576126b3612614565b604052919050565b600082601f8301126126cc57600080fd5b813567ffffffffffffffff8111156126e6576126e6612614565b61271760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161266c565b81815284602083860101111561272c57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000838503606081121561275f57600080fd5b843561276a81612429565b9350602085013567ffffffffffffffff81111561278657600080fd5b612792878288016126bb565b93505060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0820112156127c557600080fd5b506127ce612643565b60408501356127dc81612429565b815292959194509192509050565b825173ffffffffffffffffffffffffffffffffffffffff1681526020808401519082015260808101825173ffffffffffffffffffffffffffffffffffffffff16604083015260208301516060830152611ece565b6000806000806080858703121561285457600080fd5b843561285f81612429565b935060208501359250604085013561287681612429565b9150612884606086016125a5565b905092959194509250565b6000806000604084860312156128a457600080fd5b833567ffffffffffffffff808211156128bc57600080fd5b818601915086601f8301126128d057600080fd5b8135818111156128df57600080fd5b87602082850101111561258457600080fd5b60006020828403121561290357600080fd5b8135611ece81612429565b60008060006040848603121561292357600080fd5b83359250602084013567ffffffffffffffff8082111561294257600080fd5b818601915086601f83011261295657600080fd5b81358181111561296557600080fd5b8760208260061b850101111561297a57600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129f157600080fd5b83018035915067ffffffffffffffff821115612a0c57600080fd5b602001915036819003821315612a2157600080fd5b9250929050565b8035602083101561042b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612ac457612ac4612a64565b5060010190565b80516020808301519190811015612b0a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff811681146125bd57600080fd5b60008060008060008060c08789031215612b3d57600080fd5b86519550612b4d60208801612b10565b9450612b5b60408801612b10565b93506060870151612b6b8161244b565b6080880151909350612b7c8161244b565b9150612b8a60a08801612b10565b90509295509295509295565b8181038181111561042b5761042b612a64565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612be157612be1612a64565b500290565b8082018082111561042b5761042b612a64565b600060208284031215612c0b57600080fd5b5051919050565b600081518084526020808501945080840160005b83811015612c675781518051885283015177ffffffffffffffffffffffffffffffffffffffffffffffff168388015260409096019590820190600101612c26565b509495945050505050565b604081526000612c856040830185612c12565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b8381526040602080830182905282820184905260009190859060608501845b87811015612d1d578335612cdc81612429565b73ffffffffffffffffffffffffffffffffffffffff16825267ffffffffffffffff612d088585016125a5565b16828401529284019290840190600101612cc9565b5098975050505050505050565b600082601f830112612d3b57600080fd5b6040516060810181811067ffffffffffffffff82111715612d5e57612d5e612614565b604052806060840185811115612d7357600080fd5b845b81811015612d8d578035835260209283019201612d75565b509195945050505050565b60008060808385031215612dab57600080fd5b612db58484612d2a565b9150606083013567ffffffffffffffff811115612dd157600080fd5b612ddd858286016126bb565b9150509250929050565b600082601f830112612df857600080fd5b8135602067ffffffffffffffff821115612e1457612e14612614565b8160051b612e2382820161266c565b9283528481018201928281019087851115612e3d57600080fd5b83870192505b8483101561225f57823582529183019190830190612e43565b6000806000806000806101008789031215612e7657600080fd5b612e808888612d2a565b9550606087013567ffffffffffffffff80821115612e9d57600080fd5b612ea98a838b016126bb565b96506080890135915080821115612ebf57600080fd5b612ecb8a838b01612de7565b955060a0890135915080821115612ee157600080fd5b612eed8a838b01612de7565b945060c0890135935060e0890135915080821115612f0a57600080fd5b50612f1789828a016126bb565b9150509295509295509295565b600060208284031215612f3657600080fd5b612f3e612643565b8251612f4981612429565b81529392505050565b602081526000611ece6020830184612c12565b600082612f9b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215612fb257600080fd5b81518015158114611ece57600080fd5b60008251612fd48184602087016124aa565b919091019291505056fea164736f6c6343000810000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReceivingAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"fee\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"reward\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"appliedDiscount\",\"type\":\"uint256\"}],\"name\":\"DiscountApplied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"rewards\",\"type\":\"tuple[]\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSurcharge\",\"type\":\"uint64\"}],\"name\":\"NativeSurchargeUpdated\",\"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\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"internalType\":\"structIFeeManager.Quote\",\"name\":\"quote\",\"type\":\"tuple\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFeeBulk\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"surcharge\",\"type\":\"uint64\"}],\"name\":\"setNativeSurcharge\",\"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\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b50604051620034d8380380620034d8833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e051613102620003d660003960008181611185015281816114a601528181611ce20152611f3001526000818161061a0152818161124501526113ec015260008181610a7a01528181610ad101528181610d8801528181610e9701528181611c080152611cb101526000818161079301528181610a9f01528181610b2c01528181610c7601528181610ce501528181610d2401528181610e4001528181610fd70152818161134f015281816118830152611da301526131026000f3fe60806040526004361061010e5760003560e01c806387d6d843116100a5578063d09dc33911610074578063f1387e1611610059578063f1387e1614610382578063f2fde38b14610395578063f65df962146103b557600080fd5b8063d09dc3391461034d578063e389d9a41461036257600080fd5b806387d6d8431461024f5780638da5cb5b1461028d578063c541cbde146102c2578063ce7817d11461032d57600080fd5b806332f5f746116100e157806332f5f746146101f157806340d7f78e14610207578063505380941461021a57806379ba50971461023a57600080fd5b8063013f542b1461011357806301ffc9a714610153578063181f5a77146101835780631d4d84a2146101cf575b600080fd5b34801561011f57600080fd5b5061014061012e366004612532565b60036020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561015f57600080fd5b5061017361016e36600461254b565b6103d5565b604051901515815260200161014a565b34801561018f57600080fd5b50604080518082018252601081527f4665654d616e6167657220312e302e30000000000000000000000000000000006020820152905161014a91906125b1565b3480156101db57600080fd5b506101ef6101ea36600461264a565b61046e565b005b3480156101fd57600080fd5b5061014060045481565b6101ef610215366004612695565b610602565b34801561022657600080fd5b506101ef61023536600461272d565b610845565b34801561024657600080fd5b506101ef6108df565b34801561025b57600080fd5b5061014061026a366004612748565b600260209081526000938452604080852082529284528284209052825290205481565b34801561029957600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014a565b3480156102ce57600080fd5b506102e26102dd3660046128b4565b6109e1565b60408051845173ffffffffffffffffffffffffffffffffffffffff9081168252602095860151868301528451169181019190915292909101516060830152608082015260a00161014a565b34801561033957600080fd5b506101ef610348366004612955565b610dea565b34801561035957600080fd5b50610140610fa6565b34801561036e57600080fd5b506101ef61037d366004612532565b61105c565b6101ef6103903660046129a6565b61122d565b3480156103a157600080fd5b506101ef6103b0366004612a08565b6113c0565b3480156103c157600080fd5b506101ef6103d0366004612a25565b6113d4565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167ff1387e1600000000000000000000000000000000000000000000000000000000148061046857507fffffffff0000000000000000000000000000000000000000000000000000000082167f40d7f78e00000000000000000000000000000000000000000000000000000000145b92915050565b61047661150d565b73ffffffffffffffffffffffffffffffffffffffff831661054b5760008273ffffffffffffffffffffffffffffffffffffffff168277ffffffffffffffffffffffffffffffffffffffffffffffff1660405160006040518083038185875af1925050503d8060008114610505576040519150601f19603f3d011682016040523d82523d6000602084013e61050a565b606091505b5050905080610545576040517fef2af20100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61058673ffffffffffffffffffffffffffffffffffffffff84168377ffffffffffffffffffffffffffffffffffffffffffffffff8416611590565b6040805133815273ffffffffffffffffffffffffffffffffffffffff848116602083015285168183015277ffffffffffffffffffffffffffffffffffffffffffffffff8316606082015290517f7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f299181900360800190a15b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610671576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008267ffffffffffffffff81111561068c5761068c61277f565b6040519080825280602002602001820160405280156106c557816020015b6106b26124a5565b8152602001906001900390816106aa5790505b5090506000806000805b8681101561080e5760008060006107098b8b868181106106f1576106f1612aa4565b90506020028101906107039190612ad3565b8b611664565b92509250925082602001516000146107fa5760405180608001604052808c8c8781811061073857610738612aa4565b905060200281019061074a9190612ad3565b61075391612b3f565b81526020018481526020018381526020018281525088868061077490612baa565b97508151811061078657610786612aa4565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16036107f3578660010196506107fa565b8560010195505b5050508061080790612baa565b90506106cf565b508215158061081c57508115155b156108325761082d8585858561179e565b61083c565b61083c8534611fb2565b50505050505050565b61084d61150d565b670de0b6b3a764000067ffffffffffffffff82161115610899576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660048190556040519081527f08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d6399060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314610965576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6040805180820182526000808252602080830182905283518085018552828152808201839052845180860186528381528083018490528551808701909652838652918501839052929382610a3488612be2565b90507fffff000000000000000000000000000000000000000000000000000000000000808216908101610acf57505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f0000000000000000000000000000000000000000000000000000000000000000168152909350915060009050610de1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16886000015173ffffffffffffffffffffffffffffffffffffffff1614158015610b7f57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16886000015173ffffffffffffffffffffffffffffffffffffffff1614155b15610bb6576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008b806020019051810190610bcf9190612c3b565b77ffffffffffffffffffffffffffffffffffffffffffffffff92831698509116955063ffffffff1693505050428210159050610c37576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808e16600090815260026020908152604080832089845282528083208f51851684529091529020547f00000000000000000000000000000000000000000000000000000000000000009091168752610cc7610caf82670de0b6b3a7640000612cad565b610cb99086612cc0565b670de0b6b3a7640000611fff565b60208801528b5173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116911603610d555773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016885260208088015190890152610dd2565b600454600090610d7190610caf90670de0b6b3a7640000612cfd565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a529050610dcb610dc183670de0b6b3a7640000612cad565b610cb99083612cc0565b60208a0152505b96995094975094955050505050505b93509350939050565b610df261150d565b670de0b6b3a764000067ffffffffffffffff82161115610e3e576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015610ee657507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15610f1d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff848116600081815260026020908152604080832088845282528083209487168084529482529182902067ffffffffffffffff86169081905582519485529084015285927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a350505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611033573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110579190612d10565b905090565b61106461150d565b600081815260036020526040812054908190036110ad576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600360205260408082208290558051600180825281830190925290816020015b60408051808201909152600080825260208201528152602001906001900390816110d257905050905060405180604001604052808481526020018377ffffffffffffffffffffffffffffffffffffffffffffffff168152508160008151811061113d5761113d612aa4565b60209081029190910101526040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa19906111bc9084903090600401612d89565b600060405180830381600087803b1580156111d657600080fd5b505af11580156111ea573d6000803e3d6000fd5b50505050827f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd98958360405161122091815260200190565b60405180910390a2505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461129c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060006112ac868686611664565b92509250925082602001516000036112d0576112c88434611fb2565b505050505050565b604080516001808252818301909252600091816020015b6112ef6124a5565b8152602001906001900390816112e757505060408051608081019091529091508061131a888a612b3f565b8152602001858152602001848152602001838152508160008151811061134257611342612aa4565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff16036113b25761082d85826001600061179e565b61083c85826000600161179e565b6113c861150d565b6113d181612037565b50565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801590611432575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611469576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f14060f2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906314060f23906114df90869086908690600401612dc1565b600060405180830381600087803b1580156114f957600080fd5b505af115801561083c573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461158e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161095c565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526105fd9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261212c565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260003073ffffffffffffffffffffffffffffffffffffffff8516036116dd576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116eb86880188612eaf565b9150506000816116fa90612be2565b6040805160208101909152600081529091507e010000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000831614611781576000611762898b018b612f73565b955050505050508080602001905181019061177d919061303b565b9150505b61178c8784836109e1565b95509550955050505093509350939050565b60008267ffffffffffffffff8111156117b9576117b961277f565b6040519080825280602002602001820160405280156117fe57816020015b60408051808201909152600080825260208201528152602001906001900390816117d75790505b50905060008267ffffffffffffffff81111561181c5761181c61277f565b60405190808252806020026020018201604052801561186157816020015b604080518082019091526000808252602082015281526020019060019003908161183a5790505b509050600080808080611874888a612cfd565b905060005b81811015611bc3577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b82815181106118ca576118ca612aa4565b6020026020010151602001516000015173ffffffffffffffffffffffffffffffffffffffff16036119905760405180604001604052808c838151811061191257611912612aa4565b60200260200101516000015181526020018c838151811061193557611935612aa4565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff1681525088858061196e90612baa565b96508151811061198057611980612aa4565b6020026020010181905250611a85565b60405180604001604052808c83815181106119ad576119ad612aa4565b60200260200101516000015181526020018c83815181106119d0576119d0612aa4565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16815250878480611a0990612baa565b955081518110611a1b57611a1b612aa4565b60200260200101819052508a8181518110611a3857611a38612aa4565b6020026020010151602001516020015186611a539190612cfd565b95508a8181518110611a6757611a67612aa4565b6020026020010151604001516020015185611a829190612cfd565b94505b8a8181518110611a9757611a97612aa4565b602002602001015160600151600014611bb3578b73ffffffffffffffffffffffffffffffffffffffff168b8281518110611ad357611ad3612aa4565b6020026020010151600001517f88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e71258d8481518110611b1257611b12612aa4565b6020026020010151602001518e8581518110611b3057611b30612aa4565b6020026020010151604001518f8681518110611b4e57611b4e612aa4565b602002602001015160600151604051611baa93929190835173ffffffffffffffffffffffffffffffffffffffff908116825260209485015185830152835116604082015291909201516060820152608081019190915260a00190565b60405180910390a35b611bbc81612baa565b9050611879565b5060003415611c915734861115611c06576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c6e57600080fd5b505af1158015611c82573d6000803e3d6000fd5b50505050508534039050611cd9565b8515611cd957611cd973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168d3089612238565b875115611d6e577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b0d9fa19898e6040518363ffffffff1660e01b8152600401611d3b929190612d89565b600060405180830381600087803b158015611d5557600080fd5b505af1158015611d69573d6000803e3d6000fd5b505050505b865115611f9a576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611dff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e239190612d10565b851115611ef35760005b8751811015611eb657878181518110611e4857611e48612aa4565b60200260200101516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16600360008a8481518110611e8457611e84612aa4565b60209081029190910181015151825281019190915260400160002080549091019055611eaf81612baa565b9050611e2d565b507ff52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b6787604051611ee69190613069565b60405180910390a1611f9a565b6040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa1990611f67908a903090600401612d89565b600060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050505b611fa48c82611fb2565b505050505050505050505050565b8015611ffb5760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156105fd573d6000803e3d6000fd5b5050565b6000821561202d5781612013600185612cad565b61201d919061307c565b612028906001612cfd565b612030565b60005b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161095c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061218e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122969092919063ffffffff16565b8051909150156105fd57808060200190518101906121ac91906130b7565b6105fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161095c565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105459085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016115e2565b60606122a584846000856122ad565b949350505050565b60608247101561233f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161095c565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161236891906130d9565b60006040518083038185875af1925050503d80600081146123a5576040519150601f19603f3d011682016040523d82523d6000602084013e6123aa565b606091505b50915091506123bb878383876123c6565b979650505050505050565b6060831561245c5782516000036124555773ffffffffffffffffffffffffffffffffffffffff85163b612455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161095c565b50816122a5565b6122a583838151156124715781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095c91906125b1565b6040518060800160405280600080191681526020016124ed6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b81526020016125256040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001600081525090565b60006020828403121561254457600080fd5b5035919050565b60006020828403121561255d57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461203057600080fd5b60005b838110156125a8578181015183820152602001612590565b50506000910152565b60208152600082518060208401526125d081604085016020870161258d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff811681146113d157600080fd5b77ffffffffffffffffffffffffffffffffffffffffffffffff811681146113d157600080fd5b60008060006060848603121561265f57600080fd5b833561266a81612602565b9250602084013561267a81612602565b9150604084013561268a81612624565b809150509250925092565b6000806000604084860312156126aa57600080fd5b833567ffffffffffffffff808211156126c257600080fd5b818601915086601f8301126126d657600080fd5b8135818111156126e557600080fd5b8760208260051b85010111156126fa57600080fd5b6020928301955093505084013561268a81612602565b803567ffffffffffffffff8116811461272857600080fd5b919050565b60006020828403121561273f57600080fd5b61203082612710565b60008060006060848603121561275d57600080fd5b833561276881612602565b925060208401359150604084013561268a81612602565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810167ffffffffffffffff811182821017156127d1576127d161277f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561281e5761281e61277f565b604052919050565b600082601f83011261283757600080fd5b813567ffffffffffffffff8111156128515761285161277f565b61288260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127d7565b81815284602083860101111561289757600080fd5b816020850160208301376000918101602001919091529392505050565b600080600083850360608112156128ca57600080fd5b84356128d581612602565b9350602085013567ffffffffffffffff8111156128f157600080fd5b6128fd87828801612826565b93505060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08201121561293057600080fd5b506129396127ae565b604085013561294781612602565b815292959194509192509050565b6000806000806080858703121561296b57600080fd5b843561297681612602565b935060208501359250604085013561298d81612602565b915061299b60608601612710565b905092959194509250565b6000806000604084860312156129bb57600080fd5b833567ffffffffffffffff808211156129d357600080fd5b818601915086601f8301126129e757600080fd5b8135818111156129f657600080fd5b8760208285010111156126fa57600080fd5b600060208284031215612a1a57600080fd5b813561203081612602565b600080600060408486031215612a3a57600080fd5b83359250602084013567ffffffffffffffff80821115612a5957600080fd5b818601915086601f830112612a6d57600080fd5b813581811115612a7c57600080fd5b8760208260061b8501011115612a9157600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612b0857600080fd5b83018035915067ffffffffffffffff821115612b2357600080fd5b602001915036819003821315612b3857600080fd5b9250929050565b80356020831015610468577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612bdb57612bdb612b7b565b5060010190565b80516020808301519190811015612c21577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff8116811461272857600080fd5b60008060008060008060c08789031215612c5457600080fd5b86519550612c6460208801612c27565b9450612c7260408801612c27565b93506060870151612c8281612624565b6080880151909350612c9381612624565b9150612ca160a08801612c27565b90509295509295509295565b8181038181111561046857610468612b7b565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612cf857612cf8612b7b565b500290565b8082018082111561046857610468612b7b565b600060208284031215612d2257600080fd5b5051919050565b600081518084526020808501945080840160005b83811015612d7e5781518051885283015177ffffffffffffffffffffffffffffffffffffffffffffffff168388015260409096019590820190600101612d3d565b509495945050505050565b604081526000612d9c6040830185612d29565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b8381526040602080830182905282820184905260009190859060608501845b87811015612e34578335612df381612602565b73ffffffffffffffffffffffffffffffffffffffff16825267ffffffffffffffff612e1f858501612710565b16828401529284019290840190600101612de0565b5098975050505050505050565b600082601f830112612e5257600080fd5b6040516060810181811067ffffffffffffffff82111715612e7557612e7561277f565b604052806060840185811115612e8a57600080fd5b845b81811015612ea4578035835260209283019201612e8c565b509195945050505050565b60008060808385031215612ec257600080fd5b612ecc8484612e41565b9150606083013567ffffffffffffffff811115612ee857600080fd5b612ef485828601612826565b9150509250929050565b600082601f830112612f0f57600080fd5b8135602067ffffffffffffffff821115612f2b57612f2b61277f565b8160051b612f3a8282016127d7565b9283528481018201928281019087851115612f5457600080fd5b83870192505b848310156123bb57823582529183019190830190612f5a565b6000806000806000806101008789031215612f8d57600080fd5b612f978888612e41565b9550606087013567ffffffffffffffff80821115612fb457600080fd5b612fc08a838b01612826565b96506080890135915080821115612fd657600080fd5b612fe28a838b01612efe565b955060a0890135915080821115612ff857600080fd5b6130048a838b01612efe565b945060c0890135935060e089013591508082111561302157600080fd5b5061302e89828a01612826565b9150509295509295509295565b60006020828403121561304d57600080fd5b6130556127ae565b825161306081612602565b81529392505050565b6020815260006120306020830184612d29565b6000826130b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156130c957600080fd5b8151801515811461203057600080fd5b600082516130eb81846020870161258d565b919091019291505056fea164736f6c6343000810000a", } var FeeManagerABI = FeeManagerMetaData.ABI @@ -190,26 +190,27 @@ func (_FeeManager *FeeManagerTransactorRaw) Transact(opts *bind.TransactOpts, me return _FeeManager.Contract.contract.Transact(opts, method, params...) } -func (_FeeManager *FeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { +func (_FeeManager *FeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, *big.Int, error) { var out []interface{} err := _FeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quote) if err != nil { - return *new(CommonAsset), *new(CommonAsset), err + return *new(CommonAsset), *new(CommonAsset), *new(*big.Int), err } out0 := *abi.ConvertType(out[0], new(CommonAsset)).(*CommonAsset) out1 := *abi.ConvertType(out[1], new(CommonAsset)).(*CommonAsset) + out2 := *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - return out0, out1, err + return out0, out1, out2, err } -func (_FeeManager *FeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { +func (_FeeManager *FeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, *big.Int, error) { return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quote) } -func (_FeeManager *FeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { +func (_FeeManager *FeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, *big.Int, error) { return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quote) } @@ -463,16 +464,155 @@ func (_FeeManager *FeeManagerTransactorSession) UpdateSubscriberDiscount(subscri return _FeeManager.Contract.UpdateSubscriberDiscount(&_FeeManager.TransactOpts, subscriber, feedId, token, discount) } -func (_FeeManager *FeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { - return _FeeManager.contract.Transact(opts, "withdraw", assetAddress, quantity) +func (_FeeManager *FeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "withdraw", assetAddress, recipient, quantity) } -func (_FeeManager *FeeManagerSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { - return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, quantity) +func (_FeeManager *FeeManagerSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, recipient, quantity) } -func (_FeeManager *FeeManagerTransactorSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { - return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, quantity) +func (_FeeManager *FeeManagerTransactorSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, recipient, quantity) +} + +type FeeManagerDiscountAppliedIterator struct { + Event *FeeManagerDiscountApplied + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerDiscountAppliedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerDiscountApplied) + 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(FeeManagerDiscountApplied) + 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 *FeeManagerDiscountAppliedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerDiscountAppliedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerDiscountApplied struct { + ConfigDigest [32]byte + Subscriber common.Address + Fee CommonAsset + Reward CommonAsset + AppliedDiscount *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*FeeManagerDiscountAppliedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "DiscountApplied", configDigestRule, subscriberRule) + if err != nil { + return nil, err + } + return &FeeManagerDiscountAppliedIterator{contract: _FeeManager.contract, event: "DiscountApplied", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *FeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "DiscountApplied", configDigestRule, subscriberRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerDiscountApplied) + if err := _FeeManager.contract.UnpackLog(event, "DiscountApplied", 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 (_FeeManager *FeeManagerFilterer) ParseDiscountApplied(log types.Log) (*FeeManagerDiscountApplied, error) { + event := new(FeeManagerDiscountApplied) + if err := _FeeManager.contract.UnpackLog(event, "DiscountApplied", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } type FeeManagerInsufficientLinkIterator struct { @@ -1309,6 +1449,7 @@ func (it *FeeManagerWithdrawIterator) Close() error { type FeeManagerWithdraw struct { AdminAddress common.Address + Recipient common.Address AssetAddress common.Address Quantity *big.Int Raw types.Log @@ -1368,6 +1509,8 @@ func (_FeeManager *FeeManagerFilterer) ParseWithdraw(log types.Log) (*FeeManager func (_FeeManager *FeeManager) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { + case _FeeManager.abi.Events["DiscountApplied"].ID: + return _FeeManager.ParseDiscountApplied(log) case _FeeManager.abi.Events["InsufficientLink"].ID: return _FeeManager.ParseInsufficientLink(log) case _FeeManager.abi.Events["LinkDeficitCleared"].ID: @@ -1388,6 +1531,10 @@ func (_FeeManager *FeeManager) ParseLog(log types.Log) (generated.AbigenLog, err } } +func (FeeManagerDiscountApplied) Topic() common.Hash { + return common.HexToHash("0x88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e7125") +} + func (FeeManagerInsufficientLink) Topic() common.Hash { return common.HexToHash("0xf52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b67") } @@ -1413,7 +1560,7 @@ func (FeeManagerSubscriberDiscountUpdated) Topic() common.Hash { } func (FeeManagerWithdraw) Topic() common.Hash { - return common.HexToHash("0x72608e45b52a95a12c2ac7f15ff53f92fc9572c9d84b6e6b5d7f0f7826cf3271") + return common.HexToHash("0x7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f29") } func (_FeeManager *FeeManager) Address() common.Address { @@ -1421,7 +1568,7 @@ func (_FeeManager *FeeManager) Address() common.Address { } type FeeManagerInterface interface { - GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) + GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, *big.Int, error) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) @@ -1453,7 +1600,13 @@ type FeeManagerInterface interface { UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) - Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) + Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) + + FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*FeeManagerDiscountAppliedIterator, error) + + WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *FeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error) + + ParseDiscountApplied(log types.Log) (*FeeManagerDiscountApplied, error) FilterInsufficientLink(opts *bind.FilterOpts) (*FeeManagerInsufficientLinkIterator, error) diff --git a/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go b/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go index ed4c621842c..236eeaa5c1a 100644 --- a/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go +++ b/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go @@ -41,8 +41,8 @@ type IRewardManagerFeePayment struct { } var RewardManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"FeePaid\",\"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\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_rewardRecipientWeightsSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_totalRewardRecipientFeesLastClaimedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"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\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162002080380380620020808339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611e85620001fb60003960008181610ca70152610ee20152611e856000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806359256201116100b25780638ac85a5c11610081578063b0d9fa1911610066578063b0d9fa1914610377578063cd5f72921461038a578063f2fde38b1461039d57600080fd5b80638ac85a5c1461032e5780638da5cb5b1461035957600080fd5b806359256201146102b857806360122608146102db5780636992922f1461030657806379ba50971461032657600080fd5b8063276e766011610109578063472d35b9116100ee578063472d35b91461027f5780634944832f146102925780634d322084146102a557600080fd5b8063276e76601461020c57806339ee81e11461025157600080fd5b806301ffc9a71461013b5780630f3c34d1146101a557806314060f23146101ba578063181f5a77146101cd575b600080fd5b6101906101493660046117aa565b7fffffffff00000000000000000000000000000000000000000000000000000000167fb0d9fa19000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101b86101b336600461186a565b6103b0565b005b6101b86101c836600461195c565b6103be565b604080518082018252601381527f5265776172644d616e6167657220302e302e31000000000000000000000000006020820152905161019c91906119cc565b60075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b61027161025f366004611a1d565b60026020526000908152604090205481565b60405190815260200161019c565b6101b861028d366004611a5f565b610574565b6101b86102a036600461195c565b610642565b6101b86102b3366004611a81565b6107c4565b6101906102c6366004611a1d565b60056020526000908152604090205460ff1681565b6102716102e9366004611b00565b600360209081526000928352604080842090915290825290205481565b610319610314366004611a5f565b610903565b60405161019c9190611b2c565b6101b8610a34565b61027161033c366004611b00565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff1661022c565b6101b8610385366004611b70565b610b36565b610271610398366004611a1d565b610d10565b6101b86103ab366004611a5f565b610d31565b6103ba3382610d45565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906103fe575060075473ffffffffffffffffffffffffffffffffffffffff163314155b15610435576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819003610470576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff16156104b9576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055610535838383670de0b6b3a7640000610f12565b827f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68383604051610567929190611bdc565b60405180910390a2505050565b61057c611123565b73ffffffffffffffffffffffffffffffffffffffff81166105c9576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49060200160405180910390a150565b61064a611123565b60408051600180825281830190925260009160208083019080368337019050509050838160008151811061068057610680611c51565b6020026020010181815250506000805b838110156107765760008585838181106106ac576106ac611c51565b6106c29260206040909202019081019150611a5f565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205491925081900361072e576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075f87878581811061074357610743611c51565b6107599260206040909202019081019150611a5f565b86610d45565b5092909201915061076f81611caf565b9050610690565b5061078385858584610f12565b847f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe685856040516107b5929190611bdc565b60405180910390a25050505050565b826107e460005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415801561083657506000818152600460209081526040808320338452909152902054155b1561086d576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160018082528183019092526000916020808301908036833701905050905084816000815181106108a3576108a3611c51565b60200260200101818152505060005b838110156108fb576108ea8585838181106108cf576108cf611c51565b90506020020160208101906108e49190611a5f565b83610d45565b506108f481611caf565b90506108b2565b505050505050565b60065460609060008167ffffffffffffffff811115610924576109246117ec565b60405190808252806020026020018201604052801561094d578160200160208202803683370190505b5090506000805b83811015610a2a5760006006828154811061097157610971611c51565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8c16855290925291205490915015610a19576000818152600260209081526040808320546003835281842073ffffffffffffffffffffffffffffffffffffffff8c168552909252909120548114610a175781858580600101965081518110610a0a57610a0a611c51565b6020026020010181815250505b505b50610a2381611caf565b9050610954565b5090949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610b76575060075473ffffffffffffffffffffffffffffffffffffffff163314155b15610bad576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015610c8c57848482818110610bcb57610bcb611c51565b9050604002016020016020810190610be39190611d0f565b77ffffffffffffffffffffffffffffffffffffffffffffffff1660026000878785818110610c1357610c13611c51565b6040908102929092013583525060208201929092520160002080549091019055848482818110610c4557610c45611c51565b9050604002016020016020810190610c5d9190611d0f565b77ffffffffffffffffffffffffffffffffffffffffffffffff168201915080610c8590611caf565b9050610bb1565b50610ccf73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168330846111a6565b7fa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66848484604051610d0293929190611d2a565b60405180910390a150505050565b60068181548110610d2057600080fd5b600091825260209091200154905081565b610d39611123565b610d4281611288565b50565b60008060005b8351811015610ec1576000848281518110610d6857610d68611c51565b6020026020010151905060006002600083815260200190815260200160002054905080600003610d99575050610eb1565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16808552908352818420548685526004845282852091855292528220549083039190670de0b6b3a764000090830204905080600003610e025750505050610eb1565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d168085529252909120849055885196820196899087908110610e4d57610e4d611c51565b60200260200101517f989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef283604051610ea4919077ffffffffffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a3505050505b610eba81611caf565b9050610d4b565b508015610f0957610f0973ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016858361137d565b90505b92915050565b610f6d8383808060200260200160405190810160405280939291908181526020016000905b82821015610f6357610f5460408302860136819003810190611db1565b81526020019060010190610f37565b50505050506113d8565b15610fa4576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b838110156110e2576000858583818110610fc457610fc4611c51565b9050604002016020016020810190610fdc9190611e0c565b67ffffffffffffffff1690506000868684818110610ffc57610ffc611c51565b6110129260206040909202019081019150611a5f565b905073ffffffffffffffffffffffffffffffffffffffff8116611061576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160000361109b576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff90941683529290522081905591909101906110db81611caf565b9050610fa8565b5081811461111c576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146111a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610ab1565b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112829085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261148f565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611307576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610ab1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113d39084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611200565b505050565b6000805b82518110156114865760006113f2826001611e27565b90505b835181101561147d5783818151811061141057611410611c51565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1684838151811061144457611444611c51565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603611475575060019392505050565b6001016113f5565b506001016113dc565b50600092915050565b60006114f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661159b9092919063ffffffff16565b8051909150156113d3578080602001905181019061150f9190611e3a565b6113d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ab1565b60606115aa84846000856115b2565b949350505050565b606082471015611644576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ab1565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161166d9190611e5c565b60006040518083038185875af1925050503d80600081146116aa576040519150601f19603f3d011682016040523d82523d6000602084013e6116af565b606091505b50915091506116c0878383876116cb565b979650505050505050565b6060831561176157825160000361175a5773ffffffffffffffffffffffffffffffffffffffff85163b61175a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ab1565b50816115aa565b6115aa83838151156117765781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab191906119cc565b6000602082840312156117bc57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f0957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611862576118626117ec565b604052919050565b6000602080838503121561187d57600080fd5b823567ffffffffffffffff8082111561189557600080fd5b818501915085601f8301126118a957600080fd5b8135818111156118bb576118bb6117ec565b8060051b91506118cc84830161181b565b81815291830184019184810190888411156118e657600080fd5b938501935b83851015611904578435825293850193908501906118eb565b98975050505050505050565b60008083601f84011261192257600080fd5b50813567ffffffffffffffff81111561193a57600080fd5b6020830191508360208260061b850101111561195557600080fd5b9250929050565b60008060006040848603121561197157600080fd5b83359250602084013567ffffffffffffffff81111561198f57600080fd5b61199b86828701611910565b9497909650939450505050565b60005b838110156119c35781810151838201526020016119ab565b50506000910152565b60208152600082518060208401526119eb8160408501602087016119a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611a2f57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a5a57600080fd5b919050565b600060208284031215611a7157600080fd5b611a7a82611a36565b9392505050565b600080600060408486031215611a9657600080fd5b83359250602084013567ffffffffffffffff80821115611ab557600080fd5b818601915086601f830112611ac957600080fd5b813581811115611ad857600080fd5b8760208260051b8501011115611aed57600080fd5b6020830194508093505050509250925092565b60008060408385031215611b1357600080fd5b82359150611b2360208401611a36565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611b6457835183529284019291840191600101611b48565b50909695505050505050565b600080600060408486031215611b8557600080fd5b833567ffffffffffffffff811115611b9c57600080fd5b611ba886828701611910565b9094509250611bbb905060208501611a36565b90509250925092565b803567ffffffffffffffff81168114611a5a57600080fd5b6020808252818101839052600090604080840186845b87811015611c445773ffffffffffffffffffffffffffffffffffffffff611c1883611a36565b16835267ffffffffffffffff611c2f868401611bc4565b16838601529183019190830190600101611bf2565b5090979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ce057611ce0611c80565b5060010190565b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611a5a57600080fd5b600060208284031215611d2157600080fd5b611a7a82611ce7565b60408082528181018490526000908560608401835b87811015611d865782358252602077ffffffffffffffffffffffffffffffffffffffffffffffff611d71828601611ce7565b16908301529183019190830190600101611d3f565b5080935050505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060408284031215611dc357600080fd5b6040516040810181811067ffffffffffffffff82111715611de657611de66117ec565b604052611df283611a36565b8152611e0060208401611bc4565b60208201529392505050565b600060208284031215611e1e57600080fd5b611a7a82611bc4565b80820180821115610f0c57610f0c611c80565b600060208284031215611e4c57600080fd5b81518015158114610f0957600080fd5b60008251611e6e8184602087016119a8565b919091019291505056fea164736f6c6343000810000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"FeePaid\",\"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\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endIndex\",\"type\":\"uint256\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_rewardRecipientWeightsSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_totalRewardRecipientFeesLastClaimedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"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\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620020ec380380620020ec8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611ef1620001fb60003960008181610cda0152610f150152611ef16000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80634d322084116100b25780638ac85a5c11610081578063b0d9fa1911610066578063b0d9fa1914610377578063cd5f72921461038a578063f2fde38b1461039d57600080fd5b80638ac85a5c1461032e5780638da5cb5b1461035957600080fd5b80634d322084146102c557806359256201146102d857806360122608146102fb57806379ba50971461032657600080fd5b8063276e76601161010957806347226475116100ee578063472264751461027f578063472d35b91461029f5780634944832f146102b257600080fd5b8063276e76601461020c57806339ee81e11461025157600080fd5b806301ffc9a71461013b5780630f3c34d1146101a557806314060f23146101ba578063181f5a77146101cd575b600080fd5b6101906101493660046117dd565b7fffffffff00000000000000000000000000000000000000000000000000000000167fb0d9fa19000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101b86101b336600461189d565b6103b0565b005b6101b86101c836600461198f565b6103be565b604080518082018252601381527f5265776172644d616e6167657220312e302e30000000000000000000000000006020820152905161019c91906119ff565b60075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b61027161025f366004611a50565b60026020526000908152604090205481565b60405190815260200161019c565b61029261028d366004611a92565b610574565b60405161019c9190611ac5565b6101b86102ad366004611b09565b6106fe565b6101b86102c036600461198f565b6107cc565b6101b86102d3366004611b2b565b61094e565b6101906102e6366004611a50565b60056020526000908152604090205460ff1681565b610271610309366004611baa565b600360209081526000928352604080842090915290825290205481565b6101b8610a8d565b61027161033c366004611baa565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff1661022c565b6101b8610385366004611bd6565b610b8f565b610271610398366004611a50565b610d43565b6101b86103ab366004611b09565b610d64565b6103ba3382610d78565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906103fe575060075473ffffffffffffffffffffffffffffffffffffffff163314155b15610435576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819003610470576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff16156104b9576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055610535838383670de0b6b3a7640000610f45565b827f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68383604051610567929190611c42565b60405180910390a2505050565b6006546060906000818411610589578361058b565b815b9050808511156105c7576040517fa22caccc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105d38683611cd9565b67ffffffffffffffff8111156105eb576105eb61181f565b604051908082528060200260200182016040528015610614578160200160208202803683370190505b5090506000865b838110156106f15760006006828154811061063857610638611cec565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8f168552909252912054909150156106e0576000818152600260209081526040808320546003835281842073ffffffffffffffffffffffffffffffffffffffff8f1685529092529091205481146106de57818585806001019650815181106106d1576106d1611cec565b6020026020010181815250505b505b506106ea81611d1b565b905061061b565b5090979650505050505050565b610706611156565b73ffffffffffffffffffffffffffffffffffffffff8116610753576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49060200160405180910390a150565b6107d4611156565b60408051600180825281830190925260009160208083019080368337019050509050838160008151811061080a5761080a611cec565b6020026020010181815250506000805b8381101561090057600085858381811061083657610836611cec565b61084c9260206040909202019081019150611b09565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091528120549192508190036108b8576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108e98787858181106108cd576108cd611cec565b6108e39260206040909202019081019150611b09565b86610d78565b509290920191506108f981611d1b565b905061081a565b5061090d85858584610f45565b847f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe6858560405161093f929190611c42565b60405180910390a25050505050565b8261096e60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156109c057506000818152600460209081526040808320338452909152902054155b156109f7576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508481600081518110610a2d57610a2d611cec565b60200260200101818152505060005b83811015610a8557610a74858583818110610a5957610a59611cec565b9050602002016020810190610a6e9190611b09565b83610d78565b50610a7e81611d1b565b9050610a3c565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60075473ffffffffffffffffffffffffffffffffffffffff163314610be0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015610cbf57848482818110610bfe57610bfe611cec565b9050604002016020016020810190610c169190611d7b565b77ffffffffffffffffffffffffffffffffffffffffffffffff1660026000878785818110610c4657610c46611cec565b6040908102929092013583525060208201929092520160002080549091019055848482818110610c7857610c78611cec565b9050604002016020016020810190610c909190611d7b565b77ffffffffffffffffffffffffffffffffffffffffffffffff168201915080610cb890611d1b565b9050610be4565b50610d0273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168330846111d9565b7fa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66848484604051610d3593929190611d96565b60405180910390a150505050565b60068181548110610d5357600080fd5b600091825260209091200154905081565b610d6c611156565b610d75816112bb565b50565b60008060005b8351811015610ef4576000848281518110610d9b57610d9b611cec565b6020026020010151905060006002600083815260200190815260200160002054905080600003610dcc575050610ee4565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16808552908352818420548685526004845282852091855292528220549083039190670de0b6b3a764000090830204905080600003610e355750505050610ee4565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d168085529252909120849055885196820196899087908110610e8057610e80611cec565b60200260200101517f989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef283604051610ed7919077ffffffffffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a3505050505b610eed81611d1b565b9050610d7e565b508015610f3c57610f3c73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685836113b0565b90505b92915050565b610fa08383808060200260200160405190810160405280939291908181526020016000905b82821015610f9657610f8760408302860136819003810190611e1d565b81526020019060010190610f6a565b505050505061140b565b15610fd7576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015611115576000858583818110610ff757610ff7611cec565b905060400201602001602081019061100f9190611e78565b67ffffffffffffffff169050600086868481811061102f5761102f611cec565b6110459260206040909202019081019150611b09565b905073ffffffffffffffffffffffffffffffffffffffff8116611094576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000036110ce576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff909416835292905220819055919091019061110e81611d1b565b9050610fdb565b5081811461114f576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146111d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b0a565b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112b59085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114c2565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b0a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114069084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611233565b505050565b6000805b82518110156114b9576000611425826001611e93565b90505b83518110156114b05783818151811061144357611443611cec565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1684838151811061147757611477611cec565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036114a8575060019392505050565b600101611428565b5060010161140f565b50600092915050565b6000611524826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115ce9092919063ffffffff16565b80519091501561140657808060200190518101906115429190611ea6565b611406576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0a565b60606115dd84846000856115e5565b949350505050565b606082471015611677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0a565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516116a09190611ec8565b60006040518083038185875af1925050503d80600081146116dd576040519150601f19603f3d011682016040523d82523d6000602084013e6116e2565b606091505b50915091506116f3878383876116fe565b979650505050505050565b6060831561179457825160000361178d5773ffffffffffffffffffffffffffffffffffffffff85163b61178d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0a565b50816115dd565b6115dd83838151156117a95781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0a91906119ff565b6000602082840312156117ef57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f3c57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156118955761189561181f565b604052919050565b600060208083850312156118b057600080fd5b823567ffffffffffffffff808211156118c857600080fd5b818501915085601f8301126118dc57600080fd5b8135818111156118ee576118ee61181f565b8060051b91506118ff84830161184e565b818152918301840191848101908884111561191957600080fd5b938501935b838510156119375784358252938501939085019061191e565b98975050505050505050565b60008083601f84011261195557600080fd5b50813567ffffffffffffffff81111561196d57600080fd5b6020830191508360208260061b850101111561198857600080fd5b9250929050565b6000806000604084860312156119a457600080fd5b83359250602084013567ffffffffffffffff8111156119c257600080fd5b6119ce86828701611943565b9497909650939450505050565b60005b838110156119f65781810151838201526020016119de565b50506000910152565b6020815260008251806020840152611a1e8160408501602087016119db565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611a6257600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a8d57600080fd5b919050565b600080600060608486031215611aa757600080fd5b611ab084611a69565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611afd57835183529284019291840191600101611ae1565b50909695505050505050565b600060208284031215611b1b57600080fd5b611b2482611a69565b9392505050565b600080600060408486031215611b4057600080fd5b83359250602084013567ffffffffffffffff80821115611b5f57600080fd5b818601915086601f830112611b7357600080fd5b813581811115611b8257600080fd5b8760208260051b8501011115611b9757600080fd5b6020830194508093505050509250925092565b60008060408385031215611bbd57600080fd5b82359150611bcd60208401611a69565b90509250929050565b600080600060408486031215611beb57600080fd5b833567ffffffffffffffff811115611c0257600080fd5b611c0e86828701611943565b9094509250611c21905060208501611a69565b90509250925092565b803567ffffffffffffffff81168114611a8d57600080fd5b6020808252818101839052600090604080840186845b878110156106f15773ffffffffffffffffffffffffffffffffffffffff611c7e83611a69565b16835267ffffffffffffffff611c95868401611c2a565b16838601529183019190830190600101611c58565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610f3f57610f3f611caa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d4c57611d4c611caa565b5060010190565b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611a8d57600080fd5b600060208284031215611d8d57600080fd5b611b2482611d53565b60408082528181018490526000908560608401835b87811015611df25782358252602077ffffffffffffffffffffffffffffffffffffffffffffffff611ddd828601611d53565b16908301529183019190830190600101611dab565b5080935050505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060408284031215611e2f57600080fd5b6040516040810181811067ffffffffffffffff82111715611e5257611e5261181f565b604052611e5e83611a69565b8152611e6c60208401611c2a565b60208201529392505050565b600060208284031215611e8a57600080fd5b611b2482611c2a565b80820180821115610f3f57610f3f611caa565b600060208284031215611eb857600080fd5b81518015158114610f3c57600080fd5b60008251611eda8184602087016119db565b919091019291505056fea164736f6c6343000810000a", } var RewardManagerABI = RewardManagerMetaData.ABI @@ -181,9 +181,9 @@ func (_RewardManager *RewardManagerTransactorRaw) Transact(opts *bind.TransactOp return _RewardManager.Contract.contract.Transact(opts, method, params...) } -func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address) ([][32]byte, error) { +func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { var out []interface{} - err := _RewardManager.contract.Call(opts, &out, "getAvailableRewardPoolIds", recipient) + err := _RewardManager.contract.Call(opts, &out, "getAvailableRewardPoolIds", recipient, startIndex, endIndex) if err != nil { return *new([][32]byte), err @@ -195,12 +195,12 @@ func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind. } -func (_RewardManager *RewardManagerSession) GetAvailableRewardPoolIds(recipient common.Address) ([][32]byte, error) { - return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient) +func (_RewardManager *RewardManagerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient, startIndex, endIndex) } -func (_RewardManager *RewardManagerCallerSession) GetAvailableRewardPoolIds(recipient common.Address) ([][32]byte, error) { - return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient) +func (_RewardManager *RewardManagerCallerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient, startIndex, endIndex) } func (_RewardManager *RewardManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { @@ -425,16 +425,16 @@ func (_RewardManager *RewardManagerTransactorSession) ClaimRewards(poolIds [][32 return _RewardManager.Contract.ClaimRewards(&_RewardManager.TransactOpts, poolIds) } -func (_RewardManager *RewardManagerTransactor) OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payee common.Address) (*types.Transaction, error) { - return _RewardManager.contract.Transact(opts, "onFeePaid", payments, payee) +func (_RewardManager *RewardManagerTransactor) OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "onFeePaid", payments, payer) } -func (_RewardManager *RewardManagerSession) OnFeePaid(payments []IRewardManagerFeePayment, payee common.Address) (*types.Transaction, error) { - return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payee) +func (_RewardManager *RewardManagerSession) OnFeePaid(payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payer) } -func (_RewardManager *RewardManagerTransactorSession) OnFeePaid(payments []IRewardManagerFeePayment, payee common.Address) (*types.Transaction, error) { - return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payee) +func (_RewardManager *RewardManagerTransactorSession) OnFeePaid(payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payer) } func (_RewardManager *RewardManagerTransactor) PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { @@ -676,7 +676,7 @@ func (it *RewardManagerFeePaidIterator) Close() error { type RewardManagerFeePaid struct { Payments []IRewardManagerFeePayment - Payee common.Address + Payer common.Address Raw types.Log } @@ -1318,7 +1318,7 @@ func (_RewardManager *RewardManager) Address() common.Address { } type RewardManagerInterface interface { - GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address) ([][32]byte, error) + GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) Owner(opts *bind.CallOpts) (common.Address, error) @@ -1342,7 +1342,7 @@ type RewardManagerInterface interface { ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error) - OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payee common.Address) (*types.Transaction, error) + OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go b/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go index 77e76dfd70b..12e5e28948e 100644 --- a/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go +++ b/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go @@ -36,8 +36,8 @@ type CommonAddressAndWeight struct { } var VerifierProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"VerifierAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"VerifierNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"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\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"oldConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierUnset\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getVerifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"initializeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"currentConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"addressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setVerifier\",\"outputs\":[],\"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\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"unsetVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifiedReport\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"verifiedReports\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162001ac538038062001ac5833981016040819052620000349162000193565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050600480546001600160a01b0319166001600160a01b03939093169290921790915550620001c5565b336001600160a01b03821603620001425760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001a657600080fd5b81516001600160a01b0381168114620001be57600080fd5b9392505050565b6118f080620001d56000396000f3fe6080604052600436106100dd5760003560e01c80638da5cb5b1161007f578063b011b24711610059578063b011b2471461028e578063eeb7b248146102ae578063f08391d8146102f1578063f2fde38b1461031157600080fd5b80638da5cb5b146102235780638e760afe1461024e57806394ba28461461026157600080fd5b80636e914094116100bb5780636e914094146101ae57806379ba5097146101ce57806383490cd7146101e35780638c2a4d531461020357600080fd5b8063181f5a77146100e257806338416b5b1461013a578063472d35b91461018c575b600080fd5b3480156100ee57600080fd5b5060408051808201909152601381527f566572696669657250726f787920312e312e300000000000000000000000000060208201525b6040516101319190611216565b60405180910390f35b34801561014657600080fd5b506005546101679073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610131565b34801561019857600080fd5b506101ac6101a7366004611252565b610331565b005b3480156101ba57600080fd5b506101ac6101c936600461126f565b61040d565b3480156101da57600080fd5b506101ac6104fe565b6101f66101f1366004611288565b6105fb565b60405161013191906112fd565b34801561020f57600080fd5b506101ac61021e366004611252565b610859565b34801561022f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610167565b61012461025c36600461137d565b610a8a565b34801561026d57600080fd5b506004546101679073ffffffffffffffffffffffffffffffffffffffff1681565b34801561029a57600080fd5b506101ac6102a93660046113dd565b610c3e565b3480156102ba57600080fd5b506101676102c936600461126f565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156102fd57600080fd5b506101ac61030c366004611252565b610e64565b34801561031d57600080fd5b506101ac61032c366004611252565b610eeb565b610339610eff565b73ffffffffffffffffffffffffffffffffffffffff8116610386576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b610415610eff565b60008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610479576040517fb151802b000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b6000828152600360205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c90610401908490849091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60015473ffffffffffffffffffffffffffffffffffffffff16331461057f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610470565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60045460609073ffffffffffffffffffffffffffffffffffffffff1680158015906106bb57506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf89061067890339060009036906004016114a9565b602060405180830381865afa158015610695573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b991906114d9565b155b156106f2576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff16801561079c576040517f40d7f78e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906340d7f78e903490610769908990899033906004016114fb565b6000604051808303818588803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b50505050505b8367ffffffffffffffff8111156107b5576107b56115f0565b6040519080825280602002602001820160405280156107e857816020015b60608152602001906001900390816107d35790505b50925060005b848110156108505761082286868381811061080b5761080b61161f565b905060200281019061081d919061164e565b610f82565b8482815181106108345761083461161f565b602002602001018190525080610849906116ba565b90506107ee565b50505092915050565b610861610eff565b8073ffffffffffffffffffffffffffffffffffffffff81166108af576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3d3ac1b500000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610939573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095d91906114d9565b610993576040517f75b0527a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff1615610a0b576040517f4e01ccfd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610470565b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e99101610401565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610b4a57506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610b0790339060009036906004016114a9565b602060405180830381865afa158015610b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4891906114d9565b155b15610b81576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff168015610c2b576040517ff1387e1600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063f1387e16903490610bf890899089903390600401611719565b6000604051808303818588803b158015610c1157600080fd5b505af1158015610c25573d6000803e3d6000fd5b50505050505b610c358585610f82565b95945050505050565b600083815260036020526040902054839073ffffffffffffffffffffffffffffffffffffffff168015610cbc576040517f375d1fe60000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff82166024820152604401610470565b3360009081526002602052604090205460ff16610d05576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260036020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790558215610e1d5760055473ffffffffffffffffffffffffffffffffffffffff16610d90576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517ff65df96200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f65df96290610dea90889088908890600401611753565b600060405180830381600087803b158015610e0457600080fd5b505af1158015610e18573d6000803e3d6000fd5b505050505b6040805187815260208101879052338183015290517fbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf9181900360600190a1505050505050565b610e6c610eff565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b69101610401565b610ef3610eff565b610efc816110b3565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610470565b565b60606000610f9083856117dc565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff1680610ff2576040517fb151802b00000000000000000000000000000000000000000000000000000000815260048101839052602401610470565b6040517f3d3ac1b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690633d3ac1b59061104890889088903390600401611719565b6000604051808303816000875af1158015611067573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c359190810190611818565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611132576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610470565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b838110156111c35781810151838201526020016111ab565b50506000910152565b600081518084526111e48160208601602086016111a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061122960208301846111cc565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610efc57600080fd5b60006020828403121561126457600080fd5b813561122981611230565b60006020828403121561128157600080fd5b5035919050565b6000806020838503121561129b57600080fd5b823567ffffffffffffffff808211156112b357600080fd5b818501915085601f8301126112c757600080fd5b8135818111156112d657600080fd5b8660208260051b85010111156112eb57600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611370577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261135e8583516111cc565b94509285019290850190600101611324565b5092979650505050505050565b6000806020838503121561139057600080fd5b823567ffffffffffffffff808211156113a857600080fd5b818501915085601f8301126113bc57600080fd5b8135818111156113cb57600080fd5b8660208285010111156112eb57600080fd5b600080600080606085870312156113f357600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561141957600080fd5b818701915087601f83011261142d57600080fd5b81358181111561143c57600080fd5b8860208260061b850101111561145157600080fd5b95989497505060200194505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff84168152604060208201526000610c35604083018486611460565b6000602082840312156114eb57600080fd5b8151801515811461122957600080fd5b6040808252810183905260006060600585901b8301810190830186835b878110156115c7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa086850301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18a360301811261157957600080fd5b8901602081810191359067ffffffffffffffff82111561159857600080fd5b8136038313156115a757600080fd5b6115b2878385611460565b96509485019493909301925050600101611518565b50505073ffffffffffffffffffffffffffffffffffffffff841660208401529050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261168357600080fd5b83018035915067ffffffffffffffff82111561169e57600080fd5b6020019150368190038213156116b357600080fd5b9250929050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611712577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60408152600061172d604083018587611460565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b838152604060208083018290528282018490526000919085906060850184805b888110156117cd57843561178681611230565b73ffffffffffffffffffffffffffffffffffffffff1683528484013567ffffffffffffffff81168082146117b8578384fd5b84860152509385019391850191600101611773565b50909998505050505050505050565b803560208310156110ad577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b60006020828403121561182a57600080fd5b815167ffffffffffffffff8082111561184257600080fd5b818401915084601f83011261185657600080fd5b815181811115611868576118686115f0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156118ae576118ae6115f0565b816040528281528760208487010111156118c757600080fd5b6118d88360208301602088016111a8565b97965050505050505056fea164736f6c6343000810000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeManagerInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"VerifierAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"VerifierNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"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\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"oldConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierUnset\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getVerifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"initializeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"currentConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"addressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setVerifier\",\"outputs\":[],\"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\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"unsetVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"verifiedReports\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162001c6138038062001c61833981016040819052620000349162000193565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050600480546001600160a01b0319166001600160a01b03939093169290921790915550620001c5565b336001600160a01b03821603620001425760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001a657600080fd5b81516001600160a01b0381168114620001be57600080fd5b9392505050565b611a8c80620001d56000396000f3fe6080604052600436106100dd5760003560e01c80638da5cb5b1161007f578063b011b24711610059578063b011b2471461028e578063eeb7b248146102ae578063f08391d8146102f1578063f2fde38b1461031157600080fd5b80638da5cb5b146102235780638e760afe1461024e57806394ba28461461026157600080fd5b80636e914094116100bb5780636e914094146101ae57806379ba5097146101ce57806383490cd7146101e35780638c2a4d531461020357600080fd5b8063181f5a77146100e257806338416b5b1461013a578063472d35b91461018c575b600080fd5b3480156100ee57600080fd5b5060408051808201909152601381527f566572696669657250726f787920312e312e300000000000000000000000000060208201525b60405161013191906113b2565b60405180910390f35b34801561014657600080fd5b506005546101679073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610131565b34801561019857600080fd5b506101ac6101a73660046113ee565b610331565b005b3480156101ba57600080fd5b506101ac6101c936600461140b565b6105a9565b3480156101da57600080fd5b506101ac61069a565b6101f66101f1366004611424565b610797565b6040516101319190611499565b34801561020f57600080fd5b506101ac61021e3660046113ee565b6109f5565b34801561022f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610167565b61012461025c366004611519565b610c26565b34801561026d57600080fd5b506004546101679073ffffffffffffffffffffffffffffffffffffffff1681565b34801561029a57600080fd5b506101ac6102a9366004611579565b610dda565b3480156102ba57600080fd5b506101676102c936600461140b565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156102fd57600080fd5b506101ac61030c3660046113ee565b611000565b34801561031d57600080fd5b506101ac61032c3660046113ee565b611087565b61033961109b565b73ffffffffffffffffffffffffffffffffffffffff8116610386576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527ff1387e1600000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610410573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043491906115fc565b15806104eb57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f40d7f78e00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e991906115fc565b155b15610522576040517f8238941900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b6105b161109b565b60008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610615576040517fb151802b000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b6000828152600360205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c9061059d908490849091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60015473ffffffffffffffffffffffffffffffffffffffff16331461071b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161060c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60045460609073ffffffffffffffffffffffffffffffffffffffff16801580159061085757506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf8906108149033906000903690600401611667565b602060405180830381865afa158015610831573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085591906115fc565b155b1561088e576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff168015610938576040517f40d7f78e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906340d7f78e90349061090590899089903390600401611697565b6000604051808303818588803b15801561091e57600080fd5b505af1158015610932573d6000803e3d6000fd5b50505050505b8367ffffffffffffffff8111156109515761095161178c565b60405190808252806020026020018201604052801561098457816020015b606081526020019060019003908161096f5790505b50925060005b848110156109ec576109be8686838181106109a7576109a76117bb565b90506020028101906109b991906117ea565b61111e565b8482815181106109d0576109d06117bb565b6020026020010181905250806109e590611856565b905061098a565b50505092915050565b6109fd61109b565b8073ffffffffffffffffffffffffffffffffffffffff8116610a4b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3d3ac1b500000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af991906115fc565b610b2f576040517f75b0527a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff1615610ba7576040517f4e01ccfd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161060c565b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e9910161059d565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610ce657506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610ca39033906000903690600401611667565b602060405180830381865afa158015610cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce491906115fc565b155b15610d1d576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff168015610dc7576040517ff1387e1600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063f1387e16903490610d94908990899033906004016118b5565b6000604051808303818588803b158015610dad57600080fd5b505af1158015610dc1573d6000803e3d6000fd5b50505050505b610dd1858561111e565b95945050505050565b600083815260036020526040902054839073ffffffffffffffffffffffffffffffffffffffff168015610e58576040517f375d1fe60000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161060c565b3360009081526002602052604090205460ff16610ea1576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260036020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790558215610fb95760055473ffffffffffffffffffffffffffffffffffffffff16610f2c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517ff65df96200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f65df96290610f86908890889088906004016118ef565b600060405180830381600087803b158015610fa057600080fd5b505af1158015610fb4573d6000803e3d6000fd5b505050505b6040805187815260208101879052338183015290517fbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf9181900360600190a1505050505050565b61100861109b565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6910161059d565b61108f61109b565b6110988161124f565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461111c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161060c565b565b6060600061112c8385611978565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff168061118e576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161060c565b6040517f3d3ac1b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690633d3ac1b5906111e4908890889033906004016118b5565b6000604051808303816000875af1158015611203573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610dd191908101906119b4565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff8216036112ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161060c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8381101561135f578181015183820152602001611347565b50506000910152565b60008151808452611380816020860160208601611344565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006113c56020830184611368565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461109857600080fd5b60006020828403121561140057600080fd5b81356113c5816113cc565b60006020828403121561141d57600080fd5b5035919050565b6000806020838503121561143757600080fd5b823567ffffffffffffffff8082111561144f57600080fd5b818501915085601f83011261146357600080fd5b81358181111561147257600080fd5b8660208260051b850101111561148757600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561150c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526114fa858351611368565b945092850192908501906001016114c0565b5092979650505050505050565b6000806020838503121561152c57600080fd5b823567ffffffffffffffff8082111561154457600080fd5b818501915085601f83011261155857600080fd5b81358181111561156757600080fd5b86602082850101111561148757600080fd5b6000806000806060858703121561158f57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156115b557600080fd5b818701915087601f8301126115c957600080fd5b8135818111156115d857600080fd5b8860208260061b85010111156115ed57600080fd5b95989497505060200194505050565b60006020828403121561160e57600080fd5b815180151581146113c557600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff84168152604060208201526000610dd160408301848661161e565b6040808252810183905260006060600585901b8301810190830186835b87811015611763577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa086850301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18a360301811261171557600080fd5b8901602081810191359067ffffffffffffffff82111561173457600080fd5b81360383131561174357600080fd5b61174e87838561161e565b965094850194939093019250506001016116b4565b50505073ffffffffffffffffffffffffffffffffffffffff841660208401529050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261181f57600080fd5b83018035915067ffffffffffffffff82111561183a57600080fd5b60200191503681900382131561184f57600080fd5b9250929050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036118ae577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b6040815260006118c960408301858761161e565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b838152604060208083018290528282018490526000919085906060850184805b88811015611969578435611922816113cc565b73ffffffffffffffffffffffffffffffffffffffff1683528484013567ffffffffffffffff8116808214611954578384fd5b8486015250938501939185019160010161190f565b50909998505050505050505050565b80356020831015611249577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b6000602082840312156119c657600080fd5b815167ffffffffffffffff808211156119de57600080fd5b818401915084601f8301126119f257600080fd5b815181811115611a0457611a0461178c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611a4a57611a4a61178c565b81604052828152876020848701011115611a6357600080fd5b611a74836020830160208801611344565b97965050505050505056fea164736f6c6343000810000a", } var VerifierProxyABI = VerifierProxyMetaData.ABI 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 a082c254c02..284e9886f3e 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,9 +1,9 @@ GETH_VERSION: 1.12.0 errored_verifier: ../../../contracts/solc/v0.8.16/ErroredVerifier.abi ../../../contracts/solc/v0.8.16/ErroredVerifier.bin a1b88979c6b0b210677346df554ffc33992d6ebe24be5a244475bfb4d153155e exposed_verifier: ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 -fee_manager: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin bdae30fb942324e29ea99513fe1aadb705152bf5ac3dd411e8f31d24d99b7bc8 +fee_manager: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin 2c22cbfb24374f645eef8a368f30d1821e350501742118eebd0fa3e8bcbc4d29 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 -reward_manager: ../../../contracts/solc/v0.8.16/RewardManager.abi ../../../contracts/solc/v0.8.16/RewardManager.bin 87ff86cc1e15b9f291b6cdc8e1cc2d884f49d0555a03e1ab3da5bbfeaa0273fd +reward_manager: ../../../contracts/solc/v0.8.16/RewardManager.abi ../../../contracts/solc/v0.8.16/RewardManager.bin 8b163eb0537180accfa69beea298890f1605c8d9f776689ea26802eefda46457 verifier: ../../../contracts/solc/v0.8.16/Verifier.abi ../../../contracts/solc/v0.8.16/Verifier.bin 8f841ddd5e616fc1a8d6ac3d27ea9a383d958055237c90ecaf980f5cb3421e49 -verifier_proxy: ../../../contracts/solc/v0.8.16/VerifierProxy.abi ../../../contracts/solc/v0.8.16/VerifierProxy.bin ffe46f650ac7e8389102596339fb060d5ca5b695efc462cae031dc1f102d2571 +verifier_proxy: ../../../contracts/solc/v0.8.16/VerifierProxy.abi ../../../contracts/solc/v0.8.16/VerifierProxy.bin 92ad0416e999e9d55e4f00a8b7df616bb69ae27ce52994a6061598e95364d2cc From da3e6116efda903c4a861788a290d7dc1e963773 Mon Sep 17 00:00:00 2001 From: Chris Cushman <104409744+vreff@users.noreply.github.com> Date: Wed, 6 Sep 2023 11:44:23 -0400 Subject: [PATCH 29/88] [VRF] opt out of snapshot checks (#10491) * [VRF] opt out of snapshot checks * Change VRF snapshot by 1 * Remove snapshot file --- .github/workflows/solidity-foundry.yml | 1 + contracts/gas-snapshots/vrf.gas-snapshot | 18 ------------------ 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 contracts/gas-snapshots/vrf.gas-snapshot diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index abdb64d1763..5044b668c2c 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -72,6 +72,7 @@ jobs: FOUNDRY_PROFILE: ${{ matrix.product }} - name: Run Forge snapshot + if: ${{ !contains(fromJson('["vrf"]'), matrix.product) }} run: | forge snapshot --check gas-snapshots/${{ matrix.product }}.gas-snapshot id: snapshot diff --git a/contracts/gas-snapshots/vrf.gas-snapshot b/contracts/gas-snapshots/vrf.gas-snapshot deleted file mode 100644 index 44145caadaa..00000000000 --- a/contracts/gas-snapshots/vrf.gas-snapshot +++ /dev/null @@ -1,18 +0,0 @@ -TrustedBlockhashStoreTest:testGenericBHSFunctions() (gas: 53507) -TrustedBlockhashStoreTest:testTrustedBHSFunctions() (gas: 54617) -VRFCoordinatorV2Plus_Migration:testDeregister() (gas: 101083) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCaller() (gas: 33190) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCoordinator() (gas: 19877) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenPendingFulfillment() (gas: 237679) -VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenReentrant() (gas: 357765) -VRFCoordinatorV2Plus_Migration:testMigration() (gas: 471605) -VRFCoordinatorV2Plus_Migration:testMigrationNoLink() (gas: 431075) -VRFV2Plus:testCancelSubWithNoLink() (gas: 160279) -VRFV2Plus:testCreateSubscription() (gas: 181127) -VRFV2Plus:testGetActiveSubscriptionIds() (gas: 3453681) -VRFV2Plus:testRegisterProvingKey() (gas: 101085) -VRFV2Plus:testRequestAndFulfillRandomWordsLINK() (gas: 755144) -VRFV2Plus:testRequestAndFulfillRandomWordsNative() (gas: 705591) -VRFV2Plus:testSetConfig() (gas: 73032) -VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsLINKWrapper() (gas: 393885) -VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsNativeWrapper() (gas: 294434) \ No newline at end of file From a53b972206cdfdb800c628b2296892e820c3eb85 Mon Sep 17 00:00:00 2001 From: krehermann Date: Wed, 6 Sep 2023 10:31:41 -0600 Subject: [PATCH 30/88] BCF-2564: take new loop relayer interface (#10430) * BCF-2564: take new loop relayer interface * take merged sha in relayer repo * fix solana --- core/chains/chain_kv_test.go | 2 +- core/chains/cosmos/chain.go | 4 - core/chains/cosmos/relay_extender.go | 85 -------- core/chains/cosmos/relayer_adapter.go | 51 +++++ core/chains/evm/mocks/chain.go | 14 -- core/chains/solana/chain.go | 4 +- core/chains/solana/relay_extender.go | 40 ---- core/chains/starknet/relay_extender.go | 43 ----- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- .../chainlink/relayer_chain_interoperators.go | 23 ++- core/services/chainlink/relayer_factory.go | 12 +- .../relay/evm/mocks/loop_relay_adapter.go | 181 +++++++----------- core/services/relay/evm/relayer_extender.go | 4 - core/web/solana_transfer_controller.go | 5 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- plugins/cmd/chainlink-solana/main.go | 4 +- plugins/cmd/chainlink-starknet/main.go | 4 +- 21 files changed, 160 insertions(+), 334 deletions(-) delete mode 100644 core/chains/cosmos/relay_extender.go create mode 100644 core/chains/cosmos/relayer_adapter.go delete mode 100644 core/chains/solana/relay_extender.go delete mode 100644 core/chains/starknet/relay_extender.go diff --git a/core/chains/chain_kv_test.go b/core/chains/chain_kv_test.go index e8b8f6c0ab4..f226b6f38be 100644 --- a/core/chains/chain_kv_test.go +++ b/core/chains/chain_kv_test.go @@ -94,7 +94,7 @@ func (s *testChainService) HealthReport() map[string]error { func (s *testChainService) GetChainStatus(ctx context.Context) (stat types.ChainStatus, err error) { return } -func (s *testChainService) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, err error) { +func (s *testChainService) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) { return } diff --git a/core/chains/cosmos/chain.go b/core/chains/cosmos/chain.go index c73793c1c3a..48f4c2f8854 100644 --- a/core/chains/cosmos/chain.go +++ b/core/chains/cosmos/chain.go @@ -239,10 +239,6 @@ func (c *chain) Transact(ctx context.Context, from, to string, amount *big.Int, return chains.ErrLOOPPUnsupported } -func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { - return c.Transact(ctx, from, to, amount, balanceCheck) -} - // TODO BCF-2602 statuses are static for non-evm chain and should be dynamic func (c *chain) listNodeStatuses(start, end int) ([]relaytypes.NodeStatus, int, error) { stats := make([]relaytypes.NodeStatus, 0) diff --git a/core/chains/cosmos/relay_extender.go b/core/chains/cosmos/relay_extender.go deleted file mode 100644 index 3f9b9f5ad5b..00000000000 --- a/core/chains/cosmos/relay_extender.go +++ /dev/null @@ -1,85 +0,0 @@ -package cosmos - -import ( - "context" - "fmt" - "math/big" - - "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters" - - "github.com/smartcontractkit/chainlink-relay/pkg/loop" - relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" - - pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" - "github.com/smartcontractkit/chainlink/v2/core/chains" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" -) - -// LegacyChainContainer is container interface for Cosmos chains -type LegacyChainContainer interface { - Get(id string) (adapters.Chain, error) - Len() int - List(ids ...string) ([]adapters.Chain, error) - Slice() []adapters.Chain -} - -type LegacyChains = chains.ChainsKV[adapters.Chain] - -var _ LegacyChainContainer = &LegacyChains{} - -func NewLegacyChains(m map[string]adapters.Chain) *LegacyChains { - return chains.NewChainsKV[adapters.Chain](m) -} - -type LoopRelayerChainer interface { - loop.Relayer - Chain() adapters.Chain -} - -type LoopRelayerChain struct { - loop.Relayer - chain adapters.Chain -} - -func NewLoopRelayerChain(r *pkgcosmos.Relayer, s *RelayExtender) *LoopRelayerChain { - - ra := relay.NewRelayerAdapter(r, s) - return &LoopRelayerChain{ - Relayer: ra, - chain: s, - } -} -func (r *LoopRelayerChain) Chain() adapters.Chain { - return r.chain -} - -var _ LoopRelayerChainer = &LoopRelayerChain{} - -// TODO remove these wrappers after BCF-2441 -type RelayExtender struct { - adapters.Chain - chainImpl *chain -} - -var _ relay.RelayerExt = &RelayExtender{} - -func NewRelayExtender(cfg *CosmosConfig, opts ChainOpts) (*RelayExtender, error) { - c, err := NewChain(cfg, opts) - if err != nil { - return nil, err - } - chainImpl, ok := (c).(*chain) - if !ok { - return nil, fmt.Errorf("internal error: cosmos relay extender got wrong type %t", c) - } - return &RelayExtender{Chain: chainImpl, chainImpl: chainImpl}, nil -} -func (r *RelayExtender) GetChainStatus(ctx context.Context) (relaytypes.ChainStatus, error) { - return r.chainImpl.GetChainStatus(ctx) -} -func (r *RelayExtender) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []relaytypes.NodeStatus, nextPageToken string, total int, err error) { - return r.chainImpl.ListNodeStatuses(ctx, pageSize, pageToken) -} -func (r *RelayExtender) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { - return chains.ErrLOOPPUnsupported -} diff --git a/core/chains/cosmos/relayer_adapter.go b/core/chains/cosmos/relayer_adapter.go new file mode 100644 index 00000000000..899eae01951 --- /dev/null +++ b/core/chains/cosmos/relayer_adapter.go @@ -0,0 +1,51 @@ +package cosmos + +import ( + "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters" + + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + + pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" + "github.com/smartcontractkit/chainlink/v2/core/chains" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +// LegacyChainContainer is container interface for Cosmos chains +type LegacyChainContainer interface { + Get(id string) (adapters.Chain, error) + Len() int + List(ids ...string) ([]adapters.Chain, error) + Slice() []adapters.Chain +} + +type LegacyChains = chains.ChainsKV[adapters.Chain] + +var _ LegacyChainContainer = &LegacyChains{} + +func NewLegacyChains(m map[string]adapters.Chain) *LegacyChains { + return chains.NewChainsKV[adapters.Chain](m) +} + +type LoopRelayerChainer interface { + loop.Relayer + Chain() adapters.Chain +} + +type LoopRelayerChain struct { + loop.Relayer + chain adapters.Chain +} + +func NewLoopRelayerChain(r *pkgcosmos.Relayer, s adapters.Chain) *LoopRelayerChain { + + ra := relay.NewRelayerAdapter(r, s) + return &LoopRelayerChain{ + Relayer: ra, + chain: s, + } +} +func (r *LoopRelayerChain) Chain() adapters.Chain { + return r.chain +} + +var _ LoopRelayerChainer = &LoopRelayerChain{} diff --git a/core/chains/evm/mocks/chain.go b/core/chains/evm/mocks/chain.go index 92d39a95fb9..bf4d1581e22 100644 --- a/core/chains/evm/mocks/chain.go +++ b/core/chains/evm/mocks/chain.go @@ -320,20 +320,6 @@ func (_m *Chain) Ready() error { return r0 } -// SendTx provides a mock function with given fields: ctx, from, to, amount, balanceCheck -func (_m *Chain) SendTx(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error { - ret := _m.Called(ctx, from, to, amount, balanceCheck) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, *big.Int, bool) error); ok { - r0 = rf(ctx, from, to, amount, balanceCheck) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // Start provides a mock function with given fields: _a0 func (_m *Chain) Start(_a0 context.Context) error { ret := _m.Called(_a0) diff --git a/core/chains/solana/chain.go b/core/chains/solana/chain.go index 5678cc7f504..b39435368ad 100644 --- a/core/chains/solana/chain.go +++ b/core/chains/solana/chain.go @@ -248,7 +248,7 @@ func (c *chain) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken } func (c *chain) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { - panic("unimplmented") + return c.sendTx(ctx, from, to, amount, balanceCheck) } func (c *chain) listNodeStatuses(start, end int) ([]relaytypes.NodeStatus, int, error) { @@ -392,7 +392,7 @@ func (c *chain) HealthReport() map[string]error { return report } -func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { +func (c *chain) sendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { reader, err := c.Reader() if err != nil { return fmt.Errorf("chain unreachable: %w", err) diff --git a/core/chains/solana/relay_extender.go b/core/chains/solana/relay_extender.go deleted file mode 100644 index e25cce0b697..00000000000 --- a/core/chains/solana/relay_extender.go +++ /dev/null @@ -1,40 +0,0 @@ -package solana - -import ( - "context" - "fmt" - "math/big" - - relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" - "github.com/smartcontractkit/chainlink-solana/pkg/solana" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" -) - -// TODO remove these wrappers after BCF-2441 -type RelayExtender struct { - solana.Chain - chainImpl *chain -} - -var _ relay.RelayerExt = &RelayExtender{} - -func NewRelayExtender(cfg *SolanaConfig, opts ChainOpts) (*RelayExtender, error) { - c, err := NewChain(cfg, opts) - if err != nil { - return nil, err - } - chainImpl, ok := (c).(*chain) - if !ok { - return nil, fmt.Errorf("internal error: cosmos relay extender got wrong type %t", c) - } - return &RelayExtender{Chain: chainImpl, chainImpl: chainImpl}, nil -} -func (r *RelayExtender) GetChainStatus(ctx context.Context) (relaytypes.ChainStatus, error) { - return r.chainImpl.GetChainStatus(ctx) -} -func (r *RelayExtender) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []relaytypes.NodeStatus, nextPageToken string, total int, err error) { - return r.chainImpl.ListNodeStatuses(ctx, pageSize, pageToken) -} -func (r *RelayExtender) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { - return r.chainImpl.SendTx(ctx, from, to, amount, balanceCheck) -} diff --git a/core/chains/starknet/relay_extender.go b/core/chains/starknet/relay_extender.go deleted file mode 100644 index 54d5ab2ab03..00000000000 --- a/core/chains/starknet/relay_extender.go +++ /dev/null @@ -1,43 +0,0 @@ -package starknet - -import ( - "context" - "fmt" - "math/big" - - relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" - starkchain "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/chain" - - "github.com/smartcontractkit/chainlink/v2/core/chains" - - "github.com/smartcontractkit/chainlink/v2/core/services/relay" -) - -// TODO remove these wrappers after BCF-2441 -type RelayExtender struct { - starkchain.Chain - chainImpl *chain -} - -var _ relay.RelayerExt = &RelayExtender{} - -func NewRelayExtender(cfg *StarknetConfig, opts ChainOpts) (*RelayExtender, error) { - c, err := NewChain(cfg, opts) - if err != nil { - return nil, err - } - chainImpl, ok := (c).(*chain) - if !ok { - return nil, fmt.Errorf("internal error: starkent relay extender got wrong type %t", c) - } - return &RelayExtender{Chain: chainImpl, chainImpl: chainImpl}, nil -} -func (r *RelayExtender) GetChainStatus(ctx context.Context) (relaytypes.ChainStatus, error) { - return r.chainImpl.GetChainStatus(ctx) -} -func (r *RelayExtender) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []relaytypes.NodeStatus, nextPageToken string, total int, err error) { - return r.chainImpl.ListNodeStatuses(ctx, pageSize, pageToken) -} -func (r *RelayExtender) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { - return chains.ErrLOOPPUnsupported -} diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 738d21ddb73..05c80a63dbc 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -299,7 +299,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.20230831132059-42af68994512 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 9d919d1ac72..61b13f05a10 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1377,8 +1377,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-cosmos v0.4.1-0.20230831132059-42af68994512 h1:DojChlaudA1HAxwQPKmt/EDf36OUeFJ0LJBYClauMyU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938 h1:LnxS4RoDcUS4+zXoY/gaV4BB6u90DgW3LtyFCoCpJzY= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 h1:yArUq/0t126bl8BRtjLCf2NuHK35CDIkhc3M5P46apc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 65859338b6c..924279389f0 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -215,10 +215,8 @@ func (rs *CoreRelayerChainInteroperators) ChainStatus(ctx context.Context, id re if err != nil { return types.ChainStatus{}, fmt.Errorf("%w: error getting chain status: %w", chains.ErrNotFound, err) } - // this call is weird because the [loop.Relayer] interface still requires id - // but in this context the `relayer` should only have only id - // moreover, the `relayer` here is pinned to one chain we need to pass the chain id - return lr.ChainStatus(ctx, id.ChainID.String()) + + return lr.GetChainStatus(ctx) } func (rs *CoreRelayerChainInteroperators) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) { @@ -240,8 +238,7 @@ func (rs *CoreRelayerChainInteroperators) ChainStatuses(ctx context.Context, off }) for _, rid := range relayerIds { lr := rs.loopRelayers[rid] - // the relayer is chain specific; use the chain id and not the relayer id - stat, err := lr.ChainStatus(ctx, rid.ChainID.String()) + stat, err := lr.GetChainStatus(ctx) if err != nil { totalErr = errors.Join(totalErr, err) continue @@ -275,7 +272,7 @@ func (rs *CoreRelayerChainInteroperators) Node(ctx context.Context, name string) } // ids must be a string representation of relay.Identifier -// ids are a filter; if none are specificied, all are returned. +// ids are a filter; if none are specified, all are returned. // TODO: BCF-2440/1 this signature can be changed to id relay.Identifier which is a much better API func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...string) (nodes []types.NodeStatus, count int, err error) { var ( @@ -283,13 +280,14 @@ func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offs result []types.NodeStatus ) if len(relayerIDs) == 0 { - for rid, lr := range rs.loopRelayers { - stats, _, err := lr.NodeStatuses(ctx, offset, limit, rid.ChainID.String()) + for _, lr := range rs.loopRelayers { + stats, _, total, err := lr.ListNodeStatuses(ctx, int32(limit), "") if err != nil { totalErr = errors.Join(totalErr, err) continue } result = append(result, stats...) + count += total } } else { for _, idStr := range relayerIDs { @@ -304,22 +302,23 @@ func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offs totalErr = errors.Join(totalErr, fmt.Errorf("relayer %s does not exist", rid.Name())) continue } - nodeStats, _, err := lr.NodeStatuses(ctx, offset, limit, rid.ChainID.String()) + nodeStats, _, total, err := lr.ListNodeStatuses(ctx, int32(limit), "") if err != nil { totalErr = errors.Join(totalErr, err) continue } result = append(result, nodeStats...) + count += total } } if totalErr != nil { return nil, 0, totalErr } if len(result) > limit && limit > 0 { - return result[offset : offset+limit], limit, nil + return result[offset : offset+limit], count, nil } - return result[offset:], len(result[offset:]), nil + return result[offset:], count, nil } type FilterFn func(id relay.ID) bool diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 4ff70a585ac..6c09f5c4ab4 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -131,11 +131,11 @@ func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solana.SolanaCo Configs: solana.NewConfigs(singleChainCfg), } - relayExt, err := solana.NewRelayExtender(chainCfg, opts) + chain, err := solana.NewChain(chainCfg, opts) if err != nil { return nil, err } - solanaRelayers[relayId] = relay.NewRelayerAdapter(pkgsolana.NewRelayer(solLggr, relayExt), relayExt) + solanaRelayers[relayId] = relay.NewRelayerAdapter(pkgsolana.NewRelayer(solLggr, chain), chain) } } return solanaRelayers, nil @@ -203,12 +203,12 @@ func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs starknet.St Configs: starknet.NewConfigs(singleChainCfg), } - relayExt, err := starknet.NewRelayExtender(chainCfg, opts) + chain, err := starknet.NewChain(chainCfg, opts) if err != nil { return nil, err } - starknetRelayers[relayId] = relay.NewRelayerAdapter(pkgstarknet.NewRelayer(starkLggr, relayExt), relayExt) + starknetRelayers[relayId] = relay.NewRelayerAdapter(pkgstarknet.NewRelayer(starkLggr, chain), chain) } } return starknetRelayers, nil @@ -241,13 +241,13 @@ func (r *RelayerFactory) NewCosmos(ctx context.Context, config CosmosFactoryConf EventBroadcaster: config.EventBroadcaster, } opts.Configs = cosmos.NewConfigs(cosmos.CosmosConfigs{chainCfg}) - relayExt, err := cosmos.NewRelayExtender(chainCfg, opts) + chain, err := cosmos.NewChain(chainCfg, opts) if err != nil { return nil, fmt.Errorf("failed to load Cosmos chain %q: %w", relayId, err) } - relayers[relayId] = cosmos.NewLoopRelayerChain(pkgcosmos.NewRelayer(lggr, relayExt), relayExt) + relayers[relayId] = cosmos.NewLoopRelayerChain(pkgcosmos.NewRelayer(lggr, chain), chain) } return relayers, nil diff --git a/core/services/relay/evm/mocks/loop_relay_adapter.go b/core/services/relay/evm/mocks/loop_relay_adapter.go index b0d9b7cf95e..7ed28ac4b11 100644 --- a/core/services/relay/evm/mocks/loop_relay_adapter.go +++ b/core/services/relay/evm/mocks/loop_relay_adapter.go @@ -33,63 +33,6 @@ func (_m *LoopRelayAdapter) Chain() evm.Chain { return r0 } -// ChainStatus provides a mock function with given fields: ctx, id -func (_m *LoopRelayAdapter) ChainStatus(ctx context.Context, id string) (types.ChainStatus, error) { - ret := _m.Called(ctx, id) - - var r0 types.ChainStatus - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string) (types.ChainStatus, error)); ok { - return rf(ctx, id) - } - if rf, ok := ret.Get(0).(func(context.Context, string) types.ChainStatus); ok { - r0 = rf(ctx, id) - } else { - r0 = ret.Get(0).(types.ChainStatus) - } - - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ChainStatuses provides a mock function with given fields: ctx, offset, limit -func (_m *LoopRelayAdapter) ChainStatuses(ctx context.Context, offset int, limit int) ([]types.ChainStatus, int, error) { - ret := _m.Called(ctx, offset, limit) - - var r0 []types.ChainStatus - var r1 int - var r2 error - if rf, ok := ret.Get(0).(func(context.Context, int, int) ([]types.ChainStatus, int, error)); ok { - return rf(ctx, offset, limit) - } - if rf, ok := ret.Get(0).(func(context.Context, int, int) []types.ChainStatus); ok { - r0 = rf(ctx, offset, limit) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]types.ChainStatus) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, int, int) int); ok { - r1 = rf(ctx, offset, limit) - } else { - r1 = ret.Get(1).(int) - } - - if rf, ok := ret.Get(2).(func(context.Context, int, int) error); ok { - r2 = rf(ctx, offset, limit) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - // Close provides a mock function with given fields: func (_m *LoopRelayAdapter) Close() error { ret := _m.Called() @@ -118,6 +61,30 @@ func (_m *LoopRelayAdapter) Default() bool { return r0 } +// GetChainStatus provides a mock function with given fields: ctx +func (_m *LoopRelayAdapter) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { + ret := _m.Called(ctx) + + var r0 types.ChainStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (types.ChainStatus, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) types.ChainStatus); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(types.ChainStatus) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // HealthReport provides a mock function with given fields: func (_m *LoopRelayAdapter) HealthReport() map[string]error { ret := _m.Called() @@ -134,6 +101,46 @@ func (_m *LoopRelayAdapter) HealthReport() map[string]error { return r0 } +// ListNodeStatuses provides a mock function with given fields: ctx, pageSize, pageToken +func (_m *LoopRelayAdapter) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) ([]types.NodeStatus, string, int, error) { + ret := _m.Called(ctx, pageSize, pageToken) + + var r0 []types.NodeStatus + var r1 string + var r2 int + var r3 error + if rf, ok := ret.Get(0).(func(context.Context, int32, string) ([]types.NodeStatus, string, int, error)); ok { + return rf(ctx, pageSize, pageToken) + } + if rf, ok := ret.Get(0).(func(context.Context, int32, string) []types.NodeStatus); ok { + r0 = rf(ctx, pageSize, pageToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.NodeStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int32, string) string); ok { + r1 = rf(ctx, pageSize, pageToken) + } else { + r1 = ret.Get(1).(string) + } + + if rf, ok := ret.Get(2).(func(context.Context, int32, string) int); ok { + r2 = rf(ctx, pageSize, pageToken) + } else { + r2 = ret.Get(2).(int) + } + + if rf, ok := ret.Get(3).(func(context.Context, int32, string) error); ok { + r3 = rf(ctx, pageSize, pageToken) + } else { + r3 = ret.Error(3) + } + + return r0, r1, r2, r3 +} + // Name provides a mock function with given fields: func (_m *LoopRelayAdapter) Name() string { ret := _m.Called() @@ -252,46 +259,6 @@ func (_m *LoopRelayAdapter) NewMercuryProvider(_a0 context.Context, _a1 types.Re return r0, r1 } -// NodeStatuses provides a mock function with given fields: ctx, offset, limit, chainIDs -func (_m *LoopRelayAdapter) NodeStatuses(ctx context.Context, offset int, limit int, chainIDs ...string) ([]types.NodeStatus, int, error) { - _va := make([]interface{}, len(chainIDs)) - for _i := range chainIDs { - _va[_i] = chainIDs[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, offset, limit) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 []types.NodeStatus - var r1 int - var r2 error - if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) ([]types.NodeStatus, int, error)); ok { - return rf(ctx, offset, limit, chainIDs...) - } - if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) []types.NodeStatus); ok { - r0 = rf(ctx, offset, limit, chainIDs...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]types.NodeStatus) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, int, int, ...string) int); ok { - r1 = rf(ctx, offset, limit, chainIDs...) - } else { - r1 = ret.Get(1).(int) - } - - if rf, ok := ret.Get(2).(func(context.Context, int, int, ...string) error); ok { - r2 = rf(ctx, offset, limit, chainIDs...) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - // Ready provides a mock function with given fields: func (_m *LoopRelayAdapter) Ready() error { ret := _m.Called() @@ -306,13 +273,13 @@ func (_m *LoopRelayAdapter) Ready() error { return r0 } -// SendTx provides a mock function with given fields: ctx, chainID, from, to, amount, balanceCheck -func (_m *LoopRelayAdapter) SendTx(ctx context.Context, chainID string, from string, to string, amount *big.Int, balanceCheck bool) error { - ret := _m.Called(ctx, chainID, from, to, amount, balanceCheck) +// Start provides a mock function with given fields: _a0 +func (_m *LoopRelayAdapter) Start(_a0 context.Context) error { + ret := _m.Called(_a0) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, string, *big.Int, bool) error); ok { - r0 = rf(ctx, chainID, from, to, amount, balanceCheck) + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) } else { r0 = ret.Error(0) } @@ -320,13 +287,13 @@ func (_m *LoopRelayAdapter) SendTx(ctx context.Context, chainID string, from str return r0 } -// Start provides a mock function with given fields: _a0 -func (_m *LoopRelayAdapter) Start(_a0 context.Context) error { - ret := _m.Called(_a0) +// Transact provides a mock function with given fields: ctx, from, to, amount, balanceCheck +func (_m *LoopRelayAdapter) Transact(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error { + ret := _m.Called(ctx, from, to, amount, balanceCheck) var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, string, string, *big.Int, bool) error); ok { + r0 = rf(ctx, from, to, amount, balanceCheck) } else { r0 = ret.Error(0) } diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index 5b3a3535c51..637baedab83 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -139,10 +139,6 @@ var ErrInconsistentChainRelayerExtender = errors.New("inconsistent evm chain rel // Legacy interface remove after BFC-2441, BCF-2564 -func (s *ChainRelayerExt) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { - return s.Transact(ctx, from, to, amount, balanceCheck) -} - func (s *ChainRelayerExt) ChainStatus(ctx context.Context, id string) (relaytypes.ChainStatus, error) { if s.chain.ID().String() != id { return relaytypes.ChainStatus{}, fmt.Errorf("%w: given id %q does not match expected id %q", ErrInconsistentChainRelayerExtender, id, s.chain.ID()) diff --git a/core/web/solana_transfer_controller.go b/core/web/solana_transfer_controller.go index 5f92c02269b..df750586a46 100644 --- a/core/web/solana_transfer_controller.go +++ b/core/web/solana_transfer_controller.go @@ -58,9 +58,8 @@ func (tc *SolanaTransfersController) Create(c *gin.Context) { jsonAPIError(c, http.StatusInternalServerError, err) return } - // note the [loop.Relayer] API is in intermediate state. we found the relayer above; we should not need to pass - // the chain id here - err = relayer.SendTx(c, tr.SolanaChainID, tr.From.String(), tr.To.String(), amount, !tr.AllowHigherAmounts) + + err = relayer.Transact(c, tr.From.String(), tr.To.String(), amount, !tr.AllowHigherAmounts) if err != nil { switch err { case chains.ErrNotFound, chains.ErrChainIDEmpty: diff --git a/go.mod b/go.mod index 730a30daa16..56c59625339 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-cosmos v0.4.1-0.20230831132059-42af68994512 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938 + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 diff --git a/go.sum b/go.sum index 152a27cad3e..8d127373678 100644 --- a/go.sum +++ b/go.sum @@ -1377,8 +1377,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-cosmos v0.4.1-0.20230831132059-42af68994512 h1:DojChlaudA1HAxwQPKmt/EDf36OUeFJ0LJBYClauMyU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938 h1:LnxS4RoDcUS4+zXoY/gaV4BB6u90DgW3LtyFCoCpJzY= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 h1:yArUq/0t126bl8BRtjLCf2NuHK35CDIkhc3M5P46apc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index c7e8ec794a2..0874c743853 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -384,7 +384,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.20230831132059-42af68994512 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index d43c4163142..c3a08560bda 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2252,8 +2252,8 @@ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af6899451 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= github.com/smartcontractkit/chainlink-env v0.36.0 h1:CFOjs0c0y3lrHi/fl5qseCH9EQa5W/6CFyOvmhe2VnA= github.com/smartcontractkit/chainlink-env v0.36.0/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938 h1:LnxS4RoDcUS4+zXoY/gaV4BB6u90DgW3LtyFCoCpJzY= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230901143551-bf6bd84d6938/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 h1:yArUq/0t126bl8BRtjLCf2NuHK35CDIkhc3M5P46apc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= diff --git a/plugins/cmd/chainlink-solana/main.go b/plugins/cmd/chainlink-solana/main.go index 150a9d840dd..9f470355297 100644 --- a/plugins/cmd/chainlink-solana/main.go +++ b/plugins/cmd/chainlink-solana/main.go @@ -71,11 +71,11 @@ func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, keystore KeyStore: keystore, Configs: solana.NewConfigs(cfgAdapter), } - relayExt, err := solana.NewRelayExtender(&cfg.Solana, opts) + chain, err := solana.NewChain(&cfg.Solana, opts) if err != nil { return nil, fmt.Errorf("failed to create chain: %w", err) } - ra := relay.NewRelayerAdapter(pkgsol.NewRelayer(c.Logger, relayExt), relayExt) + ra := relay.NewRelayerAdapter(pkgsol.NewRelayer(c.Logger, chain), chain) c.SubService(ra) diff --git a/plugins/cmd/chainlink-starknet/main.go b/plugins/cmd/chainlink-starknet/main.go index 15bd0122121..433d4408e31 100644 --- a/plugins/cmd/chainlink-starknet/main.go +++ b/plugins/cmd/chainlink-starknet/main.go @@ -75,11 +75,11 @@ func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, loopKs lo Configs: starknet.NewConfigs(cfgAdapter), } - relayExt, err := starknet.NewRelayExtender(&cfg.Starknet, opts) + chain, err := starknet.NewChain(&cfg.Starknet, opts) if err != nil { return nil, fmt.Errorf("failed to create chain: %w", err) } - ra := relay.NewRelayerAdapter(pkgstarknet.NewRelayer(c.Logger, relayExt), relayExt) + ra := relay.NewRelayerAdapter(pkgstarknet.NewRelayer(c.Logger, chain), chain) c.SubService(ra) From b5e6207e1166520c1965ffa30f9d148e715f1e16 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 6 Sep 2023 11:52:25 -0500 Subject: [PATCH 31/88] golangci-lint tweaks (#10510) --- GNUmakefile | 2 +- core/services/vrf/v2/integration_v2_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 8b6fd2d2ac4..8698d845f3d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -146,7 +146,7 @@ config-docs: ## Generate core node configuration documentation .PHONY: golangci-lint golangci-lint: ## Run golangci-lint for all issues. [ -d "./golangci-lint" ] || mkdir ./golangci-lint && \ - docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.53.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%s).txt + docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.53.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt GORELEASER_CONFIG ?= .goreleaser.yaml diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 3609754df3d..3b85a524bac 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -2143,7 +2143,7 @@ VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt) //nolint:gosec - just copying fields _, err = db.NamedExec(sql, &dbAttempt) require.NoError(t, err) - txmgr.DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt) //nolin:gosec - just copying fields + txmgr.DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt) //nolint:gosec - just copying fields } // add eth_receipts From a15bcd805bcfba930f3abdbf906db3ff04519ac5 Mon Sep 17 00:00:00 2001 From: Chris Cushman <104409744+vreff@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:50:43 -0400 Subject: [PATCH 32/88] [Automation] Update docker scripts (#10516) --- core/scripts/chaincli/command/keeper/launch.go | 2 +- core/scripts/chaincli/handler/keeper_verifiable_load.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/scripts/chaincli/command/keeper/launch.go b/core/scripts/chaincli/command/keeper/launch.go index 7e4c79f70d2..e918095edb4 100644 --- a/core/scripts/chaincli/command/keeper/launch.go +++ b/core/scripts/chaincli/command/keeper/launch.go @@ -47,7 +47,7 @@ var launchAndTestCmd = &cobra.Command{ func init() { launchAndTestCmd.Flags().BoolP("withdraw", "w", true, "Specify if funds should be withdrawn and upkeeps should be canceled") - launchAndTestCmd.Flags().BoolP("bootstrap", "b", true, "Specify if launching bootstrap node is required. Default listen ports(5688, 8000) are used, if you need to use custom ports, please use bootstrap command") + launchAndTestCmd.Flags().BoolP("bootstrap", "b", false, "Specify if launching bootstrap node is required. Default listen ports(5688, 8000) are used, if you need to use custom ports, please use bootstrap command") launchAndTestCmd.Flags().BoolP("export-logs", "l", false, "Specify if container logs should be exported to ./") launchAndTestCmd.Flags().BoolP("force", "f", false, "Specify if existing containers should be forcefully removed ./") } diff --git a/core/scripts/chaincli/handler/keeper_verifiable_load.go b/core/scripts/chaincli/handler/keeper_verifiable_load.go index ad704393877..429a7620079 100644 --- a/core/scripts/chaincli/handler/keeper_verifiable_load.go +++ b/core/scripts/chaincli/handler/keeper_verifiable_load.go @@ -37,7 +37,7 @@ type upkeepInfo struct { } type verifiableLoad interface { - GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) Counters(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) @@ -79,7 +79,7 @@ func (k *Keeper) GetVerifiableLoadStats(ctx context.Context) { } // get all active upkeep IDs on this verifiable load contract - upkeepIds, err := v.GetActiveUpkeepIDs(opts, big.NewInt(0), big.NewInt(0)) + upkeepIds, err := v.GetAllActiveUpkeepIDsOnRegistry(opts, big.NewInt(0), big.NewInt(0)) if err != nil { log.Fatalf("failed to get active upkeep IDs from %s: %v", k.cfg.VerifiableLoadContractAddress, err) } From ad22c6ed0c4bed4053adc1585dca0ad55b481685 Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Wed, 6 Sep 2023 21:17:23 +0300 Subject: [PATCH 33/88] Seed order to manage logs overflow (#10485) * update ocr2keepers * go mod tidy * buffer: drop logs by seed-order * comment out noisy log * ensure order for provider.GetLatestPayloads() * ensure order for recoverer.GetRecoveryProposals() * use a normalized value of latestBlock * set overall limit for recovery proposals (MaxProposals) value TBD, currently set to 50 * set max proposals to 20 (was 50) * apply total limits when dequeing for payloads MaxPayloads was set to 100 * fix test * fix max block logs * protect log spamming * renaming * lint * set offset to 100 * added tests * use maps when sorting * temporary added blockhash to log id * lint * remove todo from log id func --- .../ocr2keeper/evm21/logprovider/buffer.go | 132 ++++- .../evm21/logprovider/buffer_test.go | 510 +++++++++++++++++- .../evm21/logprovider/integration_test.go | 6 +- .../ocr2keeper/evm21/logprovider/provider.go | 11 +- .../ocr2keeper/evm21/logprovider/recoverer.go | 55 +- .../evm21/logprovider/recoverer_test.go | 4 +- .../ocr2/plugins/ocr2keeper/evm21/registry.go | 1 + 7 files changed, 677 insertions(+), 42 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go index ad0ae5e1024..1835ac69f09 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go @@ -1,26 +1,45 @@ package logprovider import ( + "encoding/hex" "math/big" "sort" "sync" "sync/atomic" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/random" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" ) var ( - // allowedLogsPerBlock is the maximum number of logs allowed per upkeep in a block. - allowedLogsPerBlock = 128 - // bufferMaxBlockSize is the maximum number of blocks in the buffer. - bufferMaxBlockSize = 1024 + // maxLogsPerUpkeepInBlock is the maximum number of logs allowed per upkeep in a block. + maxLogsPerUpkeepInBlock = 32 + // maxLogsPerBlock is the maximum number of blocks in the buffer. + maxLogsPerBlock = 1024 ) // fetchedLog holds the log and the ID of the upkeep type fetchedLog struct { upkeepID *big.Int log logpoller.Log + // cachedLogID is the cached log identifier, used for sorting. + // It is calculated lazily, and cached for performance. + cachedLogID string +} + +func (l *fetchedLog) getLogID() string { + if len(l.cachedLogID) == 0 { + ext := ocr2keepers.LogTriggerExtension{ + Index: uint32(l.log.LogIndex), + } + copy(ext.TxHash[:], l.log.TxHash[:]) + copy(ext.BlockHash[:], l.log.BlockHash[:]) + l.cachedLogID = hex.EncodeToString(ext.LogIdentifier()) + } + return l.cachedLogID } // fetchedBlock holds the logs fetched for a block @@ -33,9 +52,46 @@ type fetchedBlock struct { visited []fetchedLog } +func (b *fetchedBlock) Append(lggr logger.Logger, fl fetchedLog, maxBlockLogs, maxUpkeepLogs int) (fetchedLog, bool) { + has, upkeepLogs := b.has(fl.upkeepID, fl.log) + if has { + // Skipping known logs + return fetchedLog{}, false + } + // lggr.Debugw("Adding log", "i", i, "blockBlock", currentBlock.blockNumber, "logBlock", log.BlockNumber, "id", id) + b.logs = append(b.logs, fl) + + // drop logs if we reached limits. + if upkeepLogs+1 > maxUpkeepLogs { + // in case we have logs overflow for a particular upkeep, we drop a log of that upkeep, + // based on shared, random (per block) order of the logs in the block. + b.Sort() + var dropped fetchedLog + currentLogs := make([]fetchedLog, 0, len(b.logs)-1) + for _, l := range b.logs { + if dropped.upkeepID == nil && l.upkeepID.Cmp(fl.upkeepID) == 0 { + dropped = l + continue + } + currentLogs = append(currentLogs, l) + } + b.logs = currentLogs + return dropped, true + } else if len(b.logs)+len(b.visited) > maxBlockLogs { + // in case we have logs overflow in the buffer level, we drop a log based on + // shared, random (per block) order of the logs in the block. + b.Sort() + dropped := b.logs[0] + b.logs = b.logs[1:] + return dropped, true + } + + return fetchedLog{}, true +} + // Has returns true if the block has the log, // and the number of logs for that upkeep in the block. -func (b fetchedBlock) Has(id *big.Int, log logpoller.Log) (bool, int) { +func (b fetchedBlock) has(id *big.Int, log logpoller.Log) (bool, int) { allLogs := append(b.logs, b.visited...) upkeepLogs := 0 for _, l := range allLogs { @@ -62,6 +118,22 @@ func (b fetchedBlock) Clone() fetchedBlock { } } +// Sort by log identifiers, shuffled using a pseduorandom souce that is shared across all nodes +// for a given block. +func (b *fetchedBlock) Sort() { + randSeed := random.GetRandomKeySource(nil, uint64(b.blockNumber)) + + shuffledLogIDs := make(map[string]string, len(b.logs)) + for _, log := range b.logs { + logID := log.getLogID() + shuffledLogIDs[logID] = random.ShuffleString(logID, randSeed) + } + + sort.SliceStable(b.logs, func(i, j int) bool { + return shuffledLogIDs[b.logs[i].getLogID()] < shuffledLogIDs[b.logs[j].getLogID()] + }) +} + // logEventBuffer is a circular/ring buffer of fetched logs. // Each entry in the buffer represents a block, // and holds the logs fetched for that block. @@ -97,6 +169,7 @@ func (b *logEventBuffer) bufferSize() int { } // enqueue adds logs (if not exist) to the buffer, returning the number of logs added +// minus the number of logs dropped. func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int { b.lock.Lock() defer b.lock.Unlock() @@ -107,7 +180,8 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int { maxUpkeepLogs := int(b.maxUpkeepLogsPerBlock) latestBlock := b.latestBlockSeen() - added := 0 + added, dropped := 0, 0 + for _, log := range logs { if log.BlockNumber == 0 { // invalid log @@ -125,23 +199,20 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int { lggr.Debugw("Skipping log from old block", "currentBlock", currentBlock.blockNumber, "newBlock", log.BlockNumber) continue } - if len(currentBlock.logs)+1 > maxBlockLogs { - lggr.Debugw("Reached max logs number per block, dropping log", "blockNumber", log.BlockNumber, - "blockHash", log.BlockHash, "txHash", log.TxHash, "logIndex", log.LogIndex) + droppedLog, ok := currentBlock.Append(lggr, fetchedLog{upkeepID: id, log: log}, maxBlockLogs, maxUpkeepLogs) + if !ok { + // Skipping known logs continue } - if has, upkeepLogs := currentBlock.Has(id, log); has { - // Skipping existing log - continue - } else if upkeepLogs+1 > maxUpkeepLogs { - lggr.Debugw("Reached max logs number per upkeep, dropping log", "blockNumber", log.BlockNumber, - "blockHash", log.BlockHash, "txHash", log.TxHash, "logIndex", log.LogIndex) - continue + if droppedLog.upkeepID != nil { + dropped++ + lggr.Debugw("Reached log buffer limits, dropping log", "blockNumber", droppedLog.log.BlockNumber, + "blockHash", droppedLog.log.BlockHash, "txHash", droppedLog.log.TxHash, "logIndex", droppedLog.log.LogIndex, + "upkeepID", droppedLog.upkeepID.String()) } - // lggr.Debugw("Adding log", "i", i, "blockBlock", currentBlock.blockNumber, "logBlock", log.BlockNumber, "id", id) - currentBlock.logs = append(currentBlock.logs, fetchedLog{upkeepID: id, log: log}) - b.blocks[i] = currentBlock added++ + b.blocks[i] = currentBlock + if log.BlockNumber > latestBlock { latestBlock = log.BlockNumber } @@ -151,10 +222,10 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int { atomic.StoreInt64(&b.latestBlock, latestBlock) } if added > 0 { - lggr.Debugw("Added logs to buffer", "addedLogs", added, "latestBlock", latestBlock) + lggr.Debugw("Added logs to buffer", "addedLogs", added, "dropped", dropped, "latestBlock", latestBlock) } - return added + return added - dropped } // peek returns the logs in range [latestBlock-blocks, latestBlock] @@ -196,7 +267,7 @@ func (b *logEventBuffer) peekRange(start, end int64) []fetchedLog { } // dequeueRange returns the logs between start and end inclusive. -func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit int) []fetchedLog { +func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit, totalLimit int) []fetchedLog { b.lock.Lock() defer b.lock.Unlock() @@ -214,20 +285,33 @@ func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit int) []fetch }) logsCount := map[string]int{} + totalCount := 0 var results []fetchedLog for _, block := range fetchedBlocks { - // double checking that we don't have any gaps in the range if block.blockNumber < start || block.blockNumber > end { + // double checking that we don't have any gaps in the range continue } + if totalCount >= totalLimit { + // reached total limit, no need to process more blocks + break + } + // Sort the logs in random order that is shared across all nodes. + // This ensures that nodes across the network will process the same logs. + block.Sort() var remainingLogs, blockResults []fetchedLog for _, log := range block.logs { + if totalCount >= totalLimit { + remainingLogs = append(remainingLogs, log) + continue + } if logsCount[log.upkeepID.String()] >= upkeepLimit { remainingLogs = append(remainingLogs, log) continue } - logsCount[log.upkeepID.String()]++ blockResults = append(blockResults, log) + logsCount[log.upkeepID.String()]++ + totalCount++ } if len(blockResults) == 0 { continue diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go index 18eecb748a5..0f389d0d418 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go @@ -1,15 +1,18 @@ package logprovider import ( + "encoding/hex" "fmt" "math/big" "testing" "github.com/ethereum/go-ethereum/common" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/stretchr/testify/require" "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/evm21/core" ) func TestLogEventBuffer_GetBlocksInRange(t *testing.T) { @@ -236,7 +239,7 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { results := buf.peekRange(int64(1), int64(2)) require.Equal(t, 2, len(results)) verifyBlockNumbers(t, results, 1, 2) - removed := buf.dequeueRange(int64(1), int64(2), 2) + removed := buf.dequeueRange(int64(1), int64(2), 2, 10) require.Equal(t, 2, len(removed)) results = buf.peekRange(int64(1), int64(2)) require.Equal(t, 0, len(results)) @@ -256,7 +259,7 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { results := buf.peek(8) require.Equal(t, 4, len(results)) verifyBlockNumbers(t, results, 1, 2, 3, 3) - removed := buf.dequeueRange(1, 3, 5) + removed := buf.dequeueRange(1, 3, 5, 5) require.Equal(t, 4, len(removed)) buf.lock.Lock() require.Equal(t, 0, len(buf.blocks[0].logs)) @@ -313,10 +316,18 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x5"), LogIndex: 0}, ), 5) - logs := buf.dequeueRange(1, 5, 2) + logs := buf.dequeueRange(1, 5, 2, 10) require.Equal(t, 2, len(logs)) require.Equal(t, int64(5), logs[0].log.BlockNumber) require.Equal(t, int64(4), logs[1].log.BlockNumber) + + require.Equal(t, buf.enqueue(big.NewInt(1), + logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x4"), LogIndex: 1}, + logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x5"), LogIndex: 1}, + ), 2) + + logs = buf.dequeueRange(1, 5, 3, 2) + require.Equal(t, 2, len(logs)) }) t.Run("dequeue doesn't return same logs again", func(t *testing.T) { @@ -327,19 +338,508 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0}, ), 3) - logs := buf.dequeueRange(3, 3, 2) + logs := buf.dequeueRange(3, 3, 2, 10) fmt.Println(logs) require.Equal(t, 1, len(logs)) - logs = buf.dequeueRange(3, 3, 2) + logs = buf.dequeueRange(3, 3, 2, 10) fmt.Println(logs) require.Equal(t, 0, len(logs)) }) } +func TestLogEventBuffer_FetchedBlock_Append(t *testing.T) { + type appendArgs struct { + fl fetchedLog + maxBlockLogs, maxUpkeepLogs int + added, dropped bool + } + + tests := []struct { + name string + blockNumber int64 + logs []fetchedLog + visited []fetchedLog + toAdd []appendArgs + expected []fetchedLog + added bool + }{ + { + name: "empty block", + blockNumber: 1, + logs: []fetchedLog{}, + visited: []fetchedLog{}, + toAdd: []appendArgs{ + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 10, + maxUpkeepLogs: 2, + added: true, + }, + }, + expected: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + }, + { + name: "existing log", + blockNumber: 1, + logs: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + visited: []fetchedLog{}, + toAdd: []appendArgs{ + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 10, + maxUpkeepLogs: 2, + added: false, + }, + }, + expected: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + }, + { + name: "visited log", + blockNumber: 1, + logs: []fetchedLog{}, + visited: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + toAdd: []appendArgs{ + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 10, + maxUpkeepLogs: 2, + added: false, + }, + }, + expected: []fetchedLog{}, + }, + { + name: "upkeep log limits", + blockNumber: 1, + logs: []fetchedLog{}, + visited: []fetchedLog{}, + toAdd: []appendArgs{ + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 10, + maxUpkeepLogs: 2, + added: true, + }, + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 1, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 10, + maxUpkeepLogs: 2, + added: true, + }, + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 2, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 10, + maxUpkeepLogs: 2, + added: true, + dropped: true, + }, + }, + expected: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 1, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 2, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + }, + { + name: "block log limits", + blockNumber: 1, + logs: []fetchedLog{}, + visited: []fetchedLog{}, + toAdd: []appendArgs{ + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 2, + maxUpkeepLogs: 4, + added: true, + }, + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 1, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 2, + maxUpkeepLogs: 4, + added: true, + }, + { + fl: fetchedLog{ + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 2, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + maxBlockLogs: 2, + maxUpkeepLogs: 4, + added: true, + dropped: true, + }, + }, + expected: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 1, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 2, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + lggr := logger.TestLogger(t) + b := fetchedBlock{ + blockNumber: tc.blockNumber, + logs: make([]fetchedLog, len(tc.logs)), + visited: make([]fetchedLog, len(tc.visited)), + } + copy(b.logs, tc.logs) + copy(b.visited, tc.visited) + + for _, args := range tc.toAdd { + dropped, added := b.Append(lggr, args.fl, args.maxBlockLogs, args.maxUpkeepLogs) + require.Equal(t, args.added, added) + if args.dropped { + require.NotNil(t, dropped.upkeepID) + } else { + require.Nil(t, dropped.upkeepID) + } + } + // clear cached logIDs + for i := range b.logs { + b.logs[i].cachedLogID = "" + } + require.Equal(t, tc.expected, b.logs) + }) + } +} +func TestLogEventBuffer_FetchedBlock_Sort(t *testing.T) { + tests := []struct { + name string + blockNumber int64 + logs []fetchedLog + beforeSort []string + afterSort []string + iterations int + }{ + { + name: "no logs", + blockNumber: 10, + logs: []fetchedLog{}, + beforeSort: []string{}, + afterSort: []string{}, + }, + { + name: "single log", + blockNumber: 1, + logs: []fetchedLog{ + { + log: logpoller.Log{ + BlockHash: common.HexToHash("0x111"), + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + }, + }, + beforeSort: []string{ + "000000000000000000000000000000000000000000000000000000000000000100000000", + }, + afterSort: []string{ + "000000000000000000000000000000000000000000000000000000000000000100000000", + }, + }, + { + name: "multiple logs with 10 iterations", + blockNumber: 1, + logs: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xb711bd1103927611ee41152aa8ae27f3330"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "222").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"), + LogIndex: 4, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"), + LogIndex: 3, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "222").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"), + LogIndex: 2, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"), + LogIndex: 5, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"), + LogIndex: 3, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"), + TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"), + LogIndex: 1, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + beforeSort: []string{ + "00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001", + }, + afterSort: []string{ + "00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004", + "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005", + }, + iterations: 10, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + b := fetchedBlock{ + blockNumber: tc.blockNumber, + logs: make([]fetchedLog, len(tc.logs)), + } + if tc.iterations == 0 { + tc.iterations = 1 + } + // performing the same multiple times should yield the same result + // default is one iteration + for i := 0; i < tc.iterations; i++ { + copy(b.logs, tc.logs) + logIDs := getLogIds(b) + require.Equal(t, len(tc.beforeSort), len(logIDs)) + require.Equal(t, tc.beforeSort, logIDs) + b.Sort() + logIDsAfterSort := getLogIds(b) + require.Equal(t, len(tc.afterSort), len(logIDsAfterSort)) + require.Equal(t, tc.afterSort, logIDsAfterSort) + } + }) + } +} + +func TestLogEventBuffer_FetchedBlock_Clone(t *testing.T) { + b1 := fetchedBlock{ + blockNumber: 1, + logs: []fetchedLog{ + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 0, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + { + log: logpoller.Log{ + BlockNumber: 1, + TxHash: common.HexToHash("0x1"), + LogIndex: 2, + }, + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(), + }, + }, + } + + b2 := b1.Clone() + require.Equal(t, b1.blockNumber, b2.blockNumber) + require.Equal(t, len(b1.logs), len(b2.logs)) + require.Equal(t, b1.logs[0].log.BlockNumber, b2.logs[0].log.BlockNumber) + + b1.blockNumber = 2 + b1.logs[0].log.BlockNumber = 2 + require.NotEqual(t, b1.blockNumber, b2.blockNumber) + require.NotEqual(t, b1.logs[0].log.BlockNumber, b2.logs[0].log.BlockNumber) +} + func verifyBlockNumbers(t *testing.T, logs []fetchedLog, bns ...int64) { require.Equal(t, len(bns), len(logs), "expected length mismatch") for i, log := range logs { require.Equal(t, bns[i], log.log.BlockNumber, "wrong block number") } } + +func getLogIds(b fetchedBlock) []string { + logIDs := make([]string, len(b.logs)) + for i, l := range b.logs { + ext := ocr2keepers.LogTriggerExtension{ + TxHash: l.log.TxHash, + Index: uint32(l.log.LogIndex), + BlockHash: l.log.BlockHash, + } + logIDs[i] = hex.EncodeToString(ext.LogIdentifier()) + } + return logIDs +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go index 30994543eb6..b5f229f6015 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go @@ -478,10 +478,10 @@ func TestIntegration_LogRecoverer_Backfill(t *testing.T) { } lp, ethClient, utilsABI := setupDependencies(t, db, backend) filterStore := logprovider.NewUpkeepFilterStore() - origDefaultRecoveryInterval := logprovider.DefaultRecoveryInterval - logprovider.DefaultRecoveryInterval = time.Millisecond * 200 + origDefaultRecoveryInterval := logprovider.RecoveryInterval + logprovider.RecoveryInterval = time.Millisecond * 200 defer func() { - logprovider.DefaultRecoveryInterval = origDefaultRecoveryInterval + logprovider.RecoveryInterval = origDefaultRecoveryInterval }() provider, recoverer := setup(logger.TestLogger(t), lp, nil, utilsABI, &mockUpkeepStateStore{}, filterStore, opts) logProvider := provider.(logprovider.LogEventProviderTest) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go index 8fbbb1e0a9d..6b89dfd0e72 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go @@ -30,6 +30,8 @@ var ( // AllowedLogsPerUpkeep is the maximum number of logs allowed per upkeep every single call. AllowedLogsPerUpkeep = 5 + // MaxPayloads is the maximum number of payloads to return per call. + MaxPayloads = 100 readJobQueueSize = 64 readLogsTimeout = 10 * time.Second @@ -99,7 +101,7 @@ func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, packer LogDa return &logEventProvider{ packer: packer, lggr: lggr.Named("KeepersRegistry.LogEventProvider"), - buffer: newLogEventBuffer(lggr, int(opts.LookbackBlocks), bufferMaxBlockSize, allowedLogsPerBlock), + buffer: newLogEventBuffer(lggr, int(opts.LookbackBlocks), maxLogsPerBlock, maxLogsPerUpkeepInBlock), poller: poller, opts: opts, filterStore: filterStore, @@ -177,7 +179,7 @@ func (p *logEventProvider) GetLatestPayloads(ctx context.Context) ([]ocr2keepers if start <= 0 { start = 1 } - logs := p.buffer.dequeueRange(start, latest, AllowedLogsPerUpkeep) + logs := p.buffer.dequeueRange(start, latest, AllowedLogsPerUpkeep, MaxPayloads) // p.lggr.Debugw("got latest logs from buffer", "latest", latest, "diff", diff, "logs", len(logs)) @@ -318,7 +320,10 @@ func (p *logEventProvider) updateFiltersLastPoll(entries []upkeepFilter) { p.filterStore.UpdateFilters(func(orig, f upkeepFilter) upkeepFilter { if f.lastPollBlock > orig.lastPollBlock { orig.lastPollBlock = f.lastPollBlock - p.lggr.Debugw("Updated lastPollBlock", "lastPollBlock", f.lastPollBlock, "upkeepID", f.upkeepID) + if f.lastPollBlock%10 == 0 { + // print log occasionally to avoid spamming logs + p.lggr.Debugw("Updated lastPollBlock", "lastPollBlock", f.lastPollBlock, "upkeepID", f.upkeepID) + } } return orig }, entries...) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go index 7a7dbbe46be..dbed9c591cd 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -13,6 +13,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/random" ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -24,11 +25,17 @@ import ( ) var ( - DefaultRecoveryInterval = 5 * time.Second - RecoveryCacheTTL = 10*time.Minute - time.Second - GCInterval = RecoveryCacheTTL - - recoveryBatchSize = 10 + // RecoveryInterval is the interval at which the recovery scanning processing is triggered + RecoveryInterval = 5 * time.Second + // RecoveryCacheTTL is the time to live for the recovery cache + RecoveryCacheTTL = 10 * time.Minute + // GCInterval is the interval at which the recovery cache is cleaned up + GCInterval = RecoveryCacheTTL - time.Second + // MaxProposals is the maximum number of proposals that can be returned by GetRecoveryProposals + MaxProposals = 20 + // recoveryBatchSize is the number of filters to recover in a single batch + recoveryBatchSize = 10 + // recoveryLogsBuffer is the number of blocks to be used as a safety buffer when reading logs recoveryLogsBuffer = int64(200) recoveryLogsBurst = int64(500) ) @@ -244,6 +251,11 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2 } func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { + latestBlock, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + if err != nil { + return nil, fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) + } + r.lock.Lock() defer r.lock.Unlock() @@ -251,18 +263,29 @@ func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers. return nil, nil } + allLogsCounter := 0 logsCount := map[string]int{} + r.sortPending(uint64(latestBlock)) + 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 + pending = append(pending, payload) + continue + } uid := payload.UpkeepID.String() if logsCount[uid] >= AllowedLogsPerUpkeep { + // we have enough proposals for this upkeep, the rest are pushed back to pending pending = append(pending, payload) continue } - logsCount[uid]++ results = append(results, payload) + logsCount[uid]++ + allLogsCounter++ } + r.pending = pending r.lggr.Debugf("found %d pending payloads", len(pending)) @@ -603,3 +626,23 @@ func (r *logRecoverer) removePending(workID string) { } r.pending = updated } + +// sortPending sorts the pending list by a random order based on the normalized latest block number. +// Divided by 10 to ensure that nodes with similar block numbers won't end up with different order. +// NOTE: the lock must be held before calling this function. +func (r *logRecoverer) sortPending(latestBlock uint64) { + normalized := latestBlock / 100 + if normalized == 0 { + normalized = 1 + } + randSeed := random.GetRandomKeySource(nil, normalized) + + shuffledIDs := make(map[string]string, len(r.pending)) + for _, p := range r.pending { + shuffledIDs[p.WorkID] = random.ShuffleString(p.WorkID, randSeed) + } + + sort.SliceStable(r.pending, func(i, j int) bool { + return shuffledIDs[r.pending[i].WorkID] < shuffledIDs[r.pending[j].WorkID] + }) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go index 0a993831b7b..e7729924304 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go @@ -31,7 +31,9 @@ import ( func TestLogRecoverer_GetRecoverables(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - r := NewLogRecoverer(logger.TestLogger(t), nil, nil, nil, nil, nil, NewOptions(200)) + lp := &lpmocks.LogPoller{} + lp.On("LatestBlock", mock.Anything).Return(int64(100), nil) + r := NewLogRecoverer(logger.TestLogger(t), lp, nil, nil, nil, nil, NewOptions(200)) tests := []struct { name string diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go index 849463e53a2..1c54bf553d9 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go @@ -283,6 +283,7 @@ func (r *EvmRegistry) refreshActiveUpkeeps() error { switch core.GetUpkeepType(*uid) { case ocr2keepers.LogTrigger: logTriggerIDs = append(logTriggerIDs, id) + default: } } From 6f8a302fe11f5409af6aaeca5d8f7110e6bd6ae4 Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 6 Sep 2023 14:25:45 -0400 Subject: [PATCH 34/88] BCF-2497: Refactoring sessions orm query pattern to avoid a confusing rollback tx error log (#10378) * fix/BCF-2497-session-error-log: refactoring sessions orm to avoid a confusing rollback tx error log * fix/BCF-2497: updating changelog * fix/BCF-2497: refactoring out redundant query implementations * fix/BCF-2497: decomposition and redundancy refactoring --- core/sessions/orm.go | 57 ++++++++++++++++++++------------------- core/sessions/orm_test.go | 6 ++--- docs/CHANGELOG.md | 5 ++-- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/core/sessions/orm.go b/core/sessions/orm.go index a4060ce487c..eaac211f242 100644 --- a/core/sessions/orm.go +++ b/core/sessions/orm.go @@ -86,43 +86,44 @@ func (o *orm) ListUsers() (users []User, err error) { return } +// findValidSession finds an unexpired session by its ID and returns the associated email. +func (o *orm) findValidSession(sessionID string) (email string, err error) { + if err := o.q.Get(&email, "SELECT email FROM sessions WHERE id = $1 AND last_used + $2 >= now() FOR UPDATE", sessionID, o.sessionDuration); err != nil { + o.lggr.Infof("query result: %v", email) + return email, errors.Wrap(err, "no matching user for provided session token") + } + return email, nil +} + +// updateSessionLastUsed updates a session by its ID and sets the LastUsed field to now(). +func (o *orm) updateSessionLastUsed(sessionID string) error { + return o.q.ExecQ("UPDATE sessions SET last_used = now() WHERE id = $1", sessionID) +} + // ErrUserSessionExpired defines the error triggered when the user session has expired -var ErrUserSessionExpired = errors.New("session missing or expired, please login again") +var ( + ErrUserSessionExpired = errors.New("user session missing or expired, please login again") + ErrEmptySessionID = errors.New("session ID cannot be empty") +) // AuthorizedUserWithSession will return the API user associated with the Session ID if it // exists and hasn't expired, and update session's LastUsed field. -func (o *orm) AuthorizedUserWithSession(sessionID string) (User, error) { +func (o *orm) AuthorizedUserWithSession(sessionID string) (user User, err error) { if len(sessionID) == 0 { - return User{}, errors.New("Session ID cannot be empty") + return User{}, ErrEmptySessionID } - var user User - err := o.q.Transaction(func(tx pg.Queryer) error { - // First find user based on session token - var foundSession struct { - Email string - Valid bool - } - if err := tx.Get(&foundSession, "SELECT email, last_used + $2 >= now() as valid FROM sessions WHERE id = $1 FOR UPDATE", sessionID, o.sessionDuration); err != nil { - return errors.Wrap(err, "no matching user for provided session token") - } - - if !foundSession.Valid { - return ErrUserSessionExpired - } - - if err := tx.Get(&user, "SELECT * FROM users WHERE lower(email) = lower($1)", foundSession.Email); err != nil { - return errors.Wrap(err, "no matching user for provided session email") - } - // Session valid and tied to user, update last_used - _, err := tx.Exec("UPDATE sessions SET last_used = now() WHERE id = $1 AND last_used + $2 >= now()", sessionID, o.sessionDuration) - if err != nil { - return errors.Wrap(err, "unable to update sessions table") - } - return nil - }) + email, err := o.findValidSession(sessionID) + if err != nil { + return User{}, ErrUserSessionExpired + } + user, err = o.findUser(email) if err != nil { + return User{}, ErrUserSessionExpired + } + + if err := o.updateSessionLastUsed(sessionID); err != nil { return User{}, err } diff --git a/core/sessions/orm_test.go b/core/sessions/orm_test.go index 681b50987bf..804ea2dbb87 100644 --- a/core/sessions/orm_test.go +++ b/core/sessions/orm_test.go @@ -59,9 +59,9 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) { wantEmail string }{ {"authorized", "correctID", cltest.MustParseDuration(t, "3m"), "", "have@email"}, - {"expired", "correctID", cltest.MustParseDuration(t, "0m"), "session missing or expired, please login again", ""}, - {"incorrect", "wrong", cltest.MustParseDuration(t, "3m"), "no matching user for provided session token: sql: no rows in result set", ""}, - {"empty", "", cltest.MustParseDuration(t, "3m"), "Session ID cannot be empty", ""}, + {"expired", "correctID", cltest.MustParseDuration(t, "0m"), sessions.ErrUserSessionExpired.Error(), ""}, + {"incorrect", "wrong", cltest.MustParseDuration(t, "3m"), sessions.ErrUserSessionExpired.Error(), ""}, + {"empty", "", cltest.MustParseDuration(t, "3m"), sessions.ErrEmptySessionID.Error(), ""}, } for _, test := range tests { diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 93ae8b611f5..f75628dcfb5 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,9 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [dev] ### Fixed + - Unauthenticated users executing CLI commands previously generated a confusing error log, which is now removed: +```[ERROR] Error in transaction, rolling back: session missing or expired, please login again pg/transaction.go:118 ``` - Fixed a bug that was preventing job runs to be displayed when the job `chainID` was disabled. - +... ## 2.5.0 - UNRELEASED ### Fixed @@ -21,7 +23,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Upcoming Required Configuration Change - Starting in 2.6.0, chainlink nodes will no longer allow insecure configuration for production builds. Any TOML configuration that sets the following line will fail validation checks in `node start` or `node validate`: - ``` AllowSimplePasswords=true ``` From 0e3b37939992d1ef4d8537d2f247339cb4b4fa09 Mon Sep 17 00:00:00 2001 From: David Cauchi <13139524+davidcauchi@users.noreply.github.com> Date: Wed, 6 Sep 2023 20:57:10 +0200 Subject: [PATCH 35/88] Switch integration tests to nightly (#10520) --- .github/workflows/integration-tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 8c1d5be828c..2e4a710ac97 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -3,8 +3,7 @@ on: merge_group: pull_request: schedule: - # - cron: "0 0 * * *" - - cron: "0 * * * *" # every hour while we debug for flakes + - cron: "0 0 * * *" push: tags: - "*" From a0e97cfefc7cfdc531e3790ad4e86d629aa0c8fe Mon Sep 17 00:00:00 2001 From: Morgan Kuphal <87319522+KuphJr@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:10:56 -0500 Subject: [PATCH 36/88] TT-562 Improved load test client contract (#10504) * Improved load test client contract * added missing param comment * fix load test * add secrets load params --------- Co-authored-by: skudasov --- .../testhelpers/FunctionsLoadTestClient.sol | 85 ++++++++++++++----- .../functions_load_test_client.go | 84 ++++++++++++------ ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../contracts/contract_models.go | 1 + .../contracts/ethereum_contracts.go | 16 +++- integration-tests/load/functions/config.go | 2 + integration-tests/load/functions/config.toml | 10 ++- .../load/functions/functions_test.go | 8 +- .../load/functions/request_gun.go | 37 ++++---- 9 files changed, 170 insertions(+), 75 deletions(-) diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol index 047b45e9562..7327dc26f78 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol @@ -11,11 +11,11 @@ import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.so contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { using FunctionsRequest for FunctionsRequest.Request; - uint32 public constant MAX_CALLBACK_GAS = 70_000; + uint32 public constant MAX_CALLBACK_GAS = 250_000; bytes32 public lastRequestID; - bytes32 public lastResponse; - bytes32 public lastError; + bytes public lastResponse; + bytes public lastError; uint32 public totalRequests; uint32 public totalEmptyResponses; uint32 public totalSucceededResponses; @@ -25,10 +25,12 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { /** * @notice Send a simple request + * @param times Number of times to send the request * @param source JavaScript source code * @param encryptedSecretsReferences Encrypted secrets payload * @param args List of arguments accessible from within the source code * @param subscriptionId Billing ID + * @param donId DON ID */ function sendRequest( uint32 times, @@ -36,7 +38,7 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { bytes calldata encryptedSecretsReferences, string[] calldata args, uint64 subscriptionId, - bytes32 jobId + bytes32 donId ) external onlyOwner { FunctionsRequest.Request memory req; req.initializeRequestForInlineJavaScript(source); @@ -44,7 +46,57 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { if (args.length > 0) req.setArgs(args); uint i = 0; for (i = 0; i < times; i++) { - lastRequestID = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId); + lastRequestID = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, donId); + totalRequests += 1; + } + } + + /** + * @notice Same as sendRequest but for DONHosted secrets + * @param times Number of times to send the request + * @param source JavaScript source code + * @param slotId DON hosted secrets slot ID + * @param slotVersion DON hosted secrets slot version + * @param args List of arguments accessible from within the source code + * @param subscriptionId Billing ID + * @param donId DON ID + */ + function sendRequestWithDONHostedSecrets( + uint32 times, + string calldata source, + uint8 slotId, + uint64 slotVersion, + string[] calldata args, + uint64 subscriptionId, + bytes32 donId + ) public onlyOwner { + FunctionsRequest.Request memory req; + req.initializeRequestForInlineJavaScript(source); + req.addDONHostedSecrets(slotId, slotVersion); + if (args.length > 0) req.setArgs(args); + uint i = 0; + for (i = 0; i < times; i++) { + lastRequestID = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, donId); + totalRequests += 1; + } + } + + /** + * @notice Sends a Chainlink Functions request that has already been CBOR encoded + * @param times Number of times to send the request + * @param cborEncodedRequest The CBOR encoded bytes data for a Functions request + * @param subscriptionId The subscription ID that will be charged to service the request + * @param donId DON ID + */ + function sendEncodedRequest( + uint32 times, + bytes memory cborEncodedRequest, + uint64 subscriptionId, + bytes32 donId + ) public onlyOwner { + uint i = 0; + for (i = 0; i < times; i++) { + lastRequestID = _sendRequest(cborEncodedRequest, subscriptionId, MAX_CALLBACK_GAS, donId); totalRequests += 1; } } @@ -59,7 +111,12 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { totalEmptyResponses = 0; } - function getStats() public view onlyOwner returns (bytes32, bytes32, bytes32, uint32, uint32, uint32, uint32) { + function getStats() + public + view + onlyOwner + returns (bytes32, bytes memory, bytes memory, uint32, uint32, uint32, uint32) + { return ( lastRequestID, lastResponse, @@ -79,10 +136,9 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { * Either response or error parameter will be set, but never both */ function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override { - // Save only the first 32 bytes of response/error to always fit within MAX_CALLBACK_GAS lastRequestID = requestId; - lastResponse = bytesToBytes32(response); - lastError = bytesToBytes32(err); + lastResponse = response; + lastError = err; if (response.length == 0) { totalEmptyResponses += 1; } @@ -93,15 +149,4 @@ contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { totalSucceededResponses += 1; } } - - function bytesToBytes32(bytes memory b) private pure returns (bytes32 out) { - uint256 maxLen = 32; - if (b.length < 32) { - maxLen = b.length; - } - for (uint256 i = 0; i < maxLen; ++i) { - out |= bytes32(b[i]) >> (i * 8); - } - return out; - } } diff --git a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go index d4f8d1fc7e6..1f399700b1c 100644 --- a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go +++ b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go @@ -31,8 +31,8 @@ var ( ) var FunctionsLoadTestClientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStats\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resetStats\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalEmptyResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalFailedResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSucceededResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001cc238038062001cc2833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051611aed620001d56000396000818161027e0152610c220152611aed6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063724ec8a2116100975780638da5cb5b116100665780638da5cb5b146101c3578063c59d4847146101eb578063c9429e2a14610233578063f2fde38b1461025357600080fd5b8063724ec8a21461019057806379ba509714610198578063887efe94146101a05780638aea61dc146101b357600080fd5b806347c03186116100d357806347c031861461015c5780635c1d92e91461016557806362747e421461017d5780636d9809a01461018657600080fd5b80630ca76175146100fa57806329f0de3f1461010f5780632ab424da1461012b575b600080fd5b61010d6101083660046114e5565b610266565b005b61011860045481565b6040519081526020015b60405180910390f35b6005546101479068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b61011860025481565b60055461014790640100000000900463ffffffff1681565b61011860035481565b6101476201117081565b61010d6102e5565b61010d610326565b61010d6101ae3660046115fd565b610428565b6005546101479063ffffffff1681565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b6101f36105a2565b6040805197885260208801969096529486019390935263ffffffff91821660608601528116608085015290811660a08401521660c082015260e001610122565b600554610147906c01000000000000000000000000900463ffffffff1681565b61010d6102613660046116cc565b610607565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102d5576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102e083838361061b565b505050565b6102ed610723565b600060028190556003819055600455600580547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610430610723565b6104796040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6104bb89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506107a69050565b85156105035761050387878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506107b79050565b831561051d5761051d6105168587611702565b8290610801565b60005b8a63ffffffff168110156105955761054561053a83610844565b856201117086610c1d565b600255600580546001919060009061056490849063ffffffff166117c9565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061058d906117ed565b915050610520565b5050505050505050505050565b60008060008060008060006105b5610723565b50506002546003546004546005549298919750955063ffffffff8083169550680100000000000000008304811694506c0100000000000000000000000083048116935064010000000090920490911690565b61060f610723565b61061881610cfc565b50565b600283905561062982610df1565b60035561063581610df1565b6004558151600003610682576001600560048282829054906101000a900463ffffffff1661066391906117c9565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b8051156106ca5760016005600c8282829054906101000a900463ffffffff166106ab91906117c9565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b8151158015906106d957508051155b156102e0576001600560088282829054906101000a900463ffffffff1661070091906117c9565b92506101000a81548163ffffffff021916908363ffffffff160217905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103a3565b565b6107b38260008084610e73565b5050565b80516000036107f2576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b805160000361083c576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b60606000610853610100610f0a565b905061089d6040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610f2b90919063ffffffff16565b82516108bb9060028111156108b4576108b4611825565b8290610f44565b60408051808201909152600881527f6c616e677561676500000000000000000000000000000000000000000000000060208201526108fa908290610f2b565b60408301516109119080156108b4576108b4611825565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610950908290610f2b565b6060830151610960908290610f2b565b60a083015151156109ba5760408051808201909152601081527f726571756573745369676e61747572650000000000000000000000000000000060208201526109aa908290610f2b565b60a08301516109ba908290610f79565b60c08301515115610a675760408051808201909152600481527f61726773000000000000000000000000000000000000000000000000000000006020820152610a04908290610f2b565b610a0d81610f86565b60005b8360c0015151811015610a5d57610a4d8460c001518281518110610a3657610a36611854565b602002602001015183610f2b90919063ffffffff16565b610a56816117ed565b9050610a10565b50610a6781610faa565b60808301515115610b6857600083602001516002811115610a8a57610a8a611825565b03610ac1576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610b00908290610f2b565b610b19836020015160028111156108b4576108b4611825565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610b58908290610f2b565b6080830151610b68908290610f79565b60e08301515115610c155760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610bb2908290610f2b565b610bbb81610f86565b60005b8360e0015151811015610c0b57610bfb8460e001518281518110610be457610be4611854565b602002602001015183610f7990919063ffffffff16565b610c04816117ed565b9050610bbe565b50610c1581610faa565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610c82959493929190611883565b6020604051808303816000875af1158015610ca1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc59190611923565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610d7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103a3565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610e06575081515b60005b81811015610e6c57610e1c81600861193c565b848281518110610e2e57610e2e611854565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610e65816117ed565b9050610e09565b5050919050565b8051600003610eae576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610ec157610ec1611825565b90816002811115610ed457610ed4611825565b90525060408401828015610eea57610eea611825565b90818015610efa57610efa611825565b9052506060909301929092525050565b610f1261139c565b8051610f1e9083610fc8565b5060006020820152919050565b610f388260038351611042565b81516102e09082611169565b8151610f519060c2611191565b506107b38282604051602001610f6991815260200190565b6040516020818303038152906040525b610f388260028351611042565b610f918160046111fa565b600181602001818151610fa49190611953565b90525050565b610fb58160076111fa565b600181602001818151610fa49190611966565b604080518082019091526060815260006020820152610fe8602083611979565b1561101057610ff8602083611979565b611003906020611966565b61100d9083611953565b91505b60208084018390526040518085526000815290818401018181101561103457600080fd5b604052508290505b92915050565b60178167ffffffffffffffff161161106f5782516110699060e0600585901b168317611191565b50505050565b60ff8167ffffffffffffffff16116110b1578251611098906018611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166001611211565b61ffff8167ffffffffffffffff16116110f45782516110db906019611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166002611211565b63ffffffff8167ffffffffffffffff161161113957825161112090601a611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166004611211565b825161115090601b611fe0600586901b1617611191565b5082516110699067ffffffffffffffff83166008611211565b60408051808201909152606081526000602082015261118a83838451611296565b9392505050565b60408051808201909152606081526000602082015282515160006111b6826001611953565b9050846020015182106111d7576111d7856111d283600261193c565b611385565b84516020838201018581535080518211156111f0578181525b5093949350505050565b81516102e090601f611fe0600585901b1617611191565b60408051808201909152606081526000602082015283515160006112358285611953565b9050856020015181111561125257611252866111d283600261193c565b6000600161126286610100611ad4565b61126c9190611966565b9050865182810187831982511617815250805183111561128a578281525b50959695505050505050565b60408051808201909152606081526000602082015282518211156112b957600080fd5b83515160006112c88483611953565b905085602001518111156112e5576112e5866111d283600261193c565b8551805183820160200191600091808511156112ff578482525b505050602086015b6020861061133f578051825261131e602083611953565b915061132b602082611953565b9050611338602087611966565b9550611307565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516113918383610fc8565b506110698382611169565b60405180604001604052806113c4604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611447576114476113d1565b604052919050565b600067ffffffffffffffff831115611469576114696113d1565b61149a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611400565b90508281528383830111156114ae57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126114d657600080fd5b61118a8383356020850161144f565b6000806000606084860312156114fa57600080fd5b83359250602084013567ffffffffffffffff8082111561151957600080fd5b611525878388016114c5565b9350604086013591508082111561153b57600080fd5b50611548868287016114c5565b9150509250925092565b60008083601f84011261156457600080fd5b50813567ffffffffffffffff81111561157c57600080fd5b60208301915083602082850101111561159457600080fd5b9250929050565b60008083601f8401126115ad57600080fd5b50813567ffffffffffffffff8111156115c557600080fd5b6020830191508360208260051b850101111561159457600080fd5b803567ffffffffffffffff811681146115f857600080fd5b919050565b600080600080600080600080600060c08a8c03121561161b57600080fd5b893563ffffffff8116811461162f57600080fd5b985060208a013567ffffffffffffffff8082111561164c57600080fd5b6116588d838e01611552565b909a50985060408c013591508082111561167157600080fd5b61167d8d838e01611552565b909850965060608c013591508082111561169657600080fd5b506116a38c828d0161159b565b90955093506116b6905060808b016115e0565b915060a08a013590509295985092959850929598565b6000602082840312156116de57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461118a57600080fd5b600067ffffffffffffffff8084111561171d5761171d6113d1565b8360051b602061172e818301611400565b86815291850191818101903684111561174657600080fd5b865b8481101561178e578035868111156117605760008081fd5b880136601f8201126117725760008081fd5b61178036823587840161144f565b845250918301918301611748565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8181168382160190808211156117e6576117e661179a565b5092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361181e5761181e61179a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156118c15788810183015185820160c0015282016118a5565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505061190a604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b60006020828403121561193557600080fd5b5051919050565b808202811582820484141761103c5761103c61179a565b8082018082111561103c5761103c61179a565b8181038181111561103c5761103c61179a565b6000826119af577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b80851115611a0d57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156119f3576119f361179a565b80851615611a0057918102915b93841c93908002906119b9565b509250929050565b600082611a245750600161103c565b81611a315750600061103c565b8160018114611a475760028114611a5157611a6d565b600191505061103c565b60ff841115611a6257611a6261179a565b50506001821b61103c565b5060208310610133831016604e8410600b8410161715611a90575081810a61103c565b611a9a83836119b4565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611acc57611acc61179a565b029392505050565b600061118a8383611a1556fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStats\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastError\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponse\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resetStats\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"cborEncodedRequest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendEncodedRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"slotId\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"slotVersion\",\"type\":\"uint64\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestWithDONHostedSecrets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalEmptyResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalFailedResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSucceededResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200243938038062002439833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051612264620001d5600039600081816102ac0152610fde01526122646000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c806379ba5097116100b2578063954491c111610081578063c59d484711610066578063c59d484714610246578063c9429e2a14610261578063f2fde38b1461028157600080fd5b8063954491c114610220578063b2518e0e1461023357600080fd5b806379ba5097146101cd578063887efe94146101d55780638aea61dc146101e85780638da5cb5b146101f857600080fd5b80635c1d92e9116100ee5780635c1d92e91461019b57806362747e42146101b35780636d9809a0146101bb578063724ec8a2146101c557600080fd5b80630ca761751461012057806329f0de3f146101355780632ab424da1461015357806347c0318614610184575b600080fd5b61013361012e3660046118ee565b610294565b005b61013d610313565b60405161014a91906119bf565b60405180910390f35b60055461016f9068010000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161014a565b61018d60025481565b60405190815260200161014a565b60055461016f90640100000000900463ffffffff1681565b61013d6103a1565b61016f6203d09081565b6101336103ae565b610133610420565b6101336101e3366004611a91565b610522565b60055461016f9063ffffffff1681565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014a565b61013361022e366004611b55565b61069c565b610133610241366004611c1b565b6107ba565b61024e610839565b60405161014a9796959493929190611c81565b60055461016f906c01000000000000000000000000900463ffffffff1681565b61013361028f366004611cde565b6109c1565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610303576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030e8383836109d5565b505050565b6004805461032090611d14565b80601f016020809104026020016040519081016040528092919081815260200182805461034c90611d14565b80156103995780601f1061036e57610100808354040283529160200191610399565b820191906000526020600020905b81548152906001019060200180831161037c57829003601f168201915b505050505081565b6003805461032090611d14565b6103b6610adf565b6000600281905560408051602081019091529081526003906103d89082611db5565b506040805160208101909152600081526004906103f59082611db5565b50600580547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61052a610adf565b6105736040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6105b589898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b629050565b85156105fd576105fd87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b739050565b8315610617576106176106108587611ecf565b8290610bbd565b60005b8a63ffffffff1681101561068f5761063f61063483610c00565b856203d09086610fd9565b600255600580546001919060009061065e90849063ffffffff16611f96565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061068790611fba565b91505061061a565b5050505050505050505050565b6106a4610adf565b6106ed6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b61072f89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b629050565b61073a8188886110b8565b831561074d5761074d6106108587611ecf565b60005b8a63ffffffff1681101561068f5761076a61063483610c00565b600255600580546001919060009061078990849063ffffffff16611f96565b92506101000a81548163ffffffff021916908363ffffffff16021790555080806107b290611fba565b915050610750565b6107c2610adf565b60005b8463ffffffff16811015610832576107e284846203d09085610fd9565b600255600580546001919060009061080190849063ffffffff16611f96565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061082a90611fba565b9150506107c5565b5050505050565b600060608060008060008061084c610adf565b60025460055460038054909160049163ffffffff808316926801000000000000000081048216926c01000000000000000000000000820483169264010000000090920490911690869061089e90611d14565b80601f01602080910402602001604051908101604052809291908181526020018280546108ca90611d14565b80156109175780601f106108ec57610100808354040283529160200191610917565b820191906000526020600020905b8154815290600101906020018083116108fa57829003601f168201915b5050505050955084805461092a90611d14565b80601f016020809104026020016040519081016040528092919081815260200182805461095690611d14565b80156109a35780601f10610978576101008083540402835291602001916109a3565b820191906000526020600020905b81548152906001019060200180831161098657829003601f168201915b50505050509450965096509650965096509650965090919293949596565b6109c9610adf565b6109d28161117b565b50565b600283905560036109e68382611db5565b5060046109f38282611db5565b508151600003610a3e576001600560048282829054906101000a900463ffffffff16610a1f9190611f96565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b805115610a865760016005600c8282829054906101000a900463ffffffff16610a679190611f96565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b815115801590610a9557508051155b1561030e576001600560088282829054906101000a900463ffffffff16610abc9190611f96565b92506101000a81548163ffffffff021916908363ffffffff160217905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161049d565b565b610b6f8260008084611270565b5050565b8051600003610bae576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610bf8576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b60606000610c0f610100611307565b9050610c596040518060400160405280600c81526020017f636f64654c6f636174696f6e00000000000000000000000000000000000000008152508261132890919063ffffffff16565b8251610c77906002811115610c7057610c70611ff2565b8290611341565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610cb6908290611328565b6040830151610ccd908015610c7057610c70611ff2565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610d0c908290611328565b6060830151610d1c908290611328565b60a08301515115610d765760408051808201909152601081527f726571756573745369676e6174757265000000000000000000000000000000006020820152610d66908290611328565b60a0830151610d76908290611376565b60c08301515115610e235760408051808201909152600481527f61726773000000000000000000000000000000000000000000000000000000006020820152610dc0908290611328565b610dc981611383565b60005b8360c0015151811015610e1957610e098460c001518281518110610df257610df2612021565b60200260200101518361132890919063ffffffff16565b610e1281611fba565b9050610dcc565b50610e23816113a7565b60808301515115610f2457600083602001516002811115610e4657610e46611ff2565b03610e7d576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610ebc908290611328565b610ed583602001516002811115610c7057610c70611ff2565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610f14908290611328565b6080830151610f24908290611376565b60e08301515115610fd15760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610f6e908290611328565b610f7781611383565b60005b8360e0015151811015610fc757610fb78460e001518281518110610fa057610fa0612021565b60200260200101518361137690919063ffffffff16565b610fc081611fba565b9050610f7a565b50610fd1816113a7565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b815260040161103e959493929190612050565b6020604051808303816000875af115801561105d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611081919061209a565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b60006110c5610100611307565b905061110f6040518060400160405280600681526020017f736c6f74494400000000000000000000000000000000000000000000000000008152508261132890919063ffffffff16565b61111c8160ff85166113c5565b60408051808201909152600781527f76657273696f6e00000000000000000000000000000000000000000000000000602082015261115b908290611328565b61116581836113c5565b6002602085015251516080909301929092525050565b3373ffffffffffffffffffffffffffffffffffffffff8216036111fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161049d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516000036112ab576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838360028111156112be576112be611ff2565b908160028111156112d1576112d1611ff2565b905250604084018280156112e7576112e7611ff2565b908180156112f7576112f7611ff2565b9052506060909301929092525050565b61130f6117a5565b805161131b90836113d1565b5060006020820152919050565b611335826003835161144b565b815161030e9082611572565b815161134e9060c261159a565b50610b6f828260405160200161136691815260200190565b6040516020818303038152906040525b611335826002835161144b565b61138e816004611603565b6001816020018181516113a191906120b3565b90525050565b6113b2816007611603565b6001816020018181516113a191906120c6565b610b6f8260008361144b565b6040805180820190915260608152600060208201526113f16020836120d9565b15611419576114016020836120d9565b61140c9060206120c6565b61141690836120b3565b91505b60208084018390526040518085526000815290818401018181101561143d57600080fd5b604052508290505b92915050565b60178167ffffffffffffffff16116114785782516114729060e0600585901b16831761159a565b50505050565b60ff8167ffffffffffffffff16116114ba5782516114a1906018611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600161161a565b61ffff8167ffffffffffffffff16116114fd5782516114e4906019611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600261161a565b63ffffffff8167ffffffffffffffff161161154257825161152990601a611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600461161a565b825161155990601b611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600861161a565b6040805180820190915260608152600060208201526115938383845161169f565b9392505050565b60408051808201909152606081526000602082015282515160006115bf8260016120b3565b9050846020015182106115e0576115e0856115db836002612114565b61178e565b84516020838201018581535080518211156115f9578181525b5093949350505050565b815161030e90601f611fe0600585901b161761159a565b604080518082019091526060815260006020820152835151600061163e82856120b3565b9050856020015181111561165b5761165b866115db836002612114565b6000600161166b8661010061224b565b61167591906120c6565b90508651828101878319825116178152508051831115611693578281525b50959695505050505050565b60408051808201909152606081526000602082015282518211156116c257600080fd5b83515160006116d184836120b3565b905085602001518111156116ee576116ee866115db836002612114565b855180518382016020019160009180851115611708578482525b505050602086015b6020861061174857805182526117276020836120b3565b91506117346020826120b3565b90506117416020876120c6565b9550611710565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b815161179a83836113d1565b506114728382611572565b60405180604001604052806117cd604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611850576118506117da565b604052919050565b600067ffffffffffffffff831115611872576118726117da565b6118a360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611809565b90508281528383830111156118b757600080fd5b828260208301376000602084830101529392505050565b600082601f8301126118df57600080fd5b61159383833560208501611858565b60008060006060848603121561190357600080fd5b83359250602084013567ffffffffffffffff8082111561192257600080fd5b61192e878388016118ce565b9350604086013591508082111561194457600080fd5b50611951868287016118ce565b9150509250925092565b6000815180845260005b8181101561198157602081850181015186830182015201611965565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611593602083018461195b565b803563ffffffff811681146119e657600080fd5b919050565b60008083601f8401126119fd57600080fd5b50813567ffffffffffffffff811115611a1557600080fd5b602083019150836020828501011115611a2d57600080fd5b9250929050565b60008083601f840112611a4657600080fd5b50813567ffffffffffffffff811115611a5e57600080fd5b6020830191508360208260051b8501011115611a2d57600080fd5b803567ffffffffffffffff811681146119e657600080fd5b600080600080600080600080600060c08a8c031215611aaf57600080fd5b611ab88a6119d2565b985060208a013567ffffffffffffffff80821115611ad557600080fd5b611ae18d838e016119eb565b909a50985060408c0135915080821115611afa57600080fd5b611b068d838e016119eb565b909850965060608c0135915080821115611b1f57600080fd5b50611b2c8c828d01611a34565b9095509350611b3f905060808b01611a79565b915060a08a013590509295985092959850929598565b600080600080600080600080600060e08a8c031215611b7357600080fd5b611b7c8a6119d2565b985060208a013567ffffffffffffffff80821115611b9957600080fd5b611ba58d838e016119eb565b909a50985060408c0135915060ff82168214611bc057600080fd5b819750611bcf60608d01611a79565b965060808c0135915080821115611be557600080fd5b50611bf28c828d01611a34565b9095509350611c05905060a08b01611a79565b915060c08a013590509295985092959850929598565b60008060008060808587031215611c3157600080fd5b611c3a856119d2565b9350602085013567ffffffffffffffff811115611c5657600080fd5b611c62878288016118ce565b935050611c7160408601611a79565b9396929550929360600135925050565b87815260e060208201526000611c9a60e083018961195b565b8281036040840152611cac818961195b565b63ffffffff97881660608501529587166080840152505091841660a083015290921660c0909201919091529392505050565b600060208284031215611cf057600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461159357600080fd5b600181811c90821680611d2857607f821691505b602082108103611d61577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561030e57600081815260208120601f850160051c81016020861015611d8e5750805b601f850160051c820191505b81811015611dad57828155600101611d9a565b505050505050565b815167ffffffffffffffff811115611dcf57611dcf6117da565b611de381611ddd8454611d14565b84611d67565b602080601f831160018114611e365760008415611e005750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611dad565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611e8357888601518255948401946001909101908401611e64565b5085821015611ebf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600067ffffffffffffffff80841115611eea57611eea6117da565b8360051b6020611efb818301611809565b868152918501918181019036841115611f1357600080fd5b865b84811015611f5b57803586811115611f2d5760008081fd5b880136601f820112611f3f5760008081fd5b611f4d368235878401611858565b845250918301918301611f15565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff818116838216019080821115611fb357611fb3611f67565b5092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611feb57611feb611f67565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8616815260a06020820152600061207360a083018761195b565b61ffff9590951660408301525063ffffffff92909216606083015260809091015292915050565b6000602082840312156120ac57600080fd5b5051919050565b8082018082111561144557611445611f67565b8181038181111561144557611445611f67565b60008261210f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b808202811582820484141761144557611445611f67565b600181815b8085111561218457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561216a5761216a611f67565b8085161561217757918102915b93841c9390800290612130565b509250929050565b60008261219b57506001611445565b816121a857506000611445565b81600181146121be57600281146121c8576121e4565b6001915050611445565b60ff8411156121d9576121d9611f67565b50506001821b611445565b5060208310610133831016604e8410600b8410161715612207575081810a611445565b612211838361212b565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561224357612243611f67565b029392505050565b6000611593838361218c56fea164736f6c6343000813000a", } var FunctionsLoadTestClientABI = FunctionsLoadTestClientMetaData.ABI @@ -193,17 +193,17 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) MAXCALLBAC return _FunctionsLoadTestClient.Contract.MAXCALLBACKGAS(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) GetStats(opts *bind.CallOpts) ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) GetStats(opts *bind.CallOpts) ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error) { var out []interface{} err := _FunctionsLoadTestClient.contract.Call(opts, &out, "getStats") if err != nil { - return *new([32]byte), *new([32]byte), *new([32]byte), *new(uint32), *new(uint32), *new(uint32), *new(uint32), err + return *new([32]byte), *new([]byte), *new([]byte), *new(uint32), *new(uint32), *new(uint32), *new(uint32), err } out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - out1 := *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) - out2 := *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte) + out2 := *abi.ConvertType(out[2], new([]byte)).(*[]byte) out3 := *abi.ConvertType(out[3], new(uint32)).(*uint32) out4 := *abi.ConvertType(out[4], new(uint32)).(*uint32) out5 := *abi.ConvertType(out[5], new(uint32)).(*uint32) @@ -213,33 +213,33 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) GetStats(opts *bi } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) GetStats() ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) GetStats() ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error) { return _FunctionsLoadTestClient.Contract.GetStats(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) GetStats() ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) GetStats() ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error) { return _FunctionsLoadTestClient.Contract.GetStats(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastError(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastError(opts *bind.CallOpts) ([]byte, error) { var out []interface{} err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastError") if err != nil { - return *new([32]byte), err + return *new([]byte), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) return out0, err } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastError() ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastError() ([]byte, error) { return _FunctionsLoadTestClient.Contract.LastError(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastError() ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastError() ([]byte, error) { return _FunctionsLoadTestClient.Contract.LastError(&_FunctionsLoadTestClient.CallOpts) } @@ -265,25 +265,25 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastReques return _FunctionsLoadTestClient.Contract.LastRequestID(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastResponse(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastResponse(opts *bind.CallOpts) ([]byte, error) { var out []interface{} err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastResponse") if err != nil { - return *new([32]byte), err + return *new([]byte), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) return out0, err } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastResponse() ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastResponse() ([]byte, error) { return _FunctionsLoadTestClient.Contract.LastResponse(&_FunctionsLoadTestClient.CallOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastResponse() ([32]byte, error) { +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastResponse() ([]byte, error) { return _FunctionsLoadTestClient.Contract.LastResponse(&_FunctionsLoadTestClient.CallOpts) } @@ -433,16 +433,40 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) ResetS return _FunctionsLoadTestClient.Contract.ResetStats(&_FunctionsLoadTestClient.TransactOpts) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequest", times, source, encryptedSecretsReferences, args, subscriptionId, jobId) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendEncodedRequest(opts *bind.TransactOpts, times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "sendEncodedRequest", times, cborEncodedRequest, subscriptionId, donId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendEncodedRequest(times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendEncodedRequest(&_FunctionsLoadTestClient.TransactOpts, times, cborEncodedRequest, subscriptionId, donId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendEncodedRequest(times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendEncodedRequest(&_FunctionsLoadTestClient.TransactOpts, times, cborEncodedRequest, subscriptionId, donId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequest", times, source, encryptedSecretsReferences, args, subscriptionId, donId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, donId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, donId) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, jobId) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequestWithDONHostedSecrets(opts *bind.TransactOpts, times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequestWithDONHostedSecrets", times, source, slotId, slotVersion, args, subscriptionId, donId) } -func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, jobId) +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequestWithDONHostedSecrets(times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequestWithDONHostedSecrets(&_FunctionsLoadTestClient.TransactOpts, times, source, slotId, slotVersion, args, subscriptionId, donId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequestWithDONHostedSecrets(times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequestWithDONHostedSecrets(&_FunctionsLoadTestClient.TransactOpts, times, source, slotId, slotVersion, args, subscriptionId, donId) } func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -1022,13 +1046,13 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClient) Address() common.Addres type FunctionsLoadTestClientInterface interface { MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error) - GetStats(opts *bind.CallOpts) ([32]byte, [32]byte, [32]byte, uint32, uint32, uint32, uint32, error) + GetStats(opts *bind.CallOpts) ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error) - LastError(opts *bind.CallOpts) ([32]byte, error) + LastError(opts *bind.CallOpts) ([]byte, error) LastRequestID(opts *bind.CallOpts) ([32]byte, error) - LastResponse(opts *bind.CallOpts) ([32]byte, error) + LastResponse(opts *bind.CallOpts) ([]byte, error) Owner(opts *bind.CallOpts) (common.Address, error) @@ -1046,7 +1070,11 @@ type FunctionsLoadTestClientInterface interface { ResetStats(opts *bind.TransactOpts) (*types.Transaction, error) - SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) + SendEncodedRequest(opts *bind.TransactOpts, times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) + + SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) + + SendRequestWithDONHostedSecrets(opts *bind.TransactOpts, times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) 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 46f10db9d5d..0d7dc5a6217 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 @@ -5,7 +5,7 @@ functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin 25036bdb94a50a81df4222418bf9aa1e0c8540d5834b7e6e639aa63a2a2c8206 functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin e453fd45029ff99658d029bfbb8711b748c432323f12585c039a30977e801a79 -functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin 08b0ba467a0d2913ad146c293cc92ed1e0e5f25398bc8185addf9c4c1a41df2c +functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin 1323b4ee0bcefd61a248177cf84d98015ae08e2b05223e06a1724112efdca8cd functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin dd1d3527e19d65efe029c4a131ded44dc0ca961e5c4f459743992435431ec478 functions_v1_events_mock: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.bin 0f0ba42e0cc33c7abc8b8fd4fdfce903748a169886dd5f16cfdd56e75bcf708d diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index 941eba73ebf..8e9d561f822 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -365,4 +365,5 @@ type FunctionsLoadTestClient interface { ResetStats() error GetStats() (*EthereumFunctionsLoadStats, error) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error + SendRequestWithDONHostedSecrets(times uint32, source string, slotID uint8, slotVersion uint64, args []string, subscriptionId uint64, donID [32]byte) error } diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 8f80ed3896c..5e937ad9b72 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -2197,8 +2197,8 @@ func (e *EthereumFunctionsLoadTestClient) GetStats() (*EthereumFunctionsLoadStat } return &EthereumFunctionsLoadStats{ LastRequestID: string(Bytes32ToSlice(lr)), - LastResponse: string(Bytes32ToSlice(lbody)), - LastError: string(Bytes32ToSlice(lerr)), + LastResponse: string(lbody), + LastError: string(lerr), Total: total, Succeeded: succeeded, Errored: errored, @@ -2232,3 +2232,15 @@ func (e *EthereumFunctionsLoadTestClient) SendRequest(times uint32, source strin } return e.client.ProcessTransaction(tx) } + +func (e *EthereumFunctionsLoadTestClient) SendRequestWithDONHostedSecrets(times uint32, source string, slotID uint8, slotVersion uint64, args []string, subscriptionId uint64, donID [32]byte) error { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := e.instance.SendRequestWithDONHostedSecrets(opts, times, source, slotID, slotVersion, args, subscriptionId, donID) + if err != nil { + return err + } + return e.client.ProcessTransaction(tx) +} diff --git a/integration-tests/load/functions/config.go b/integration-tests/load/functions/config.go index 9f0a5bda0c7..b18549f460b 100644 --- a/integration-tests/load/functions/config.go +++ b/integration-tests/load/functions/config.go @@ -37,6 +37,8 @@ type Common struct { Receiver string `toml:"receiver"` FunctionsCallPayload string `toml:"functions_call_payload"` Secrets string `toml:"secrets"` + SecretsSlotID uint8 `toml:"secrets_slot_id"` + SecretsVersionID uint64 `toml:"secrets_version_id"` } type Funding struct { diff --git a/integration-tests/load/functions/config.toml b/integration-tests/load/functions/config.toml index a5cf4dbb379..f31342f0134 100644 --- a/integration-tests/load/functions/config.toml +++ b/integration-tests/load/functions/config.toml @@ -25,11 +25,13 @@ link_token_addr = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB" coordinator_addr = "0x6D6a83BB356b7242E88C1A2b290102fde26590D0" router_addr = "0x2673266D3Cd08b53494B5a92B66DEec7F1408E7A" # comment both client and sub to automatically create a new pair -client_addr = "0x64a351fbAa61681A5a7e569Cc5A691150c4D73D2" -subscription_id = 23 +client_addr = "0x89D4b58D859a536D0B888ecD5093eF5FF9e4F977" +subscription_id = 47 sub_funds = 10 -functions_call_payload = "const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); return Functions.encodeUint256(response.data.id)" -#functions_call_payload = "return Functions.encodeUint256(BigInt(secrets.ltsecret))" +#functions_call_payload = "const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); return Functions.encodeUint256(response.data.id)" +functions_call_payload = "return Functions.encodeString(JSON.stringify(secrets))" +secrets_slot_id = 0 +secrets_version = 1693945705 # uncomment to upload new secrets to s4 #secrets = "{\"ltsecret\": \"1\"}" \ No newline at end of file diff --git a/integration-tests/load/functions/functions_test.go b/integration-tests/load/functions/functions_test.go index 16311ac440b..c178fcc5e21 100644 --- a/integration-tests/load/functions/functions_test.go +++ b/integration-tests/load/functions/functions_test.go @@ -37,7 +37,8 @@ func TestFunctionsLoad(t *testing.T) { ft, cfg.Soak.RequestsPerCall, cfg.Common.FunctionsCallPayload, - []byte{}, + cfg.Common.SecretsSlotID, + cfg.Common.SecretsVersionID, []string{}, cfg.Common.SubscriptionID, StringToByte32(cfg.Common.DONID), @@ -63,9 +64,10 @@ func TestFunctionsLoad(t *testing.T) { ), Gun: NewSingleFunctionCallGun( ft, - cfg.Stress.RequestsPerCall, + cfg.Soak.RequestsPerCall, cfg.Common.FunctionsCallPayload, - []byte{}, + cfg.Common.SecretsSlotID, + cfg.Common.SecretsVersionID, []string{}, cfg.Common.SubscriptionID, StringToByte32(cfg.Common.DONID), diff --git a/integration-tests/load/functions/request_gun.go b/integration-tests/load/functions/request_gun.go index 5cbff36179e..f939b2583ab 100644 --- a/integration-tests/load/functions/request_gun.go +++ b/integration-tests/load/functions/request_gun.go @@ -7,33 +7,36 @@ import ( /* SingleFunctionCallGun is a gun that constantly requests randomness for one feed */ type SingleFunctionCallGun struct { - ft *FunctionsTest - times uint32 - source string - encryptedSecretsReferences []byte - args []string - subscriptionId uint64 - jobId [32]byte + ft *FunctionsTest + times uint32 + source string + slotID uint8 + slotVersion uint64 + args []string + subscriptionId uint64 + jobId [32]byte } -func NewSingleFunctionCallGun(ft *FunctionsTest, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) *SingleFunctionCallGun { +func NewSingleFunctionCallGun(ft *FunctionsTest, times uint32, source string, slotID uint8, slotVersion uint64, args []string, subscriptionId uint64, jobId [32]byte) *SingleFunctionCallGun { return &SingleFunctionCallGun{ - ft: ft, - times: times, - source: source, - encryptedSecretsReferences: encryptedSecretsReferences, - args: args, - subscriptionId: subscriptionId, - jobId: jobId, + ft: ft, + times: times, + source: source, + slotID: slotID, + slotVersion: slotVersion, + args: args, + subscriptionId: subscriptionId, + jobId: jobId, } } // Call implements example gun call, assertions on response bodies should be done here func (m *SingleFunctionCallGun) Call(l *wasp.Generator) *wasp.CallResult { - err := m.ft.LoadTestClient.SendRequest( + err := m.ft.LoadTestClient.SendRequestWithDONHostedSecrets( m.times, m.source, - m.encryptedSecretsReferences, + m.slotID, + m.slotVersion, m.args, m.subscriptionId, m.jobId, From c3d94fab91686113883c8dab9406047fd380daad Mon Sep 17 00:00:00 2001 From: Morgan Kuphal <87319522+KuphJr@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:52:01 -0500 Subject: [PATCH 37/88] Added log for decryption queue error (#10517) * added log * modified log --- core/services/functions/listener.go | 1 + core/services/ocr2/plugins/threshold/decryption_queue.go | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/services/functions/listener.go b/core/services/functions/listener.go index f7c94437654..e0bf5b79b03 100644 --- a/core/services/functions/listener.go +++ b/core/services/functions/listener.go @@ -728,6 +728,7 @@ func (l *FunctionsListener) getSecrets(ctx context.Context, eaClient ExternalAda decryptedSecretsBytes, err := l.decryptor.Decrypt(decryptCtx, requestID[:], secrets) if err != nil { + l.logger.Debugw("threshold decryption of secrets failed", "requestID", requestIDStr, "err", err) return "", errors.New("threshold decryption of secrets failed"), nil } return string(decryptedSecretsBytes), nil, nil diff --git a/core/services/ocr2/plugins/threshold/decryption_queue.go b/core/services/ocr2/plugins/threshold/decryption_queue.go index fae72685a2f..1ffc63e5898 100644 --- a/core/services/ocr2/plugins/threshold/decryption_queue.go +++ b/core/services/ocr2/plugins/threshold/decryption_queue.go @@ -171,7 +171,11 @@ func (dq *decryptionQueue) GetRequests(requestCountLimit int, totalBytesLimit in dq.pendingRequestQueue = removeMultipleIndices(dq.pendingRequestQueue, indicesToRemove) - dq.lggr.Debugf("returning first %d of %d total requests awaiting decryption", len(requests), len(dq.pendingRequestQueue)) + if len(dq.pendingRequestQueue) > 0 { + dq.lggr.Debugf("returning first %d of %d total requests awaiting decryption", len(requests), len(dq.pendingRequestQueue)) + } else { + dq.lggr.Debug("no requests awaiting decryption") + } return requests } From 2c0cb9c1da849f63af4a067b5d2ece7e768a942f Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Wed, 6 Sep 2023 16:52:45 -0400 Subject: [PATCH 38/88] (test): Add Functions Subscriptions foundry tests (#10435) * (test): Add Functions Subscriptions foundry tests * Changes from review * Add gas snapshot --- .../gas-snapshots/functions.gas-snapshot | 76 +- .../tests/1_0_0/FunctionsRouter.t.sol | 2 +- .../tests/1_0_0/FunctionsSubscriptions.t.sol | 926 +++++++++++++++++- .../src/v0.8/functions/tests/1_0_0/OCR2.t.sol | 0 .../src/v0.8/functions/tests/1_0_0/README.md | 22 + .../v0.8/functions/tests/1_0_0/Setup.t.sol | 178 +++- .../FunctionsCoordinatorTestHelper.sol | 4 + 7 files changed, 1156 insertions(+), 52 deletions(-) create mode 100644 contracts/src/v0.8/functions/tests/1_0_0/OCR2.t.sol create mode 100644 contracts/src/v0.8/functions/tests/1_0_0/README.md diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 7ee4f779d6a..56d8a4da7fd 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -12,6 +12,80 @@ FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13315) FunctionsRouter_Pause:test_Pause_Success() (gas: 20254) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13294) FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77334) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60355) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 60984) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94703) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62713) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 59611) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137842) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12914) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57789) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87166) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18006) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95394) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15041) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57863) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89296) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20103) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193421) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_Success() (gas: 67209) +FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7609) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28659) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17970) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 371776) +FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 16225) +FunctionsSubscriptions_GetFlags:test_GetFlags_Success() (gas: 40880) +FunctionsSubscriptions_GetSubscription:test_GetSubscription_Success() (gas: 30869) +FunctionsSubscriptions_GetSubscriptionCount:test_GetSubscriptionCount_Success() (gas: 12967) +FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15032) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCalldata() (gas: 27616) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 30093) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13424) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 35022) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 56121) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20745) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfBalanceInvariant() (gas: 189) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15638) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfPaused() (gas: 20833) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 59873) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessSetsBalanceToZero() (gas: 57842) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12818) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15549) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 52817) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 47539) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 48847) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 162051) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17946) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 165) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15577) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 37559) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54598) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37975) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14980) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175611) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27632) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57751) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15022) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 75152) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17981) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20126) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68148) +FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15554) +FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41111) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 29946) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 14997) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57778) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87210) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18004) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190641) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 41585) +FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12847) +FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15640) +FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35571) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25881) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25210) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28164) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57781) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26368) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15714) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152436) \ No newline at end of file +FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152510) \ No newline at end of file diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol index 649c06f9eed..ee75a27e3f4 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.19; import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol"; -import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfService} from "./Setup.t.sol"; +import {FunctionsRouterSetup} from "./Setup.t.sol"; // ================================================================ // | Functions Router | diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol index ab77a33691d..2fb0d4219cc 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol @@ -1,105 +1,422 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {BaseTest} from "./BaseTest.t.sol"; import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol"; +import {FunctionsResponse} from "../../dev/1_0_0/libraries/FunctionsResponse.sol"; -import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfService} from "./Setup.t.sol"; +import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfServiceSetup, FunctionsClientSetup, FunctionsSubscriptionSetup, FunctionsClientRequestSetup, FunctionsFulfillmentSetup} from "./Setup.t.sol"; // ================================================================ // | Functions Subscriptions | // ================================================================ +contract FunctionsSubscriptions_Constructor_Helper is FunctionsSubscriptions { + constructor(address link) FunctionsSubscriptions(link) {} + + function getLinkToken() public view returns (address) { + return i_linkToken; + } + + // overrides + function _getMaxConsumers() internal pure override returns (uint16) { + return 0; + } + + function _onlySenderThatAcceptedToS() internal override {} + + function _onlyRouterOwner() internal override {} + + function _whenNotPaused() internal override {} +} + /// @notice #constructor -contract FunctionsSubscriptions_Constructor { +contract FunctionsSubscriptions_Constructor is BaseTest { + FunctionsSubscriptions_Constructor_Helper s_subscriptionsHelper; + address internal s_linkToken = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709; + function setUp() public virtual override { + BaseTest.setUp(); + s_subscriptionsHelper = new FunctionsSubscriptions_Constructor_Helper(s_linkToken); + } + + function test_Constructor_Success() public { + assertEq(s_linkToken, s_subscriptionsHelper.getLinkToken()); + } } /// @notice #_markRequestInFlight contract FunctionsSubscriptions__MarkRequestInFlight { - + // TODO: make contract internal function helper } /// @notice #_pay contract FunctionsSubscriptions__Pay { - + // TODO: make contract internal function helper } /// @notice #ownerCancelSubscription -contract FunctionsSubscriptions_OwnerCancelSubscription { +contract FunctionsSubscriptions_OwnerCancelSubscription is FunctionsSubscriptionSetup { + function test_OwnerCancelSubscription_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsRouter.ownerCancelSubscription(s_subscriptionId); + } + function test_OwnerCancelSubscription_RevertIfNoSubscription() public { + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + uint64 invalidSubscriptionId = 123456789; + s_functionsRouter.ownerCancelSubscription(invalidSubscriptionId); + } + + function test_OwnerCancelSubscription_SuccessSubOwnerRefunded() public { + uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + s_functionsRouter.ownerCancelSubscription(s_subscriptionId); + uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); + assertEq(subscriptionOwnerBalanceBefore + s_subscriptionInitialFunding, subscriptionOwnerBalanceAfter); + } + + function test_OwnerCancelSubscription_SuccessWhenRequestInFlight() public { + // send request + string memory sourceCode = "return 'hello world';"; + bytes memory secrets; + string[] memory args = new string[](0); + bytes[] memory bytesArgs = new bytes[](0); + + s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000); + s_functionsRouter.ownerCancelSubscription(s_subscriptionId); + } + + function test_OwnerCancelSubscription_SuccessDeletesSubscription() public { + s_functionsRouter.ownerCancelSubscription(s_subscriptionId); + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + s_functionsRouter.getSubscription(s_subscriptionId); + } + + event SubscriptionCanceled(uint64 indexed subscriptionId, address fundsRecipient, uint256 fundsAmount); + + function test_OwnerCancelSubscription_Success() public { + uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + + // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1SubscriptionId = true; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1SubscriptionId, checkTopic2, checkTopic3, checkData); + emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, s_subscriptionInitialFunding); + + s_functionsRouter.ownerCancelSubscription(s_subscriptionId); + + uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); + assertEq(subscriptionOwnerBalanceBefore + s_subscriptionInitialFunding, subscriptionOwnerBalanceAfter); + } } /// @notice #recoverFunds -contract FunctionsSubscriptions_RecoverFunds { +contract FunctionsSubscriptions_RecoverFunds is FunctionsRouterSetup { + event FundsRecovered(address to, uint256 amount); + + function test_RecoverFunds_Success() public { + uint256 fundsTransferred = 1 * 1e18; // 1 LINK + s_linkToken.transfer(address(s_functionsRouter), fundsTransferred); + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit FundsRecovered(OWNER_ADDRESS, fundsTransferred); + + uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + s_functionsRouter.recoverFunds(OWNER_ADDRESS); + uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); + assertEq(subscriptionOwnerBalanceBefore + fundsTransferred, subscriptionOwnerBalanceAfter); + } + function test_OwnerCancelSubscription_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsRouter.recoverFunds(OWNER_ADDRESS); + } } /// @notice #oracleWithdraw -contract FunctionsSubscriptions_OracleWithdraw { +contract FunctionsSubscriptions_OracleWithdraw is FunctionsFulfillmentSetup { + function test_OracleWithdraw_RevertIfPaused() public { + s_functionsRouter.pause(); + + // Subscription payable balances are set to the Coordinator + // Send as Coordinator contract + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + vm.expectRevert("Pausable: paused"); + + uint96 amountToWithdraw = 1; // more than 0 + s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw); + } + + function test_OracleWithdraw_RevertIfNoAmount() public { + // Subscription payable balances are set to the Coordinator + // Send as Coordinator contract + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); + + uint96 amountToWithdraw = 0; + s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw); + } + + function test_OracleWithdraw_RevertIfAmountMoreThanBalance() public { + // Subscription payable balances are set to the Coordinator + // Send as Coordinator contract + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + vm.expectRevert( + abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, s_fulfillmentCoordinatorBalance) + ); + + uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance + 1; + s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw); + } + + function test_OracleWithdraw_RevertIfBalanceInvariant() public { + // Subscription payable balances are set to the Coordinator + // Send as Coordinator contract + // vm.stopPrank(); + // vm.startPrank(address(s_functionsCoordinator)); + // TODO: Use internal function helper contract to modify s_totalLinkBalance + // uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance; + // vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.TotalBalanceInvariantViolated.selector, 0, amountToWithdraw)); + // s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw); + } + function test_OracleWithdraw_SuccessPaysRecipient() public { + // Subscription payable balances are set to the Coordinator + // Send as Coordinator contract + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + uint256 transmitterBalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1); + + uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance; + s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw); + + uint256 transmitterBalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1); + assertEq(transmitterBalanceBefore + s_fulfillmentCoordinatorBalance, transmitterBalanceAfter); + } + + function test_OracleWithdraw_SuccessSetsBalanceToZero() public { + // Subscription payable balances are set to the Coordinator + // Send as Coordinator contract + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance; + s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw); + + // Attempt to withdraw 1 Juel after withdrawing full balance + vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, 0)); + s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, 1); + } } /// @notice #ownerWithdraw -contract FunctionsSubscriptions_OwnerWithdraw { +contract FunctionsSubscriptions_OwnerWithdraw is FunctionsFulfillmentSetup { + function test_OwnerWithdraw_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsRouter.recoverFunds(OWNER_ADDRESS); + } + + function test_OwnerWithdraw_RevertIfAmountMoreThanBalance() public { + vm.expectRevert( + abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, s_fulfillmentRouterOwnerBalance) + ); + + uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance + 1; + s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw); + } + + function test_OwnerWithdraw_RevertIfBalanceInvariant() public { + // TODO: Use internal function helper contract to modify s_totalLinkBalance + // uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance; + // vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.TotalBalanceInvariantViolated.selector, 0, amountToWithdraw)); + // s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw); + } + function test_OwnerWithdraw_SuccessIfNoAmount() public { + uint256 balanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + uint96 amountToWithdraw = 0; + s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw); + uint256 balanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); + assertEq(balanceBefore + s_fulfillmentRouterOwnerBalance, balanceAfter); + } + + function test_OwnerWithdraw_SuccessPaysRecipient() public { + uint256 balanceBefore = s_linkToken.balanceOf(STRANGER_ADDRESS); + + uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance; + s_functionsRouter.ownerWithdraw(STRANGER_ADDRESS, amountToWithdraw); + + uint256 balanceAfter = s_linkToken.balanceOf(STRANGER_ADDRESS); + assertEq(balanceBefore + s_fulfillmentRouterOwnerBalance, balanceAfter); + } + + function test_OwnerWithdraw_SuccessSetsBalanceToZero() public { + uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance; + s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw); + + // Attempt to withdraw 1 Juel after withdrawing full balance + vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, 0)); + s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, 1); + } } /// @notice #onTokenTransfer -contract FunctionsSubscriptions_OnTokenTransfer { +contract FunctionsSubscriptions_OnTokenTransfer is FunctionsSubscriptionSetup { + function test_OnTokenTransfer_RevertIfPaused() public { + s_functionsRouter.pause(); + vm.expectRevert("Pausable: paused"); + uint96 fundingAmount = 100; + s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, abi.encode(s_subscriptionId)); + } + + function test_OnTokenTransfer_RevertIfCallerIsNotLink() public { + vm.expectRevert(FunctionsSubscriptions.OnlyCallableFromLink.selector); + uint96 fundingAmount = 100; + s_functionsRouter.onTokenTransfer(address(s_functionsRouter), fundingAmount, abi.encode(s_subscriptionId)); + } + + function test_OnTokenTransfer_RevertIfCallerIsNoCalldata() public { + vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); + uint96 fundingAmount = 100; + s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, new bytes(0)); + } + function test_OnTokenTransfer_RevertIfCallerIsNoSubscription() public { + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + uint96 fundingAmount = 100; + uint64 invalidSubscriptionId = 123456789; + s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, abi.encode(invalidSubscriptionId)); + } + + function test_OnTokenTransfer_Success() public { + uint96 fundingAmount = 100; + uint96 subscriptionBalanceBefore = s_functionsRouter.getSubscription(s_subscriptionId).balance; + s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, abi.encode(s_subscriptionId)); + uint96 subscriptionBalanceAfter = s_functionsRouter.getSubscription(s_subscriptionId).balance; + assertEq(subscriptionBalanceBefore + fundingAmount, subscriptionBalanceAfter); + } } /// @notice #getTotalBalance -contract FunctionsSubscriptions_GetTotalBalance { +contract FunctionsSubscriptions_GetTotalBalance is FunctionsSubscriptionSetup { + function test_GetTotalBalance_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + uint96 totalBalance = s_functionsRouter.getTotalBalance(); + assertEq(totalBalance, s_subscriptionInitialFunding); + } } /// @notice #getSubscriptionCount -contract FunctionsSubscriptions_GetSubscriptionCount { +contract FunctionsSubscriptions_GetSubscriptionCount is FunctionsSubscriptionSetup { + function test_GetSubscriptionCount_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + uint96 subscriptionCount = s_functionsRouter.getSubscriptionCount(); + // One subscription was made during setup + assertEq(subscriptionCount, 1); + } } /// @notice #getSubscription -contract FunctionsSubscriptions_GetSubscription { +contract FunctionsSubscriptions_GetSubscription is FunctionsSubscriptionSetup { + function test_GetSubscription_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId); + assertEq(subscription.balance, s_subscriptionInitialFunding); + assertEq(subscription.owner, OWNER_ADDRESS); + assertEq(subscription.blockedBalance, 0); + assertEq(subscription.proposedOwner, address(0)); + assertEq(subscription.consumers[0], address(s_functionsClient)); + assertEq(subscription.flags, bytes32(0)); + } } /// @notice #getConsumer -contract FunctionsSubscriptions_GetConsumer { +contract FunctionsSubscriptions_GetConsumer is FunctionsSubscriptionSetup { + function test_GetConsumer_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + FunctionsSubscriptions.Consumer memory consumer = s_functionsRouter.getConsumer( + address(s_functionsClient), + s_subscriptionId + ); + assertEq(consumer.allowed, true); + assertEq(consumer.initiatedRequests, 0); + assertEq(consumer.completedRequests, 0); + } } /// @notice #_isExistingSubscription -contract FunctionsSubscriptions__IsExistingSubscription { - +contract FunctionsSubscriptions__IsExistingSubscription is FunctionsSubscriptionSetup { + // TODO: make contract internal function helper } /// @notice #_isAllowedConsumer contract FunctionsSubscriptions__IsAllowedConsumer { - + // TODO: make contract internal function helper } /// @notice #createSubscription -contract FunctionsSubscriptions_createSubscription is FunctionsOwnerAcceptTermsOfService { - function setUp() public virtual override { - FunctionsOwnerAcceptTermsOfService.setUp(); - } - +contract FunctionsSubscriptions_createSubscription is FunctionsOwnerAcceptTermsOfServiceSetup { event SubscriptionCreated(uint64 indexed subscriptionId, address owner); function test_CreateSubscription_Success() public { - vm.expectEmit(true, false, false, true); + // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = true; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); emit SubscriptionCreated(1, OWNER_ADDRESS); uint64 firstCallSubscriptionId = s_functionsRouter.createSubscription(); assertEq(firstCallSubscriptionId, 1); - vm.expectEmit(true, false, false, true); + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); emit SubscriptionCreated(2, OWNER_ADDRESS); uint64 secondCallSubscriptionId = s_functionsRouter.createSubscription(); assertEq(secondCallSubscriptionId, 2); - vm.expectEmit(true, false, false, true); + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); emit SubscriptionCreated(3, OWNER_ADDRESS); uint64 thirdCallSubscriptionId = s_functionsRouter.createSubscription(); assertEq(thirdCallSubscriptionId, 3); @@ -123,66 +440,597 @@ contract FunctionsSubscriptions_createSubscription is FunctionsOwnerAcceptTermsO } /// @notice #createSubscriptionWithConsumer -contract FunctionsSubscriptions_CreateSubscriptionWithConsumer { +contract FunctionsSubscriptions_CreateSubscriptionWithConsumer is FunctionsClientSetup { + event SubscriptionCreated(uint64 indexed subscriptionId, address owner); + event SubscriptionConsumerAdded(uint64 indexed subscriptionId, address consumer); + + function test_CreateSubscriptionWithConsumer_Success() public { + // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = true; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionCreated(1, OWNER_ADDRESS); + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionConsumerAdded(1, address(s_functionsClient)); + uint64 firstCallSubscriptionId = s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient)); + assertEq(firstCallSubscriptionId, 1); + assertEq(s_functionsRouter.getSubscription(firstCallSubscriptionId).consumers[0], address(s_functionsClient)); + + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionCreated(2, OWNER_ADDRESS); + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionConsumerAdded(2, address(s_functionsClient)); + uint64 secondCallSubscriptionId = s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient)); + assertEq(secondCallSubscriptionId, 2); + assertEq(s_functionsRouter.getSubscription(secondCallSubscriptionId).consumers[0], address(s_functionsClient)); + + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionCreated(3, OWNER_ADDRESS); + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionConsumerAdded(3, address(s_functionsClient)); + uint64 thirdCallSubscriptionId = s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient)); + assertEq(thirdCallSubscriptionId, 3); + assertEq(s_functionsRouter.getSubscription(thirdCallSubscriptionId).consumers[0], address(s_functionsClient)); + } + + function test_CreateSubscriptionWithConsumer_RevertIfPaused() public { + s_functionsRouter.pause(); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient)); + } + + function test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() public { + // Send as stranger, who has not accepted Terms of Service + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, STRANGER_ADDRESS)); + s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient)); + } } /// @notice #proposeSubscriptionOwnerTransfer -contract FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer { +contract FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer is FunctionsSubscriptionSetup { + uint256 internal NEW_OWNER_PRIVATE_KEY_WITH_TOS = 0x3; + address internal NEW_OWNER_ADDRESS_WITH_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITH_TOS); + uint256 internal NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS = 0x4; + address internal NEW_OWNER_ADDRESS_WITHOUT_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS); + + function setUp() public virtual override { + FunctionsSubscriptionSetup.setUp(); + + // Accept ToS as new owner + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS); + bytes32 message = s_termsOfServiceAllowList.getMessage(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + s_termsOfServiceAllowList.acceptTermsOfService(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS, r, s, v); + vm.stopPrank(); + vm.startPrank(OWNER_ADDRESS); + } + + function test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() public { + s_functionsRouter.pause(); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + } + + function test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() public { + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + uint64 invalidSubscriptionId = 123456789; + s_functionsRouter.proposeSubscriptionOwnerTransfer(invalidSubscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + } + + function test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() public { + // Send as non-owner, who has accepted Terms of Service + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS); + + vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector); + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + } + + function test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() public { + // Remove owner from Allow List + s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS)); + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + } + + function test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() public { + address EMPTY_ADDRESS = address(0); + vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, EMPTY_ADDRESS); + } + + function test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() public { + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + } + + event SubscriptionOwnerTransferRequested(uint64 indexed subscriptionId, address from, address to); + + function test_ProposeSubscriptionOwnerTransfer_Success() public { + // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = true; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionOwnerTransferRequested(s_subscriptionId, OWNER_ADDRESS, NEW_OWNER_ADDRESS_WITH_TOS); + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + assertEq(s_functionsRouter.getSubscription(s_subscriptionId).proposedOwner, NEW_OWNER_ADDRESS_WITH_TOS); + } } /// @notice #acceptSubscriptionOwnerTransfer -contract FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer { +contract FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer is FunctionsSubscriptionSetup { + uint256 internal NEW_OWNER_PRIVATE_KEY_WITH_TOS = 0x3; + address internal NEW_OWNER_ADDRESS_WITH_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITH_TOS); + uint256 internal NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS = 0x4; + address internal NEW_OWNER_ADDRESS_WITHOUT_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS); + + function setUp() public virtual override { + FunctionsSubscriptionSetup.setUp(); + + // Accept ToS as new owner + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS); + bytes32 message = s_termsOfServiceAllowList.getMessage(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + s_termsOfServiceAllowList.acceptTermsOfService(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS, r, s, v); + + vm.stopPrank(); + vm.startPrank(OWNER_ADDRESS); + } + + function test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() public { + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + s_functionsRouter.pause(); + + // Send as new owner, who has accepted Terms of Service + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId); + } + + function test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() public { + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITHOUT_TOS); + + // Send as new owner, who has NOT accepted Terms of Service + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITHOUT_TOS); + + vm.expectRevert( + abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, NEW_OWNER_ADDRESS_WITHOUT_TOS) + ); + s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId); + } + + function test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() public { + // Propose an address that is allowed to accept ownership + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + bool hasAccess = s_termsOfServiceAllowList.hasAccess(NEW_OWNER_ADDRESS_WITH_TOS, new bytes(0)); + assertEq(hasAccess, true); + + // Revoke access + s_termsOfServiceAllowList.blockSender(NEW_OWNER_ADDRESS_WITH_TOS); + + // Send as blocked address + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS); + + vm.expectRevert( + abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, NEW_OWNER_ADDRESS_WITH_TOS) + ); + s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId); + } + function test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() public { + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, STRANGER_ADDRESS); + + // Send as someone who is not hte proposed new owner + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS); + + vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.MustBeProposedOwner.selector, STRANGER_ADDRESS)); + s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId); + } + + event SubscriptionOwnerTransferred(uint64 indexed subscriptionId, address from, address to); + + function test_AcceptSubscriptionOwnerTransfer_Success() public { + s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS); + + // Send as new owner, who has accepted Terms of Service + vm.stopPrank(); + vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS); + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionOwnerTransferred(s_subscriptionId, OWNER_ADDRESS, NEW_OWNER_ADDRESS_WITH_TOS); + + s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId); + + FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId); + assertEq(subscription.owner, NEW_OWNER_ADDRESS_WITH_TOS); + assertEq(subscription.proposedOwner, address(0)); + } } /// @notice #removeConsumer -contract FunctionsSubscriptions_RemoveConsumer { +contract FunctionsSubscriptions_RemoveConsumer is FunctionsSubscriptionSetup { + function test_RemoveConsumer_RevertIfPaused() public { + s_functionsRouter.pause(); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient)); + } + + function test_RemoveConsumer_RevertIfNoSubscription() public { + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + uint64 invalidSubscriptionId = 123456789; + s_functionsRouter.removeConsumer(invalidSubscriptionId, address(s_functionsClient)); + } + + function test_RemoveConsumer_RevertIfNotSubscriptionOwner() public { + // Accept ToS as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + + // Send as non-subscription owner, who has accepted Terms of Service + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector); + s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient)); + } + + function test_RemoveConsumer_RevertIfNotAllowedSender() public { + // Remove owner from Allow List + s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS)); + s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient)); + } + function test_RemoveConsumer_RevertIfInvalidConsumer() public { + vm.expectRevert(FunctionsSubscriptions.InvalidConsumer.selector); + s_functionsRouter.removeConsumer(s_subscriptionId, address(0)); + } + + function test_RemoveConsumer_RevertIfPendingRequests() public { + // Send a minimal request + string memory sourceCode = "return 'hello world';"; + bytes memory secrets; + string[] memory args = new string[](0); + bytes[] memory bytesArgs = new bytes[](0); + + s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000); + + vm.expectRevert(FunctionsSubscriptions.CannotRemoveWithPendingRequests.selector); + s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient)); + } + + event SubscriptionConsumerRemoved(uint64 indexed subscriptionId, address consumer); + + function test_RemoveConsumer_Success() public { + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionConsumerRemoved(s_subscriptionId, address(s_functionsClient)); + s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient)); + + FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId); + assertEq(subscription.consumers, new address[](0)); + } } /// @notice #_getMaxConsumers -contract FunctionsSubscriptions__GetMaxConsumers { - +contract FunctionsSubscriptions__GetMaxConsumers is FunctionsRouterSetup { + // TODO: make contract internal function helper } /// @notice #addConsumer -contract FunctionsSubscriptions_AddConsumer { +contract FunctionsSubscriptions_AddConsumer is FunctionsSubscriptionSetup { + function test_AddConsumer_RevertIfPaused() public { + s_functionsRouter.pause(); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.addConsumer(s_subscriptionId, address(1)); + } + + function test_AddConsumer_RevertIfNoSubscription() public { + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + uint64 invalidSubscriptionId = 123456789; + s_functionsRouter.addConsumer(invalidSubscriptionId, address(1)); + } + + function test_AddConsumer_RevertIfNotSubscriptionOwner() public { + // Accept ToS as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + + // Send as non-subscription owner, who has accepted Terms of Service + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector); + s_functionsRouter.addConsumer(s_subscriptionId, address(1)); + } + + function test_AddConsumer_RevertIfNotAllowedSender() public { + // Remove owner from Allow List + s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS)); + s_functionsRouter.addConsumer(s_subscriptionId, address(1)); + } + + function test_AddConsumer_RevertIfMaximumConsumers() public { + // Fill Consumers to s_maxConsumersPerSubscription + // Already has one from setup + s_functionsRouter.addConsumer(s_subscriptionId, address(1)); + s_functionsRouter.addConsumer(s_subscriptionId, address(2)); + vm.expectRevert( + abi.encodeWithSelector(FunctionsSubscriptions.TooManyConsumers.selector, s_maxConsumersPerSubscription) + ); + s_functionsRouter.addConsumer(s_subscriptionId, address(3)); + } + + event SubscriptionConsumerAdded(uint64 indexed subscriptionId, address consumer); + + function test_AddConsumer_Success() public { + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionConsumerAdded(s_subscriptionId, address(1)); + s_functionsRouter.addConsumer(s_subscriptionId, address(1)); + + FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId); + assertEq(subscription.consumers[1], address(1)); + FunctionsSubscriptions.Consumer memory consumer = s_functionsRouter.getConsumer(address(1), s_subscriptionId); + assertEq(consumer.allowed, true); + } } /// @notice #cancelSubscription -contract FunctionsSubscriptions_CancelSubscription { +contract FunctionsSubscriptions_CancelSubscription is FunctionsSubscriptionSetup { + function test_CancelSubscription_RevertIfPaused() public { + s_functionsRouter.pause(); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); + } + function test_CancelSubscription_RevertIfNoSubscription() public { + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + uint64 invalidSubscriptionId = 123456789; + s_functionsRouter.cancelSubscription(invalidSubscriptionId, OWNER_ADDRESS); + } + + function test_CancelSubscription_RevertIfNotSubscriptionOwner() public { + // Accept ToS as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + + // Send as non-subscription owner, who has accepted Terms of Service + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector); + s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); + } + + function test_CancelSubscription_RevertIfNotAllowedSender() public { + // Remove owner from Allow List + s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS)); + s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); + } + + function test_CancelSubscription_RevertIfPendingRequests() public { + // Send a minimal request + string memory sourceCode = "return 'hello world';"; + bytes memory secrets; + string[] memory args = new string[](0); + bytes[] memory bytesArgs = new bytes[](0); + + s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000); + + vm.expectRevert(FunctionsSubscriptions.CannotRemoveWithPendingRequests.selector); + s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); + } + + event SubscriptionCanceled(uint64 indexed subscriptionId, address fundsRecipient, uint256 fundsAmount); + + function test_CancelSubscription_Success() public { + uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, s_subscriptionInitialFunding); + + s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); + + uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); + assertEq(subscriptionOwnerBalanceBefore + s_subscriptionInitialFunding, subscriptionOwnerBalanceAfter); + + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + s_functionsRouter.getSubscription(s_subscriptionId); + } } /// @notice #_cancelSubscriptionHelper contract FunctionsSubscriptions__CancelSubscriptionHelper { - + // TODO: make contract internal function helper } /// @notice #pendingRequestExists -contract FunctionsSubscriptions_PendingRequestExists { +contract FunctionsSubscriptions_PendingRequestExists is FunctionsFulfillmentSetup { + function test_PendingRequestExists_SuccessFalseIfNoPendingRequests() public { + bool hasPendingRequests = s_functionsRouter.pendingRequestExists(s_subscriptionId); + assertEq(hasPendingRequests, false); + } + + function test_PendingRequestExists_SuccessTrueIfPendingRequests() public { + // Send a minimal request + string memory sourceCode = "return 'hello world';"; + bytes memory secrets; + string[] memory args = new string[](0); + bytes[] memory bytesArgs = new bytes[](0); + + s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000); + bool hasPendingRequests = s_functionsRouter.pendingRequestExists(s_subscriptionId); + assertEq(hasPendingRequests, true); + } } /// @notice #setFlags -contract FunctionsSubscriptions_SetFlags { +contract FunctionsSubscriptions_SetFlags is FunctionsSubscriptionSetup { + function test_SetFlags_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + vm.expectRevert("Only callable by owner"); + bytes32 flagsToSet = bytes32("1"); + s_functionsRouter.setFlags(s_subscriptionId, flagsToSet); + } + + function test_SetFlags_RevertIfNoSubscription() public { + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + uint64 invalidSubscriptionId = 123456789; + bytes32 flagsToSet = bytes32("1"); + s_functionsRouter.setFlags(invalidSubscriptionId, flagsToSet); + } + + function test_SetFlags_Success() public { + bytes32 flagsToSet = bytes32("1"); + s_functionsRouter.setFlags(s_subscriptionId, flagsToSet); + bytes32 flags = s_functionsRouter.getFlags(s_subscriptionId); + assertEq(flags, flagsToSet); + } } /// @notice #getFlags -contract FunctionsSubscriptions_GetFlags { +contract FunctionsSubscriptions_GetFlags is FunctionsSubscriptionSetup { + function test_GetFlags_Success() public { + // Set flags + bytes32 flagsToSet = bytes32("1"); + s_functionsRouter.setFlags(s_subscriptionId, flagsToSet); + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 flags = s_functionsRouter.getFlags(s_subscriptionId); + assertEq(flags, flagsToSet); + } } /// @notice #timeoutRequests -contract FunctionsSubscriptions_TimeoutRequests { +contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup { + function test_TimeoutRequests_RevertIfPaused() public { + s_functionsRouter.pause(); + vm.expectRevert("Pausable: paused"); + FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); + commitments[0] = s_requestCommitment; + s_functionsRouter.timeoutRequests(commitments); + } + + function test_TimeoutRequests_RevertInvalidRequest() public { + // Modify the commitment so that it doesn't match + s_requestCommitment.donFee = 123456789; + FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); + commitments[0] = s_requestCommitment; + vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); + s_functionsRouter.timeoutRequests(commitments); + } + + function test_TimeoutRequests_RevertIfTimeoutNotExceeded() public { + vm.expectRevert(FunctionsSubscriptions.TimeoutNotExceeded.selector); + FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); + commitments[0] = s_requestCommitment; + s_functionsRouter.timeoutRequests(commitments); + } + + event RequestTimedOut(bytes32 indexed requestId); + + function test_TimeoutRequests_Success() public { + uint64 consumerCompletedRequestsBefore = s_functionsRouter + .getConsumer(address(s_functionsClient), s_subscriptionId) + .completedRequests; + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestTimedOut(s_requestId); + + // Jump ahead in time past timeout timestamp + vm.warp(s_requestCommitment.timeoutTimestamp + 1); + + FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); + commitments[0] = s_requestCommitment; + s_functionsRouter.timeoutRequests(commitments); + + // Releases blocked balance and increments completed requests + uint96 subscriptionBlockedBalanceAfter = s_functionsRouter.getSubscription(s_subscriptionId).blockedBalance; + assertEq(0, subscriptionBlockedBalanceAfter); + uint64 consumerCompletedRequestsAfter = s_functionsRouter + .getConsumer(address(s_functionsClient), s_subscriptionId) + .completedRequests; + assertEq(consumerCompletedRequestsBefore + 1, consumerCompletedRequestsAfter); + } } -/// @notice #_onlySubscriptionOwner +// @notice #_onlySubscriptionOwner contract FunctionsSubscriptions__OnlySubscriptionOwner { - + // TODO: make contract internal function helper } diff --git a/contracts/src/v0.8/functions/tests/1_0_0/OCR2.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/OCR2.t.sol new file mode 100644 index 00000000000..e69de29bb2d diff --git a/contracts/src/v0.8/functions/tests/1_0_0/README.md b/contracts/src/v0.8/functions/tests/1_0_0/README.md new file mode 100644 index 00000000000..bbbf33dbe96 --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/README.md @@ -0,0 +1,22 @@ +## Usage + +First set the foundry profile to Functions: +``` +export FOUNDRY_PROFILE=functions +``` + +To run all test files use: +``` +forge test -vv +``` + +To run a specific file use: +``` +forge test -vv --mp src/v0.8/functions/tests/1_0_0/[File Name].t.sol +``` + +To see coverage: +First ensure that the correct files are being evaluated. For example, if only v1 contracts are, then temporarily change the Functions profile in `./foundry.toml`. +``` +forge coverage +``` \ No newline at end of file diff --git a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol index 56addcabd79..4d49cb64054 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol @@ -3,23 +3,28 @@ pragma solidity ^0.8.19; import {BaseTest} from "./BaseTest.t.sol"; import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; -import {FunctionsCoordinator} from "../../dev/1_0_0/FunctionsCoordinator.sol"; +import {FunctionsCoordinatorTestHelper} from "./testhelpers/FunctionsCoordinatorTestHelper.sol"; import {FunctionsBilling} from "../../dev/1_0_0/FunctionsBilling.sol"; +import {FunctionsResponse} from "../../dev/1_0_0/libraries/FunctionsResponse.sol"; import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; import {TermsOfServiceAllowList} from "../../dev/1_0_0/accessControl/TermsOfServiceAllowList.sol"; +import {FunctionsClientUpgradeHelper} from "./testhelpers/FunctionsClientUpgradeHelper.sol"; +import {MockLinkToken} from "../../../mocks/MockLinkToken.sol"; + +import "forge-std/console.sol"; +import "forge-std/Vm.sol"; contract FunctionsRouterSetup is BaseTest { FunctionsRouter internal s_functionsRouter; - FunctionsCoordinator internal s_functionsCoordinator; + FunctionsCoordinatorTestHelper internal s_functionsCoordinator; // TODO: use actual FunctionsCoordinator instead of helper MockV3Aggregator internal s_linkEthFeed; TermsOfServiceAllowList internal s_termsOfServiceAllowList; + MockLinkToken internal s_linkToken; - uint16 internal s_maxConsumersPerSubscription = 100; + uint16 internal s_maxConsumersPerSubscription = 3; uint72 internal s_adminFee = 100; bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175; - address internal s_linkToken = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709; - int256 internal LINK_ETH_RATE = 6000000000000000; uint256 internal TOS_SIGNER_PRIVATE_KEY = 0x3; @@ -27,9 +32,10 @@ contract FunctionsRouterSetup is BaseTest { function setUp() public virtual override { BaseTest.setUp(); - s_functionsRouter = new FunctionsRouter(s_linkToken, getRouterConfig()); + s_linkToken = new MockLinkToken(); + s_functionsRouter = new FunctionsRouter(address(s_linkToken), getRouterConfig()); s_linkEthFeed = new MockV3Aggregator(0, LINK_ETH_RATE); - s_functionsCoordinator = new FunctionsCoordinator( + s_functionsCoordinator = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), address(s_linkEthFeed) @@ -73,13 +79,63 @@ contract FunctionsRouterSetup is BaseTest { } } -contract FunctionsSetupRoutes is FunctionsRouterSetup { +contract FunctionsDONSetup is FunctionsRouterSetup { + uint256 internal NOP_SIGNER_PRIVATE_KEY_1 = 0x100; + address internal NOP_SIGNER_ADDRESS_1 = vm.addr(NOP_SIGNER_PRIVATE_KEY_1); + uint256 internal NOP_SIGNER_PRIVATE_KEY_2 = 0x101; + address internal NOP_SIGNER_ADDRESS_2 = vm.addr(NOP_SIGNER_PRIVATE_KEY_2); + uint256 internal NOP_SIGNER_PRIVATE_KEY_3 = 0x102; + address internal NOP_SIGNER_ADDRESS_3 = vm.addr(NOP_SIGNER_PRIVATE_KEY_3); + uint256 internal NOP_SIGNER_PRIVATE_KEY_4 = 0x103; + address internal NOP_SIGNER_ADDRESS_4 = vm.addr(NOP_SIGNER_PRIVATE_KEY_4); + + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_1 = 0x104; + address internal NOP_TRANSMITTER_ADDRESS_1 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_1); + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_2 = 0x105; + address internal NOP_TRANSMITTER_ADDRESS_2 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_2); + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_3 = 0x106; + address internal NOP_TRANSMITTER_ADDRESS_3 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_3); + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_4 = 0x107; + address internal NOP_TRANSMITTER_ADDRESS_4 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_4); + function setUp() public virtual override { FunctionsRouterSetup.setUp(); + address[] memory _signers = new address[](4); + _signers[0] = NOP_SIGNER_ADDRESS_1; + _signers[1] = NOP_SIGNER_ADDRESS_2; + _signers[2] = NOP_SIGNER_ADDRESS_3; + _signers[3] = NOP_SIGNER_ADDRESS_4; + address[] memory _transmitters = new address[](4); + _transmitters[0] = NOP_TRANSMITTER_ADDRESS_1; + _transmitters[1] = NOP_TRANSMITTER_ADDRESS_2; + _transmitters[2] = NOP_TRANSMITTER_ADDRESS_3; + _transmitters[3] = NOP_TRANSMITTER_ADDRESS_4; + uint8 _f = 1; + bytes memory _onchainConfig = new bytes(0); + uint64 _offchainConfigVersion = 1; + bytes memory _offchainConfig = new bytes(0); + // set OCR config + s_functionsCoordinator.setConfig( + _signers, + _transmitters, + _f, + _onchainConfig, + _offchainConfigVersion, + _offchainConfig + ); + } +} + +contract FunctionsRoutesSetup is FunctionsDONSetup { + bytes32 s_donId = bytes32("1"); + + function setUp() public virtual override { + FunctionsDONSetup.setUp(); + bytes32 allowListId = s_functionsRouter.getAllowListId(); bytes32[] memory proposedContractSetIds = new bytes32[](2); - proposedContractSetIds[0] = bytes32("1"); + proposedContractSetIds[0] = s_donId; proposedContractSetIds[1] = allowListId; address[] memory proposedContractSetAddresses = new address[](2); proposedContractSetAddresses[0] = address(s_functionsCoordinator); @@ -90,9 +146,9 @@ contract FunctionsSetupRoutes is FunctionsRouterSetup { } } -contract FunctionsOwnerAcceptTermsOfService is FunctionsSetupRoutes { +contract FunctionsOwnerAcceptTermsOfServiceSetup is FunctionsRoutesSetup { function setUp() public virtual override { - FunctionsSetupRoutes.setUp(); + FunctionsRoutesSetup.setUp(); bytes32 message = s_termsOfServiceAllowList.getMessage(OWNER_ADDRESS, OWNER_ADDRESS); bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); @@ -100,3 +156,103 @@ contract FunctionsOwnerAcceptTermsOfService is FunctionsSetupRoutes { s_termsOfServiceAllowList.acceptTermsOfService(OWNER_ADDRESS, OWNER_ADDRESS, r, s, v); } } + +contract FunctionsClientSetup is FunctionsOwnerAcceptTermsOfServiceSetup { + FunctionsClientUpgradeHelper internal s_functionsClient; + + function setUp() public virtual override { + FunctionsOwnerAcceptTermsOfServiceSetup.setUp(); + + s_functionsClient = new FunctionsClientUpgradeHelper(address(s_functionsRouter)); + } +} + +contract FunctionsSubscriptionSetup is FunctionsClientSetup { + uint96 constant JUELS_PER_LINK = 1e18; + uint64 s_subscriptionId; + uint96 s_subscriptionInitialFunding = 10 * JUELS_PER_LINK; // 10 LINK + + function setUp() public virtual override { + FunctionsClientSetup.setUp(); + + // Create subscription + s_subscriptionId = s_functionsRouter.createSubscription(); + s_functionsRouter.addConsumer(s_subscriptionId, address(s_functionsClient)); + + // Fund subscription + s_linkToken.transferAndCall(address(s_functionsRouter), s_subscriptionInitialFunding, abi.encode(s_subscriptionId)); + } +} + +contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { + bytes32 s_requestId; + FunctionsResponse.Commitment s_requestCommitment; + + function setUp() public virtual override { + FunctionsSubscriptionSetup.setUp(); + + // Send a minimal request + string memory sourceCode = "return 'hello world';"; + bytes memory secrets; + string[] memory args = new string[](0); + bytes[] memory bytesArgs = new bytes[](0); + + vm.recordLogs(); + s_requestId = s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000); + + // Get commitment data from OracleRequest event log + Vm.Log[] memory entries = vm.getRecordedLogs(); + (, , , , , , , FunctionsResponse.Commitment memory commitment) = abi.decode( + entries[0].data, + (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment) + ); + s_requestCommitment = commitment; + } +} + +contract FunctionsFulfillmentSetup is FunctionsClientRequestSetup { + uint96 s_fulfillmentRouterOwnerBalance = s_adminFee; + uint96 s_fulfillmentCoordinatorBalance; + + function setUp() public virtual override { + FunctionsClientRequestSetup.setUp(); + + // Send as transmitter 1 + vm.stopPrank(); + vm.startPrank(NOP_TRANSMITTER_ADDRESS_1); + + // Build report + bytes32[] memory requestIds = new bytes32[](1); + requestIds[0] = s_requestId; + bytes[] memory results = new bytes[](1); + results[0] = bytes("hello world!"); + bytes[] memory errors = new bytes[](1); + // No error + bytes[] memory onchainMetadata = new bytes[](1); + onchainMetadata[0] = abi.encode(s_requestCommitment); + bytes[] memory offchainMetadata = new bytes[](1); + // No offchain metadata + bytes memory report = abi.encode(requestIds, results, errors, onchainMetadata, offchainMetadata); + + // Build signers + address[31] memory signers; + signers[0] = NOP_SIGNER_ADDRESS_1; + + // Send report + vm.recordLogs(); + s_functionsCoordinator.callReportWithSigners(report, signers); + + // Get actual cost from RequestProcessed event log + Vm.Log[] memory entries = vm.getRecordedLogs(); + (uint96 totalCostJuels, , , , , ) = abi.decode( + entries[1].data, + (uint96, address, FunctionsResponse.FulfillResult, bytes, bytes, bytes) + ); + // totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels + s_fulfillmentCoordinatorBalance = totalCostJuels - s_adminFee; + + // Return prank to Owner + vm.stopPrank(); + vm.startPrank(OWNER_ADDRESS); + } +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol index 0bf7adb7a25..c612f47644f 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol @@ -23,4 +23,8 @@ contract FunctionsCoordinatorTestHelper is FunctionsCoordinator { signers[1] = secondSigner; _report(gasleft(), msg.sender, 2, signers, report); } + + function callReportWithSigners(bytes calldata report, address[MAX_NUM_ORACLES] memory signers) external { + _report(gasleft(), msg.sender, 2, signers, report); + } } From 3a98db69f784978a6c43cbfae95938d1e98f9ed2 Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Wed, 6 Sep 2023 22:12:02 +0100 Subject: [PATCH 39/88] Add batch size backoff in log poller insert logs (#10525) * Add batch size backoff in log poller insert logs * update --- core/chains/evm/logpoller/orm.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index e8ced08a1e7..08a4d558fbf 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -1,6 +1,7 @@ package logpoller import ( + "context" "database/sql" "math/big" "time" @@ -189,6 +190,12 @@ func (o *ORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error { (:evm_chain_id, :log_index, :block_hash, :block_number, :block_timestamp, :address, :event_sig, :topics, :tx_hash, :data, NOW()) ON CONFLICT DO NOTHING`, logs[start:end]) if err != nil { + if errors.Is(err, context.DeadlineExceeded) && batchInsertSize > 500 { + // In case of DB timeouts, try to insert again with a smaller batch upto a limit + batchInsertSize /= 2 + i -= batchInsertSize // counteract +=batchInsertSize on next loop iteration + continue + } return err } } From a1040ebe1ba8cef401b8695943ffe6bf18af4583 Mon Sep 17 00:00:00 2001 From: krehermann Date: Wed, 6 Sep 2023 15:43:43 -0600 Subject: [PATCH 40/88] address lingering clean up and todos after BCF-2441 & BCF-2564 (#10521) * address lingering clean up and todos after BCF-2441 & BCF-2564 * address comments --- core/chains/config.go | 14 ---- .../mocks/relayer_chain_interoperators.go | 28 ++++---- .../chainlink/relayer_chain_interoperators.go | 23 +++---- core/services/relay/evm/relayer_extender.go | 20 ------ .../relay/evm/relayer_extender_test.go | 11 +--- core/services/relay/relay.go | 65 +++---------------- core/web/cosmos_nodes_controller.go | 4 +- core/web/evm_nodes_controller.go | 4 +- core/web/loader/loader_test.go | 2 +- core/web/loader/node.go | 6 +- core/web/nodes_controller.go | 34 ++++++++-- core/web/solana_nodes_controller.go | 4 +- core/web/starknet_nodes_controller.go | 7 +- 13 files changed, 80 insertions(+), 142 deletions(-) diff --git a/core/chains/config.go b/core/chains/config.go index 8ce2a63fe0b..0111521b304 100644 --- a/core/chains/config.go +++ b/core/chains/config.go @@ -1,7 +1,6 @@ package chains import ( - "context" "errors" "github.com/smartcontractkit/chainlink-relay/pkg/logger" @@ -32,19 +31,6 @@ type Configs[I ID, N Node] interface { NodeConfigs[I, N] } -// ChainStatuser is a generic interface for chain configuration. -type ChainStatuser interface { - // must return [ErrNotFound] if the id is not found - ChainStatus(ctx context.Context, id string) (types.ChainStatus, error) - ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) -} - -// NodesStatuser is an interface for node configuration and state. -// TODO BCF-2440, BCF-2511 may need Node(ctx,name) to get a node status by name -type NodesStatuser interface { - NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error) -} - // ChainOpts holds options for configuring a Chain type ChainOpts[I ID, N Node] interface { Validate() error diff --git a/core/services/chainlink/mocks/relayer_chain_interoperators.go b/core/services/chainlink/mocks/relayer_chain_interoperators.go index f25ced6c3ca..c0eb699a492 100644 --- a/core/services/chainlink/mocks/relayer_chain_interoperators.go +++ b/core/services/chainlink/mocks/relayer_chain_interoperators.go @@ -10,7 +10,7 @@ import ( cosmos "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" evm "github.com/smartcontractkit/chainlink/v2/core/chains/evm" - + // Manually edited. mockery generates the wrong dependency. edited to use `loop` rather than `loop/internal` // seems to caused by incorrect alias resolution of the relayer dep internal "github.com/smartcontractkit/chainlink-relay/pkg/loop" @@ -160,11 +160,11 @@ func (_m *RelayerChainInteroperators) List(filter chainlink.FilterFn) chainlink. return r0 } -// NodeStatuses provides a mock function with given fields: ctx, offset, limit, chainIDs -func (_m *RelayerChainInteroperators) NodeStatuses(ctx context.Context, offset int, limit int, chainIDs ...string) ([]types.NodeStatus, int, error) { - _va := make([]interface{}, len(chainIDs)) - for _i := range chainIDs { - _va[_i] = chainIDs[_i] +// NodeStatuses provides a mock function with given fields: ctx, offset, limit, relayIDs +func (_m *RelayerChainInteroperators) NodeStatuses(ctx context.Context, offset int, limit int, relayIDs ...relay.ID) ([]types.NodeStatus, int, error) { + _va := make([]interface{}, len(relayIDs)) + for _i := range relayIDs { + _va[_i] = relayIDs[_i] } var _ca []interface{} _ca = append(_ca, ctx, offset, limit) @@ -174,25 +174,25 @@ func (_m *RelayerChainInteroperators) NodeStatuses(ctx context.Context, offset i var r0 []types.NodeStatus var r1 int var r2 error - if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) ([]types.NodeStatus, int, error)); ok { - return rf(ctx, offset, limit, chainIDs...) + if rf, ok := ret.Get(0).(func(context.Context, int, int, ...relay.ID) ([]types.NodeStatus, int, error)); ok { + return rf(ctx, offset, limit, relayIDs...) } - if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) []types.NodeStatus); ok { - r0 = rf(ctx, offset, limit, chainIDs...) + if rf, ok := ret.Get(0).(func(context.Context, int, int, ...relay.ID) []types.NodeStatus); ok { + r0 = rf(ctx, offset, limit, relayIDs...) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]types.NodeStatus) } } - if rf, ok := ret.Get(1).(func(context.Context, int, int, ...string) int); ok { - r1 = rf(ctx, offset, limit, chainIDs...) + if rf, ok := ret.Get(1).(func(context.Context, int, int, ...relay.ID) int); ok { + r1 = rf(ctx, offset, limit, relayIDs...) } else { r1 = ret.Get(1).(int) } - if rf, ok := ret.Get(2).(func(context.Context, int, int, ...string) error); ok { - r2 = rf(ctx, offset, limit, chainIDs...) + if rf, ok := ret.Get(2).(func(context.Context, int, int, ...relay.ID) error); ok { + r2 = rf(ctx, offset, limit, relayIDs...) } else { r2 = ret.Error(2) } diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 924279389f0..f342176f4cf 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -53,17 +53,21 @@ type LegacyChainer interface { LegacyCosmosChains() cosmos.LegacyChainContainer } -// Similar to [chains.ChainStatuser] but keyed by relay identifier instead of string -// TODO BCF-2441 remove this comment when chains.ChainStatus is no longer keyed. type ChainStatuser interface { ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) } +// NodesStatuser is an interface for node configuration and state. +// TODO BCF-2440, BCF-2511 may need Node(ctx,name) to get a node status by name +type NodesStatuser interface { + NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) +} + // ChainsNodesStatuser report statuses about chains and nodes type ChainsNodesStatuser interface { ChainStatuser - chains.NodesStatuser + NodesStatuser } var _ RelayerChainInteroperators = &CoreRelayerChainInteroperators{} @@ -220,7 +224,6 @@ func (rs *CoreRelayerChainInteroperators) ChainStatus(ctx context.Context, id re } func (rs *CoreRelayerChainInteroperators) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) { - // chain statuses are not dynamic; the call would be better named as ChainConfig or such. var ( stats []types.ChainStatus @@ -274,7 +277,7 @@ func (rs *CoreRelayerChainInteroperators) Node(ctx context.Context, name string) // ids must be a string representation of relay.Identifier // ids are a filter; if none are specified, all are returned. // TODO: BCF-2440/1 this signature can be changed to id relay.Identifier which is a much better API -func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...string) (nodes []types.NodeStatus, count int, err error) { +func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) { var ( totalErr error result []types.NodeStatus @@ -290,14 +293,8 @@ func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offs count += total } } else { - for _, idStr := range relayerIDs { - rid := new(relay.ID) - err := rid.UnmarshalString(idStr) - if err != nil { - totalErr = errors.Join(totalErr, err) - continue - } - lr, exist := rs.loopRelayers[*rid] + for _, rid := range relayerIDs { + lr, exist := rs.loopRelayers[rid] if !exist { totalErr = errors.Join(totalErr, fmt.Errorf("relayer %s does not exist", rid.Name())) continue diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index 637baedab83..c71ccd03b25 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -24,8 +24,6 @@ type EVMChainRelayerExtender interface { Chain() evmchain.Chain Default() bool // compatibility remove after BCF-2441 - ChainStatus(ctx context.Context, id string) (relaytypes.ChainStatus, error) - ChainStatuses(ctx context.Context, offset, limit int) ([]relaytypes.ChainStatus, int, error) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []relaytypes.NodeStatus, count int, err error) } @@ -137,24 +135,6 @@ func (s *ChainRelayerExt) Ready() (err error) { var ErrInconsistentChainRelayerExtender = errors.New("inconsistent evm chain relayer extender") -// Legacy interface remove after BFC-2441, BCF-2564 - -func (s *ChainRelayerExt) ChainStatus(ctx context.Context, id string) (relaytypes.ChainStatus, error) { - if s.chain.ID().String() != id { - return relaytypes.ChainStatus{}, fmt.Errorf("%w: given id %q does not match expected id %q", ErrInconsistentChainRelayerExtender, id, s.chain.ID()) - } - return s.chain.GetChainStatus(ctx) -} - -func (s *ChainRelayerExt) ChainStatuses(ctx context.Context, offset, limit int) ([]relaytypes.ChainStatus, int, error) { - stat, err := s.chain.GetChainStatus(ctx) - if err != nil { - return nil, -1, err - } - return []relaytypes.ChainStatus{stat}, 1, nil - -} - func (s *ChainRelayerExt) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []relaytypes.NodeStatus, total int, err error) { if len(chainIDs) > 1 { return nil, -1, fmt.Errorf("single chain chain set only support one chain id. got %v", chainIDs) diff --git a/core/services/relay/evm/relayer_extender_test.go b/core/services/relay/evm/relayer_extender_test.go index d4cbb1368c2..6caf8472478 100644 --- a/core/services/relay/evm/relayer_extender_test.go +++ b/core/services/relay/evm/relayer_extender_test.go @@ -62,19 +62,10 @@ func TestChainRelayExtenders(t *testing.T) { // test extender methods on single instance relayExt := relayExtendersInstances[0] - s, err := relayExt.ChainStatus(testutils.Context(t), "not a chain") - assert.Error(t, err) - assert.Empty(t, s) - // the 0-th extender corresponds to the test fixture default chain - s, err = relayExt.ChainStatus(testutils.Context(t), cltest.FixtureChainID.String()) + s, err := relayExt.GetChainStatus(testutils.Context(t)) assert.NotEmpty(t, s) assert.NoError(t, err) - stats, cnt, err := relayExt.ChainStatuses(testutils.Context(t), 0, 0) - assert.NoError(t, err) - assert.Len(t, stats, 1) - assert.Equal(t, 1, cnt) - // test error conditions for NodeStatuses nstats, cnt, err := relayExt.NodeStatuses(testutils.Context(t), 0, 0, cltest.FixtureChainID.String(), "error, only one chain supported") assert.Error(t, err) diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go index d7c71eebac2..fccd69c411e 100644 --- a/core/services/relay/relay.go +++ b/core/services/relay/relay.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "math/big" "regexp" "strconv" @@ -105,12 +104,7 @@ func (c ChainID) Int64() (int64, error) { // RelayerExt is a subset of [loop.Relayer] for adapting [types.Relayer], typically with a Chain. See [relayerAdapter]. type RelayerExt interface { types.ChainService - // TODO remove after BFC-2441 ID() string - GetChainStatus(ctx context.Context) (types.ChainStatus, error) - ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) - // choose different name than SendTx to avoid collison during refactor. - Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error } var _ loop.Relayer = (*relayerAdapter)(nil) @@ -120,12 +114,12 @@ type relayerAdapter struct { types.Relayer // TODO we can un-embedded `ext` once BFC-2441 is merged. Right now that's not possible // because this are conflicting definitions of SendTx - ext RelayerExt + RelayerExt } // NewRelayerAdapter returns a [loop.Relayer] adapted from a [types.Relayer] and [RelayerExt]. func NewRelayerAdapter(r types.Relayer, e RelayerExt) loop.Relayer { - return &relayerAdapter{Relayer: r, ext: e} + return &relayerAdapter{Relayer: r, RelayerExt: e} } func (r *relayerAdapter) NewConfigProvider(ctx context.Context, rargs types.RelayArgs) (types.ConfigProvider, error) { @@ -146,54 +140,37 @@ func (r *relayerAdapter) NewFunctionsProvider(ctx context.Context, rargs types.R func (r *relayerAdapter) Start(ctx context.Context) error { var ms services.MultiStart - return ms.Start(ctx, r.ext, r.Relayer) + return ms.Start(ctx, r.RelayerExt, r.Relayer) } func (r *relayerAdapter) Close() error { - return services.CloseAll(r.Relayer, r.ext) + return services.CloseAll(r.Relayer, r.RelayerExt) } func (r *relayerAdapter) Name() string { - return fmt.Sprintf("%s-%s", r.Relayer.Name(), r.ext.Name()) + return fmt.Sprintf("%s-%s", r.Relayer.Name(), r.RelayerExt.Name()) } func (r *relayerAdapter) Ready() (err error) { - return errors.Join(r.Relayer.Ready(), r.ext.Ready()) + return errors.Join(r.Relayer.Ready(), r.RelayerExt.Ready()) } func (r *relayerAdapter) HealthReport() map[string]error { hr := make(map[string]error) maps.Copy(r.Relayer.HealthReport(), hr) - maps.Copy(r.ext.HealthReport(), hr) + maps.Copy(r.RelayerExt.HealthReport(), hr) return hr } -// Implement the existing [loop.Relayer] interface using the underlaying chain service -// TODO Delete this code after BFC-2441 - -func (r *relayerAdapter) ChainStatus(ctx context.Context, id string) (types.ChainStatus, error) { - if id != r.ext.ID() { - return types.ChainStatus{}, fmt.Errorf("unexpected chain id. got %s want %s", id, r.ID()) - } - return r.ext.GetChainStatus(ctx) -} -func (r *relayerAdapter) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) { - stat, err := r.ext.GetChainStatus(ctx) - if err != nil { - return nil, -1, err - } - return []types.ChainStatus{stat}, 1, nil -} - func (r *relayerAdapter) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, total int, err error) { if len(chainIDs) > 1 { return nil, 0, fmt.Errorf("internal error: node statuses expects at most one chain id got %v", chainIDs) } - if len(chainIDs) == 1 && chainIDs[0] != r.ext.ID() { + if len(chainIDs) == 1 && chainIDs[0] != r.ID() { return nil, 0, fmt.Errorf("node statuses unexpected chain id got %s want %s", chainIDs[0], r.ID()) } - nodes, _, total, err = r.ext.ListNodeStatuses(ctx, int32(limit), "") + nodes, _, total, err = r.ListNodeStatuses(ctx, int32(limit), "") if err != nil { return nil, 0, err } @@ -207,27 +184,3 @@ func (r *relayerAdapter) NodeStatuses(ctx context.Context, offset, limit int, ch } return nodes[offset:limit], total, nil } - -func (r *relayerAdapter) SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error { - if chainID != r.ext.ID() { - return fmt.Errorf("send tx unexpected chain id. got %s want %s", chainID, r.ext.ID()) - } - return r.ext.Transact(ctx, from, to, amount, balanceCheck) -} - -func (r *relayerAdapter) ID() string { - return r.ext.ID() -} - -func (r *relayerAdapter) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { - return r.ext.GetChainStatus(ctx) -} - -func (r *relayerAdapter) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) { - return r.ext.ListNodeStatuses(ctx, pageSize, pageToken) -} - -// choose different name than SendTx to avoid collison during refactor. -func (r *relayerAdapter) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { - return r.ext.Transact(ctx, from, to, amount, balanceCheck) -} diff --git a/core/web/cosmos_nodes_controller.go b/core/web/cosmos_nodes_controller.go index 756d1ded741..121d7d8422b 100644 --- a/core/web/cosmos_nodes_controller.go +++ b/core/web/cosmos_nodes_controller.go @@ -10,7 +10,9 @@ import ( var ErrCosmosNotEnabled = errChainDisabled{name: "Cosmos", tomlKey: "Cosmos.Enabled"} func NewCosmosNodesController(app chainlink.Application) NodesController { + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.Cosmos) + return newNodesController[presenters.CosmosNodeResource]( - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Cosmos)), ErrCosmosNotEnabled, presenters.NewCosmosNodeResource, app.GetAuditLogger(), + scopedNodeStatuser, ErrCosmosNotEnabled, presenters.NewCosmosNodeResource, app.GetAuditLogger(), ) } diff --git a/core/web/evm_nodes_controller.go b/core/web/evm_nodes_controller.go index aba0faca8e8..c8d0b91c0f7 100644 --- a/core/web/evm_nodes_controller.go +++ b/core/web/evm_nodes_controller.go @@ -7,6 +7,8 @@ import ( ) func NewEVMNodesController(app chainlink.Application) NodesController { + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.EVM) + return newNodesController[presenters.EVMNodeResource]( - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.EVM)), ErrEVMNotEnabled, presenters.NewEVMNodeResource, app.GetAuditLogger()) + scopedNodeStatuser, ErrEVMNotEnabled, presenters.NewEVMNodeResource, app.GetAuditLogger()) } diff --git a/core/web/loader/loader_test.go b/core/web/loader/loader_test.go index d5123053cf2..0dd45a1735d 100644 --- a/core/web/loader/loader_test.go +++ b/core/web/loader/loader_test.go @@ -81,7 +81,7 @@ func TestLoader_Nodes(t *testing.T) { } rcInterops := chainlinkmocks.NewRelayerChainInteroperators(t) rcInterops.On("NodeStatuses", mock.Anything, 0, -1, - relayID2.String(), relayID1.String(), notARelayID.String()).Return([]relaytypes.NodeStatus{ + relayID2, relayID1, notARelayID).Return([]relaytypes.NodeStatus{ genNodeStat(chainID2.String()), genNodeStat(chainID1.String()), }, 2, nil) diff --git a/core/web/loader/node.go b/core/web/loader/node.go index fb0c58d1f2c..9ea6062dc29 100644 --- a/core/web/loader/node.go +++ b/core/web/loader/node.go @@ -20,15 +20,15 @@ func (b *nodeBatcher) loadByChainIDs(ctx context.Context, keys dataloader.Keys) keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for // note backward compatibility -- this only ever supported evm chains - var evmrelayIdStrs []string + evmrelayIDs := make([]relay.ID, 0, len(keys)) for ix, key := range keys { rid := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(key.String())} - evmrelayIdStrs = append(evmrelayIdStrs, rid.String()) + evmrelayIDs = append(evmrelayIDs, rid) keyOrder[key.String()] = ix } - allNodes, _, err := b.app.GetRelayers().NodeStatuses(ctx, 0, -1, evmrelayIdStrs...) + allNodes, _, err := b.app.GetRelayers().NodeStatuses(ctx, 0, -1, evmrelayIDs...) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/nodes_controller.go b/core/web/nodes_controller.go index e65f3e68a8a..1eddc67c364 100644 --- a/core/web/nodes_controller.go +++ b/core/web/nodes_controller.go @@ -1,6 +1,7 @@ package web import ( + "context" "net/http" "github.com/gin-gonic/gin" @@ -8,8 +9,9 @@ import ( "github.com/smartcontractkit/chainlink-relay/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type NodesController interface { @@ -17,15 +19,32 @@ type NodesController interface { Index(c *gin.Context, size, page, offset int) } +type NetworkScopedNodeStatuser struct { + network relay.Network + relayers chainlink.RelayerChainInteroperators +} + +func NewNetworkScopedNodeStatuser(relayers chainlink.RelayerChainInteroperators, network relay.Network) *NetworkScopedNodeStatuser { + scoped := relayers.List(chainlink.FilterRelayersByType(network)) + return &NetworkScopedNodeStatuser{ + network: network, + relayers: scoped, + } +} + +func (n *NetworkScopedNodeStatuser) NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) { + return n.relayers.NodeStatuses(ctx, offset, limit, relayIDs...) +} + type nodesController[R jsonapi.EntityNamer] struct { - nodeSet chains.NodesStatuser + nodeSet *NetworkScopedNodeStatuser errNotEnabled error newResource func(status types.NodeStatus) R auditLogger audit.AuditLogger } func newNodesController[R jsonapi.EntityNamer]( - nodeSet chains.NodesStatuser, + nodeSet *NetworkScopedNodeStatuser, errNotEnabled error, newResource func(status types.NodeStatus) R, auditLogger audit.AuditLogger, @@ -55,7 +74,14 @@ func (n *nodesController[R]) Index(c *gin.Context, size, page, offset int) { nodes, count, err = n.nodeSet.NodeStatuses(c, offset, size) } else { // fetch nodes for chain ID - nodes, count, err = n.nodeSet.NodeStatuses(c, offset, size, id) + // backward compatibility + var rid relay.ID + err := rid.UnmarshalString(id) + if err != nil { + rid.ChainID = relay.ChainID(id) + rid.Network = n.nodeSet.network + } + nodes, count, err = n.nodeSet.NodeStatuses(c, offset, size, rid) } var resources []R diff --git a/core/web/solana_nodes_controller.go b/core/web/solana_nodes_controller.go index 1c12418a5b2..d5fbc05ccf5 100644 --- a/core/web/solana_nodes_controller.go +++ b/core/web/solana_nodes_controller.go @@ -10,6 +10,8 @@ import ( var ErrSolanaNotEnabled = errChainDisabled{name: "Solana", tomlKey: "Solana.Enabled"} func NewSolanaNodesController(app chainlink.Application) NodesController { + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.Solana) + return newNodesController[presenters.SolanaNodeResource]( - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Solana)), ErrSolanaNotEnabled, presenters.NewSolanaNodeResource, app.GetAuditLogger()) + scopedNodeStatuser, ErrSolanaNotEnabled, presenters.NewSolanaNodeResource, app.GetAuditLogger()) } diff --git a/core/web/starknet_nodes_controller.go b/core/web/starknet_nodes_controller.go index d630bc102c1..d2881f2e65a 100644 --- a/core/web/starknet_nodes_controller.go +++ b/core/web/starknet_nodes_controller.go @@ -10,9 +10,8 @@ import ( var ErrStarkNetNotEnabled = errChainDisabled{name: "StarkNet", tomlKey: "Starknet.Enabled"} func NewStarkNetNodesController(app chainlink.Application) NodesController { + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.StarkNet) + return newNodesController[presenters.StarkNetNodeResource]( - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.StarkNet)), - ErrStarkNetNotEnabled, - presenters.NewStarkNetNodeResource, - app.GetAuditLogger()) + scopedNodeStatuser, ErrStarkNetNotEnabled, presenters.NewStarkNetNodeResource, app.GetAuditLogger()) } From a87a7e6b7c6cb4a5ca03acdc0eb5c36f6abdcddb Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Wed, 6 Sep 2023 22:44:11 +0100 Subject: [PATCH 41/88] Resolve TODOs in registry and provider life cycle (#10477) * HasFilter to check whether some filter was loaded by the poller * resovle TODOs * update comment * simplify error handling * fix test --------- Co-authored-by: amirylm --- .../evm21/logprovider/provider_life_cycle.go | 10 ++++----- .../logprovider/provider_life_cycle_test.go | 6 ++++- .../ocr2/plugins/ocr2keeper/evm21/registry.go | 22 +++++++++---------- .../ocr2/plugins/ocr2keeper/evm21/services.go | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go index 0e2c0068bab..baf04ee7e2f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go @@ -145,11 +145,11 @@ func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filt } func (p *logEventProvider) UnregisterFilter(upkeepID *big.Int) error { - err := p.poller.UnregisterFilter(p.filterName(upkeepID)) - if err != nil { - // TODO: mark as removed in filter store, so we'll - // automatically retry on next refresh - return fmt.Errorf("failed to unregister upkeep filter %s: %w", upkeepID.String(), err) + // Filter might have been unregistered already, only try to unregister if it exists + if p.poller.HasFilter(p.filterName(upkeepID)) { + if err := p.poller.UnregisterFilter(p.filterName(upkeepID)); err != nil { + return fmt.Errorf("failed to unregister upkeep filter %s: %w", upkeepID.String(), err) + } } p.filterStore.RemoveActiveUpkeeps(upkeepFilter{ upkeepID: upkeepID, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go index e51871c4784..4b1ff06f316 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go @@ -110,7 +110,11 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { lp.On("RegisterFilter", mock.Anything).Return(nil) lp.On("UnregisterFilter", mock.Anything).Return(nil) lp.On("LatestBlock", mock.Anything).Return(int64(0), nil) - lp.On("HasFilter", p.filterName(tc.upkeepID)).Return(tc.hasFilter).Times(1) + hasFitlerTimes := 1 + if tc.unregister { + hasFitlerTimes = 2 + } + lp.On("HasFilter", p.filterName(tc.upkeepID)).Return(tc.hasFilter).Times(hasFitlerTimes) if tc.replyed { lp.On("ReplayAsync", mock.Anything).Return(nil).Times(1) } else { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go index 1c54bf553d9..ee0dfb7b252 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go @@ -36,9 +36,7 @@ const ( // defaultAllowListExpiration decides how long an upkeep's allow list info will be valid for. defaultAllowListExpiration = 20 * time.Minute // allowListCleanupInterval decides when the expired items in allowList cache will be deleted. - allowListCleanupInterval = 5 * time.Minute - // TODO decide on a value for this - indexedLogsConfirmations = 10 + allowListCleanupInterval = 5 * time.Minute logTriggerRefreshBatchSize = 32 ) @@ -82,6 +80,7 @@ func NewEvmRegistry( logEventProvider logprovider.LogEventProvider, packer encoding.Packer, blockSub *BlockSubscriber, + finalityDepth uint32, ) *EvmRegistry { return &EvmRegistry{ lggr: lggr.Named("EvmRegistry"), @@ -103,6 +102,7 @@ func NewEvmRegistry( hc: http.DefaultClient, logEventProvider: logEventProvider, bs: blockSub, + finalityDepth: finalityDepth, } } @@ -148,6 +148,7 @@ type EvmRegistry struct { hc HttpClient bs *BlockSubscriber logEventProvider logprovider.LogEventProvider + finalityDepth uint32 } func (r *EvmRegistry) Name() string { @@ -287,17 +288,16 @@ func (r *EvmRegistry) refreshActiveUpkeeps() error { } } - newUpkeeps, err := r.logEventProvider.RefreshActiveUpkeeps(logTriggerIDs...) + _, err = r.logEventProvider.RefreshActiveUpkeeps(logTriggerIDs...) if err != nil { return fmt.Errorf("failed to refresh active upkeep ids in log event provider: %w", err) } - return r.refreshLogTriggerUpkeeps(newUpkeeps) + // Try to refersh log trigger config for all log upkeeps + return r.refreshLogTriggerUpkeeps(logTriggerIDs) } // refreshLogTriggerUpkeeps refreshes the active upkeep ids for log trigger upkeeps -// -// TODO: check for updated config for log trigger upkeeps and update it, currently we ignore them. func (r *EvmRegistry) refreshLogTriggerUpkeeps(ids []*big.Int) error { var err error for i := 0; i < len(ids); i += logTriggerRefreshBatchSize { @@ -323,11 +323,11 @@ func (r *EvmRegistry) refreshLogTriggerUpkeepsBatch(logTriggerIDs []*big.Int) er logTriggerHashes = append(logTriggerHashes, common.BigToHash(id)) } - unpausedLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic(), r.addr, 1, logTriggerHashes, indexedLogsConfirmations, pg.WithParentCtx(r.ctx)) + unpausedLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic(), r.addr, 1, logTriggerHashes, int(r.finalityDepth), pg.WithParentCtx(r.ctx)) if err != nil { return err } - configSetLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic(), r.addr, 1, logTriggerHashes, indexedLogsConfirmations, pg.WithParentCtx(r.ctx)) + configSetLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic(), r.addr, 1, logTriggerHashes, int(r.finalityDepth), pg.WithParentCtx(r.ctx)) if err != nil { return err } @@ -361,13 +361,13 @@ func (r *EvmRegistry) refreshLogTriggerUpkeepsBatch(logTriggerIDs []*big.Int) er for _, id := range logTriggerIDs { logBlock, ok := configSetBlockNumbers[id.String()] if !ok { - r.lggr.Warnf("unable to find config set block number for %s", id.String()) + r.lggr.Warnf("unable to find finalized config set block number for %s, skipping refresh", id.String()) continue } config, ok := perUpkeepConfig[id.String()] if !ok { - r.lggr.Warnf("unable to find per upkeep config for %s", id.String()) + r.lggr.Warnf("unable to find per finalized log config for %s, skipping refresh", id.String()) continue } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/services.go b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go index 55466d28996..1c666dc7cac 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/services.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go @@ -87,7 +87,7 @@ func New(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, k services.reg = NewEvmRegistry(lggr, addr, client, streamsLookupCompatibleABI, keeperRegistryABI, registryContract, mc, al, services.logProvider, - packer, services.blockSub) + packer, services.blockSub, finalityDepth) services.upkeepProvider = NewUpkeepProvider(al, services.blockSub, client.LogPoller()) From 55be16296d92992346cc58a44a2bf7d15af3f618 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Wed, 6 Sep 2023 18:17:09 -0400 Subject: [PATCH 42/88] (feat): Add Gateways to Functions core/scripts oracle.toml template (#10409) Co-authored-by: Morgan Kuphal <87319522+KuphJr@users.noreply.github.com> --- core/scripts/functions/src/generate_jobspecs_cmd.go | 10 +++++++--- core/scripts/functions/templates/oracle.toml | 6 +++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/scripts/functions/src/generate_jobspecs_cmd.go b/core/scripts/functions/src/generate_jobspecs_cmd.go index 332e2bdc0cb..4f35dac51bd 100644 --- a/core/scripts/functions/src/generate_jobspecs_cmd.go +++ b/core/scripts/functions/src/generate_jobspecs_cmd.go @@ -31,6 +31,8 @@ func (g *generateJobSpecs) Run(args []string) { donID := fs.String("donid", "", "don id string") routerAddress := fs.String("contract", "", "router contract address") truncateHostname := fs.Bool("truncateboothostname", false, "truncate host name to first segment (needed for staging DONs)") + gatewayID := fs.String("gatewayid", "", "gateway id string") + gatewayURL := fs.String("gatewayurl", "", "gateway url string") err := fs.Parse(args) if err != nil || nodesFile == nil || *nodesFile == "" || routerAddress == nil || *routerAddress == "" { fs.Usage() @@ -45,7 +47,7 @@ func (g *generateJobSpecs) Run(args []string) { helpers.PanicErr(err) bootHost := nodes[0].url.Host - lines = replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &bootstrapNode, *truncateHostname) + lines = replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &bootstrapNode, *truncateHostname, *gatewayID, *gatewayURL) outputPath := filepath.Join(artefactsDir, bootHost+".toml") err = writeLines(lines, outputPath) helpers.PanicErr(err) @@ -54,7 +56,7 @@ func (g *generateJobSpecs) Run(args []string) { lines, err = readLines(filepath.Join(templatesDir, oracleSpecTemplate)) helpers.PanicErr(err) for i := 1; i < len(nodes); i++ { - oracleLines := replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &nca[i], *truncateHostname) + oracleLines := replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &nca[i], *truncateHostname, *gatewayID, *gatewayURL) outputPath := filepath.Join(artefactsDir, nodes[i].url.Host+".toml") err = writeLines(oracleLines, outputPath) helpers.PanicErr(err) @@ -62,7 +64,7 @@ func (g *generateJobSpecs) Run(args []string) { } } -func replacePlaceholders(lines []string, donID string, chainID, p2pPort int64, routerAddress, bootHost string, boot *NodeKeys, node *NodeKeys, truncateHostname bool) (output []string) { +func replacePlaceholders(lines []string, donID string, chainID, p2pPort int64, routerAddress, bootHost string, boot *NodeKeys, node *NodeKeys, truncateHostname bool, gatewayID string, gatewayURL string) (output []string) { chainIDStr := strconv.FormatInt(chainID, 10) if truncateHostname { bootHost = bootHost[:strings.IndexByte(bootHost, '.')] @@ -77,6 +79,8 @@ func replacePlaceholders(lines []string, donID string, chainID, p2pPort int64, r l = strings.Replace(l, "{{p2p_bootstrapper}}", bootstrapper, 1) l = strings.Replace(l, "{{timestamp}}", ts, 1) l = strings.Replace(l, "{{don_id}}", donID, 1) + l = strings.Replace(l, "{{gateway_id}}", gatewayID, 1) + l = strings.Replace(l, "{{gateway_url}}", gatewayURL, 1) output = append(output, l) } return diff --git a/core/scripts/functions/templates/oracle.toml b/core/scripts/functions/templates/oracle.toml index 092965ca7a5..208637b50fc 100644 --- a/core/scripts/functions/templates/oracle.toml +++ b/core/scripts/functions/templates/oracle.toml @@ -67,4 +67,8 @@ maxSecretsSizesList = [10_240, 20_480, 51_200, 102_400, 307_200, 512_000, 1_048_ NodeAddress = "{{node_eth_address}}" [pluginConfig.gatewayConnectorConfig.WsClientConfig] - HandshakeTimeoutMillis = 1_000 \ No newline at end of file + HandshakeTimeoutMillis = 1_000 + + [[pluginConfig.gatewayConnectorConfig.Gateways]] + Id = "{{gateway_id}}" + URL = "{{gateway_url}}" \ No newline at end of file From 3dfb527cf4157547244883fdccf4cc6c3fb07a2e Mon Sep 17 00:00:00 2001 From: Awbrey Hughlett Date: Wed, 6 Sep 2023 17:53:24 -0500 Subject: [PATCH 43/88] Update Simulated Backend Client (#10403) * Update Simulated Backend Client This commit aims to improve the simulated backend client by removing the block limit where only the latest block can be provided to `CallContext` and handling input args more gracefully. - `CallContext` will now only validate the block number passed in args - `CallContext` will NOT restrict calls to current block, but will pass nil to backend - `from` in call args is no longer required and will default to `0x` - `from` and `to` accept `common.Address`, `*big.Int` and `string` types Included is a move to Go standard error handling consistent with v1.20+ and error wrapping. * remove commented code * add comments at top of file and panic on unrecognized value type * updated error handling and comments * address comments --- core/chains/evm/client/doc.go | 10 ++ .../evm/client/simulated_backend_client.go | 134 ++++++++++++------ 2 files changed, 102 insertions(+), 42 deletions(-) create mode 100644 core/chains/evm/client/doc.go diff --git a/core/chains/evm/client/doc.go b/core/chains/evm/client/doc.go new file mode 100644 index 00000000000..f3cba4a0db2 --- /dev/null +++ b/core/chains/evm/client/doc.go @@ -0,0 +1,10 @@ +/* +The simulated backend cannot access old blocks and will return an error if +anything other than `latest`, `nil`, or the latest block are passed to +`CallContract`. + +The simulated client avoids the old block error from the simulated backend by +passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext` +and will not return an error when an old block is used. +*/ +package client diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go index 74b7aa54ece..dd79c549bfe 100644 --- a/core/chains/evm/client/simulated_backend_client.go +++ b/core/chains/evm/client/simulated_backend_client.go @@ -3,6 +3,7 @@ package client import ( "bytes" "context" + "errors" "fmt" "math/big" "strings" @@ -16,7 +17,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" - "github.com/pkg/errors" clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client" "github.com/smartcontractkit/chainlink/v2/core/assets" @@ -64,37 +64,85 @@ func (c *SimulatedBackendClient) checkEthCallArgs( "must be an eth.CallArgs, got %+#v", args[0]) } blockNumber, err := c.blockNumber(args[1]) - if err != nil || blockNumber.Cmp(c.currentBlockNumber()) != 0 { + if err != nil { return nil, nil, fmt.Errorf("fourth arg to SimulatedBackendClient.Call "+ - "must be the string \"latest\", or a *big.Int equal to current "+ - "blocknumber, got %#+v", args[1]) + "must be the string \"latest\", or a *big.Int, got %#+v", args[1]) } + + // to and from need to map to a common.Address but could come in as a string + var ( + toAddr common.Address + frmAddr common.Address + ) + + toAddr, err = interfaceToAddress(callArgs["to"]) + if err != nil { + return nil, nil, err + } + + // from is optional in the standard client; default to 0x when missing + if value, ok := callArgs["from"]; ok { + addr, err := interfaceToAddress(value) + if err != nil { + return nil, nil, err + } + + frmAddr = addr + } else { + frmAddr = common.HexToAddress("0x") + } + ca := CallArgs{ - From: callArgs["from"].(common.Address), - To: *callArgs["to"].(*common.Address), + To: toAddr, + From: frmAddr, Data: callArgs["data"].(hexutil.Bytes), } + return &ca, blockNumber, nil } +func interfaceToAddress(value interface{}) (common.Address, error) { + switch v := value.(type) { + case common.Address: + return v, nil + case string: + return common.HexToAddress(v), nil + case *big.Int: + return common.BigToAddress(v), nil + default: + return common.HexToAddress("0x"), fmt.Errorf("unrecognized value type for converting value to common.Address; try string, *big.Int, or common.Address") + } +} + // CallContext mocks the ethereum client RPC calls used by chainlink, copying the // return value into result. +// The simulated client avoids the old block error from the simulated backend by +// passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext` +// and will not return an error when an old block is used. func (c *SimulatedBackendClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { switch method { case "eth_call": - callArgs, _, err := c.checkEthCallArgs(args) - if err != nil { + var ( + callArgs *CallArgs + b []byte + err error + ) + + if callArgs, _, err = c.checkEthCallArgs(args); err != nil { return err } + callMsg := ethereum.CallMsg{From: callArgs.From, To: &callArgs.To, Data: callArgs.Data} - b, err := c.b.CallContract(ctx, callMsg, nil /* always latest block */) - if err != nil { - return errors.Wrapf(err, "while calling contract at address %x with "+ - "data %x", callArgs.To, callArgs.Data) + + if b, err = c.b.CallContract(ctx, callMsg, nil /* always latest block */); err != nil { + return fmt.Errorf("%w: while calling contract at address %x with "+ + "data %x", err, callArgs.To, callArgs.Data) } + switch r := result.(type) { case *hexutil.Bytes: *r = append(*r, b...) + if !bytes.Equal(*r, b) { return fmt.Errorf("was passed a non-empty array, or failed to copy "+ "answer. Expected %x = %x", *r, b) @@ -155,26 +203,26 @@ func init() { var err error balanceOfABI, err = abi.JSON(strings.NewReader(balanceOfABIString)) if err != nil { - panic(errors.Wrapf(err, "while parsing erc20ABI")) + panic(fmt.Errorf("%w: while parsing erc20ABI", err)) } } func (c *SimulatedBackendClient) TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (balance *big.Int, err error) { callData, err := balanceOfABI.Pack("balanceOf", address) if err != nil { - return nil, errors.Wrapf(err, "while seeking the ERC20 balance of %s on %s", + return nil, fmt.Errorf("%w: while seeking the ERC20 balance of %s on %s", err, address, contractAddress) } b, err := c.b.CallContract(ctx, ethereum.CallMsg{ To: &contractAddress, Data: callData}, c.currentBlockNumber()) if err != nil { - return nil, errors.Wrapf(err, "while calling ERC20 balanceOf method on %s "+ - "for balance of %s", contractAddress, address) + return nil, fmt.Errorf("%w: while calling ERC20 balanceOf method on %s "+ + "for balance of %s", err, contractAddress, address) } err = balanceOfABI.UnpackIntoInterface(balance, "balanceOf", b) if err != nil { - return nil, errors.New("unable to unpack balance") + return nil, fmt.Errorf("unable to unpack balance") } return balance, nil } @@ -208,8 +256,8 @@ func (c *SimulatedBackendClient) blockNumber(number interface{}) (blockNumber *b default: blockNumber, err = utils.HexToUint256(n) if err != nil { - return nil, errors.Wrapf(err, "while parsing '%s' as hex-encoded"+ - "block number", n) + return nil, fmt.Errorf("%w: while parsing '%s' as hex-encoded"+ + "block number", err, n) } return blockNumber, nil } @@ -328,8 +376,8 @@ func (c *SimulatedBackendClient) SubscribeNewHead( var err error subscription.subscription, err = c.b.SubscribeNewHead(ctx, ch) if err != nil { - return nil, errors.Wrapf(err, "could not subscribe to new heads on "+ - "simulated backend") + return nil, fmt.Errorf("%w: could not subscribe to new heads on "+ + "simulated backend", err) } go func() { var lastHead *evmtypes.Head @@ -428,8 +476,7 @@ func (c *SimulatedBackendClient) CallContract(ctx context.Context, msg ethereum. res, err := c.b.CallContract(ctx, msg, blockNumber) if err != nil { dataErr := revertError{} - isCustomRevert := errors.As(err, &dataErr) - if isCustomRevert { + if errors.Is(err, &dataErr) { return nil, &JsonError{Data: dataErr.ErrorData(), Message: dataErr.Error(), Code: 3} } // Generic revert, no data @@ -459,6 +506,9 @@ func (c *SimulatedBackendClient) SuggestGasPrice(ctx context.Context) (*big.Int, } // BatchCallContext makes a batch rpc call. +// The simulated client avoids the old block error from the simulated backend by +// passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext` +// and will not return an error when an old block is used. func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { select { case <-ctx.Done(): @@ -471,14 +521,14 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B switch elem.Method { case "eth_getTransactionReceipt": if _, ok := elem.Result.(*evmtypes.Receipt); !ok { - return errors.Errorf("SimulatedBackendClient expected return type of *evmtypes.Receipt for eth_getTransactionReceipt, got type %T", elem.Result) + return fmt.Errorf("SimulatedBackendClient expected return type of *evmtypes.Receipt for eth_getTransactionReceipt, got type %T", elem.Result) } if len(elem.Args) != 1 { - return errors.Errorf("SimulatedBackendClient expected 1 arg, got %d for eth_getTransactionReceipt", len(elem.Args)) + return fmt.Errorf("SimulatedBackendClient expected 1 arg, got %d for eth_getTransactionReceipt", len(elem.Args)) } hash, is := elem.Args[0].(common.Hash) if !is { - return errors.Errorf("SimulatedBackendClient expected arg to be a hash, got: %T", elem.Args[0]) + return fmt.Errorf("SimulatedBackendClient expected arg to be a hash, got: %T", elem.Args[0]) } receipt, err := c.b.TransactionReceipt(ctx, hash) if receipt != nil { @@ -490,22 +540,22 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B case *evmtypes.Head: case *evmtypes.Block: default: - return errors.Errorf("SimulatedBackendClient expected return type of [*evmtypes.Head] or [*evmtypes.Block] for eth_getBlockByNumber, got type %T", v) + return fmt.Errorf("SimulatedBackendClient expected return type of [*evmtypes.Head] or [*evmtypes.Block] for eth_getBlockByNumber, got type %T", v) } if len(elem.Args) != 2 { - return errors.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getBlockByNumber", len(elem.Args)) + return fmt.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getBlockByNumber", len(elem.Args)) } blockNum, is := elem.Args[0].(string) if !is { - return errors.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getBlockByNumber, got: %T", elem.Args[0]) + return fmt.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getBlockByNumber, got: %T", elem.Args[0]) } _, is = elem.Args[1].(bool) if !is { - return errors.Errorf("SimulatedBackendClient expected second arg to be a boolean for eth_getBlockByNumber, got: %T", elem.Args[1]) + return fmt.Errorf("SimulatedBackendClient expected second arg to be a boolean for eth_getBlockByNumber, got: %T", elem.Args[1]) } n, ok := new(big.Int).SetString(blockNum, 0) if !ok { - return errors.Errorf("error while converting block number string: %s to big.Int ", blockNum) + return fmt.Errorf("error while converting block number string: %s to big.Int ", blockNum) } header, err := c.b.HeaderByNumber(ctx, n) if err != nil { @@ -525,33 +575,33 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B Timestamp: time.Unix(int64(header.Time), 0), } default: - return errors.Errorf("SimulatedBackendClient Unexpected Type %T", v) + return fmt.Errorf("SimulatedBackendClient Unexpected Type %T", v) } b[i].Error = err case "eth_call": if len(elem.Args) != 2 { - return errors.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_call", len(elem.Args)) + return fmt.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_call", len(elem.Args)) } _, ok := elem.Result.(*string) if !ok { - return errors.Errorf("SimulatedBackendClient expected result to be *string for eth_call, got: %T", elem.Result) + return fmt.Errorf("SimulatedBackendClient expected result to be *string for eth_call, got: %T", elem.Result) } params, ok := elem.Args[0].(map[string]interface{}) if !ok { - return errors.Errorf("SimulatedBackendClient expected first arg to be map[string]interface{} for eth_call, got: %T", elem.Args[0]) + return fmt.Errorf("SimulatedBackendClient expected first arg to be map[string]interface{} for eth_call, got: %T", elem.Args[0]) } blockNum, ok := elem.Args[1].(string) if !ok { - return errors.Errorf("SimulatedBackendClient expected second arg to be a string for eth_call, got: %T", elem.Args[1]) + return fmt.Errorf("SimulatedBackendClient expected second arg to be a string for eth_call, got: %T", elem.Args[1]) } if blockNum != "" { if _, ok = new(big.Int).SetString(blockNum, 0); !ok { - return errors.Errorf("error while converting block number string: %s to big.Int ", blockNum) + return fmt.Errorf("error while converting block number string: %s to big.Int ", blockNum) } } @@ -561,15 +611,15 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B b[i].Error = err case "eth_getHeaderByNumber": if len(elem.Args) != 1 { - return errors.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getHeaderByNumber", len(elem.Args)) + return fmt.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getHeaderByNumber", len(elem.Args)) } blockNum, is := elem.Args[0].(string) if !is { - return errors.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getHeaderByNumber, got: %T", elem.Args[0]) + return fmt.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getHeaderByNumber, got: %T", elem.Args[0]) } n, err := hexutil.DecodeBig(blockNum) if err != nil { - return errors.Errorf("error while converting hex block number %s to big.Int ", blockNum) + return fmt.Errorf("error while converting hex block number %s to big.Int ", blockNum) } header, err := c.b.HeaderByNumber(ctx, n) if err != nil { @@ -579,10 +629,10 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B case *types.Header: b[i].Result = header default: - return errors.Errorf("SimulatedBackendClient Unexpected Type %T", v) + return fmt.Errorf("SimulatedBackendClient Unexpected Type %T", v) } default: - return errors.Errorf("SimulatedBackendClient got unsupported method %s", elem.Method) + return fmt.Errorf("SimulatedBackendClient got unsupported method %s", elem.Method) } } return nil From e5487f08df3bf65c3690cf1595a535b67b7f3888 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Wed, 6 Sep 2023 19:16:03 -0400 Subject: [PATCH 44/88] Create CI checks for GQL schema changes (#7492) * Create CI checks for GQL schema changes * Use github token issuer * Fix action references * Change OIDC roles to new names * Correct action name * Add role session name support * Update permission to allow for PR comments * Run latest github app token issuer action * TEST - Metrics collection * Use latest action * Clean up * Update AWS cred action * Update secret refs --- .../{operator-ui.yml => operator-ui-cd.yml} | 21 ++++++++- .github/workflows/operator-ui-ci.yml | 46 +++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) rename .github/workflows/{operator-ui.yml => operator-ui-cd.yml} (59%) create mode 100644 .github/workflows/operator-ui-ci.yml diff --git a/.github/workflows/operator-ui.yml b/.github/workflows/operator-ui-cd.yml similarity index 59% rename from .github/workflows/operator-ui.yml rename to .github/workflows/operator-ui-cd.yml index bd3655436c3..488e93778e6 100644 --- a/.github/workflows/operator-ui.yml +++ b/.github/workflows/operator-ui-cd.yml @@ -1,4 +1,4 @@ -name: Operator UI +name: Operator UI CD on: push: @@ -6,10 +6,12 @@ on: - develop workflow_dispatch: schedule: - - cron: '0 */1 * * *' # Run every hour + - cron: "0 */1 * * *" # Run every hour jobs: update-version: + permissions: + id-token: write name: Update Version runs-on: ubuntu-latest steps: @@ -22,10 +24,25 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./operator_ui/check.sh + - name: Assume role capable of dispatching action + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + role-to-assume: ${{ secrets.AWS_OIDC_CHAINLINK_CI_AUTO_PR_TOKEN_ISSUER_ROLE_ARN }} + role-duration-seconds: ${{ secrets.aws-role-duration-seconds }} + role-session-name: operator-ui-cd.update-version + aws-region: ${{ secrets.AWS_REGION }} + + - name: Get Github Token + id: get-gh-token + uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@chore/update-github-app-token-issuer + with: + url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }} + - name: Open PR uses: peter-evans/create-pull-request@38e0b6e68b4c852a5500a94740f0e535e0d7ba54 # v4.2.4 with: title: Update Operator UI from ${{ steps.update.outputs.current_tag }} to ${{ steps.update.outputs.latest_tag }} + token: ${{ steps.get-gh-token.outputs.access-token }} branch: chore/update-operator-ui commit-message: Update Operator UI from ${{ steps.update.outputs.current_tag }} to ${{ steps.update.outputs.latest_tag }} body: ${{ steps.update.outputs.body }} diff --git a/.github/workflows/operator-ui-ci.yml b/.github/workflows/operator-ui-ci.yml new file mode 100644 index 00000000000..b73106177c5 --- /dev/null +++ b/.github/workflows/operator-ui-ci.yml @@ -0,0 +1,46 @@ +name: Operator UI CI +on: + pull_request: + +jobs: + check-gql: + permissions: + id-token: write + contents: read + # To allow writing comments to the current PR + pull-requests: write + + name: Breaking Changes GQL Check + runs-on: ubuntu-latest + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@v1 + with: + basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + this-job-name: Breaking Changes GQL Check + continue-on-error: true + + - name: Assume role capable of dispatching action + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + role-to-assume: ${{ secrets.AWS_OIDC_CHAINLINK_CI_OPERATOR_UI_ACCESS_TOKEN_ISSUER_ROLE_ARN }} + role-duration-seconds: 3600 + role-session-name: operator-ui-ci.check-gql + aws-region: ${{ secrets.AWS_REGION }} + + - name: Get Github Token + id: get-gh-token + uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@main + with: + url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }} + + - uses: convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be #v1.6.5 + with: + owner: smartcontractkit + repo: operator-ui + comment_downstream_url: ${{ github.event.pull_request.comments_url }} + github_token: ${{ steps.get-gh-token.outputs.access-token }} + workflow_file_name: chainlink-ci.yml + client_payload: '{"ref": "${{ github.event.pull_request.head.sha }}"}' From a7dc6f1b81d81000cff4fe94ad221cbc9a70b93d Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Wed, 6 Sep 2023 19:36:07 -0400 Subject: [PATCH 45/88] (test): Add ToS Allow List foundry tests (#10438) * (test): Add Functions Subscriptions foundry tests * (test): Add ToS Allow List foundry tests --- .../gas-snapshots/functions.gas-snapshot | 25 +- .../FunctionsTermsOfServiceAllowList.t.sol | 313 +++++++++++++++++- 2 files changed, 325 insertions(+), 13 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 56d8a4da7fd..00ebdc48dfd 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -29,7 +29,7 @@ FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSub FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20103) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193421) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_Success() (gas: 67209) -FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7609) +FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7609) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28659) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17970) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 371776) @@ -88,4 +88,25 @@ FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57781) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26368) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15714) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152510) \ No newline at end of file +FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152510) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25855) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44366) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23615) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1469094) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26021) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1549182) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 94702) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 50442) +FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12187) +FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19243) +FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15773) +FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11592) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15931) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23445) +FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15354) +FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 41957) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13525) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 95208) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13736) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22082) diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol index af6fa6dcca5..d4a18e207b4 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol @@ -1,52 +1,343 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/// @notice #constructor -contract FunctionsTermsOfServiceAllowList_Constructor { +import {TermsOfServiceAllowList} from "../../dev/1_0_0/accessControl/TermsOfServiceAllowList.sol"; +import {FunctionsClientTestHelper} from "./testhelpers/FunctionsClientTestHelper.sol"; + +import {FunctionsRoutesSetup, FunctionsOwnerAcceptTermsOfServiceSetup} from "./Setup.t.sol"; +/// @notice #constructor +contract FunctionsTermsOfServiceAllowList_Constructor is FunctionsRoutesSetup { + function test_Constructor_Success() public { + assertEq(s_termsOfServiceAllowList.typeAndVersion(), "Functions Terms of Service Allow List v1.0.0"); + assertEq(s_termsOfServiceAllowList.owner(), OWNER_ADDRESS); + } } /// @notice #getConfig -contract FunctionsTermsOfServiceAllowList_GetConfig { +contract FunctionsTermsOfServiceAllowList_GetConfig is FunctionsRoutesSetup { + function test_GetConfig_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + TermsOfServiceAllowList.Config memory config = s_termsOfServiceAllowList.getConfig(); + assertEq(config.enabled, getTermsOfServiceConfig().enabled); + assertEq(config.signerPublicKey, getTermsOfServiceConfig().signerPublicKey); + } } /// @notice #updateConfig -contract FunctionsTermsOfServiceAllowList_UpdateConfig { +contract FunctionsTermsOfServiceAllowList_UpdateConfig is FunctionsRoutesSetup { + function test_UpdateConfig_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_termsOfServiceAllowList.updateConfig( + TermsOfServiceAllowList.Config({enabled: true, signerPublicKey: STRANGER_ADDRESS}) + ); + } + + event ConfigUpdated(TermsOfServiceAllowList.Config config); + + function test_UpdateConfig_Success() public { + TermsOfServiceAllowList.Config memory configToSet = TermsOfServiceAllowList.Config({ + enabled: false, + signerPublicKey: TOS_SIGNER + }); + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit ConfigUpdated(configToSet); + + s_termsOfServiceAllowList.updateConfig(configToSet); + TermsOfServiceAllowList.Config memory config = s_termsOfServiceAllowList.getConfig(); + assertEq(config.enabled, configToSet.enabled); + assertEq(config.signerPublicKey, configToSet.signerPublicKey); + } } /// @notice #getMessage -contract FunctionsTermsOfServiceAllowList_GetMessage { +contract FunctionsTermsOfServiceAllowList_GetMessage is FunctionsRoutesSetup { + function test_GetMessage_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + + assertEq(message, keccak256(abi.encodePacked(STRANGER_ADDRESS, STRANGER_ADDRESS))); + } } /// @notice #acceptTermsOfService -contract FunctionsTermsOfServiceAllowList_AcceptTermsOfService { +contract FunctionsTermsOfServiceAllowList_AcceptTermsOfService is FunctionsRoutesSetup { + function test_AcceptTermsOfService_RevertIfBlockedSender() public { + s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS); + + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + + vm.expectRevert(TermsOfServiceAllowList.RecipientIsBlocked.selector); + + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + } + + function test_AcceptTermsOfService_RevertIfInvalidSigner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(STRANGER_PRIVATE_KEY, prefixedMessage); + + vm.expectRevert(TermsOfServiceAllowList.InvalidSignature.selector); + + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + } + + function test_AcceptTermsOfService_RevertIfRecipientIsNotSender() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 message = s_termsOfServiceAllowList.getMessage(OWNER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + + vm.expectRevert(TermsOfServiceAllowList.InvalidUsage.selector); + + s_termsOfServiceAllowList.acceptTermsOfService(OWNER_ADDRESS, STRANGER_ADDRESS, r, s, v); + } + + function test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, OWNER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + + vm.expectRevert(TermsOfServiceAllowList.InvalidUsage.selector); + + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, OWNER_ADDRESS, r, s, v); + } + + function test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() public { + FunctionsClientTestHelper s_functionsClientHelper = new FunctionsClientTestHelper(address(s_functionsRouter)); + + // Send as externally owned account + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + // Attempt to accept for a contract account + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, address(s_functionsClientHelper)); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + + vm.expectRevert(TermsOfServiceAllowList.InvalidUsage.selector); + + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, address(s_functionsClientHelper), r, s, v); + } + event AddedAccess(address user); + + function test_AcceptTermsOfService_SuccessIfAcceptingForSelf() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit AddedAccess(STRANGER_ADDRESS); + + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + + assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), true); + } + + function test_AcceptTermsOfService_SuccessIfAcceptingForContract() public { + FunctionsClientTestHelper s_functionsClientHelper = new FunctionsClientTestHelper(address(s_functionsRouter)); + + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, address(s_functionsClientHelper)); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit AddedAccess(address(s_functionsClientHelper)); + + s_functionsClientHelper.acceptTermsOfService(STRANGER_ADDRESS, address(s_functionsClientHelper), r, s, v); + + assertEq(s_termsOfServiceAllowList.hasAccess(address(s_functionsClientHelper), new bytes(0)), true); + } } /// @notice #getAllAllowedSenders -contract FunctionsTermsOfServiceAllowList_GetAllAllowedSenders { +contract FunctionsTermsOfServiceAllowList_GetAllAllowedSenders is FunctionsOwnerAcceptTermsOfServiceSetup { + function test_GetAllAllowedSenders_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + address[] memory expectedSenders = new address[](1); + expectedSenders[0] = OWNER_ADDRESS; + assertEq(s_termsOfServiceAllowList.getAllAllowedSenders(), expectedSenders); + } } /// @notice #hasAccess -contract FunctionsTermsOfServiceAllowList_HasAccess { +contract FunctionsTermsOfServiceAllowList_HasAccess is FunctionsRoutesSetup { + function test_HasAccess_FalseWhenEnabled() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + // Check access of account that is not on the allow list + assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), false); + } + + function test_HasAccess_TrueWhenDisabled() public { + // Disable allow list, which opens all access + s_termsOfServiceAllowList.updateConfig( + TermsOfServiceAllowList.Config({enabled: false, signerPublicKey: TOS_SIGNER}) + ); + + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + // Check access of account that is not on the allow list + assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), true); + } } /// @notice #isBlockedSender -contract FunctionsTermsOfServiceAllowList_IsBlockedSender { +contract FunctionsTermsOfServiceAllowList_IsBlockedSender is FunctionsRoutesSetup { + function test_IsBlockedSender_SuccessFalse() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + assertEq(s_termsOfServiceAllowList.isBlockedSender(STRANGER_ADDRESS), false); + } + + function test_IsBlockedSender_SuccessTrue() public { + // Block sender + s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS); + + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + assertEq(s_termsOfServiceAllowList.isBlockedSender(STRANGER_ADDRESS), true); + } } /// @notice #blockSender -contract FunctionsTermsOfServiceAllowList_BlockSender { +contract FunctionsTermsOfServiceAllowList_BlockSender is FunctionsRoutesSetup { + function test_BlockSender_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS); + } + + event BlockedAccess(address user); + + function test_BlockSender_Success() public { + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit BlockedAccess(STRANGER_ADDRESS); + + s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS); + assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), false); + assertEq(s_termsOfServiceAllowList.isBlockedSender(STRANGER_ADDRESS), true); + // Account can no longer accept Terms of Service + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + vm.expectRevert(TermsOfServiceAllowList.RecipientIsBlocked.selector); + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + } } /// @notice #unblockSender -contract FunctionsTermsOfServiceAllowList_UnblockSender { +contract FunctionsTermsOfServiceAllowList_UnblockSender is FunctionsRoutesSetup { + function setUp() public virtual override { + FunctionsRoutesSetup.setUp(); + + s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS); + } + + function test_UnblockSender_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_termsOfServiceAllowList.unblockSender(STRANGER_ADDRESS); + } + + event UnblockedAccess(address user); + + function test_UnblockSender_Success() public { + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit UnblockedAccess(STRANGER_ADDRESS); + + s_termsOfServiceAllowList.unblockSender(STRANGER_ADDRESS); + + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + // Account can now accept the Terms of Service + bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); + } } From 8f61ff24248cad930bd393ef949e45c9c0e6be96 Mon Sep 17 00:00:00 2001 From: martin-cll <121895364+martin-cll@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:44:02 +1000 Subject: [PATCH 46/88] Fix data race in PersistenceManager tests (#10394) * Fix data race in PersistenceManager tests * Fix import order --- .../relay/evm/mercury/persistence_manager.go | 23 ++++++++++++------- .../evm/mercury/persistence_manager_test.go | 6 ++--- .../services/relay/evm/mercury/transmitter.go | 9 +++----- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/core/services/relay/evm/mercury/persistence_manager.go b/core/services/relay/evm/mercury/persistence_manager.go index a840918df66..b8ae9bf72c0 100644 --- a/core/services/relay/evm/mercury/persistence_manager.go +++ b/core/services/relay/evm/mercury/persistence_manager.go @@ -30,14 +30,21 @@ type PersistenceManager struct { deleteQueue []*pb.TransmitRequest jobID int32 + + maxTransmitQueueSize int + flushDeletesFrequency time.Duration + pruneFrequency time.Duration } -func NewPersistenceManager(lggr logger.Logger, orm ORM, jobID int32) *PersistenceManager { +func NewPersistenceManager(lggr logger.Logger, orm ORM, jobID int32, maxTransmitQueueSize int, flushDeletesFrequency, pruneFrequency time.Duration) *PersistenceManager { return &PersistenceManager{ - lggr: lggr.Named("MercuryPersistenceManager"), - orm: orm, - stopCh: make(chan struct{}), - jobID: jobID, + lggr: lggr.Named("MercuryPersistenceManager"), + orm: orm, + stopCh: make(chan struct{}), + jobID: jobID, + maxTransmitQueueSize: maxTransmitQueueSize, + flushDeletesFrequency: flushDeletesFrequency, + pruneFrequency: pruneFrequency, } } @@ -80,7 +87,7 @@ func (pm *PersistenceManager) runFlushDeletesLoop() { ctx, cancel := pm.stopCh.Ctx(context.Background()) defer cancel() - ticker := time.NewTicker(utils.WithJitter(flushDeletesFrequency)) + ticker := time.NewTicker(utils.WithJitter(pm.flushDeletesFrequency)) for { select { case <-ctx.Done(): @@ -103,7 +110,7 @@ func (pm *PersistenceManager) runPruneLoop() { ctx, cancel := pm.stopCh.Ctx(context.Background()) defer cancel() - ticker := time.NewTicker(utils.WithJitter(pruneFrequency)) + ticker := time.NewTicker(utils.WithJitter(pm.pruneFrequency)) for { select { case <-ctx.Done(): @@ -111,7 +118,7 @@ func (pm *PersistenceManager) runPruneLoop() { return case <-ticker.C: pm.lggr.Trace("Pruning transmit requests table") - if err := pm.orm.PruneTransmitRequests(maxTransmitQueueSize, pg.WithParentCtx(ctx), pg.WithLongQueryTimeout()); err != nil { + if err := pm.orm.PruneTransmitRequests(pm.maxTransmitQueueSize, pg.WithParentCtx(ctx), pg.WithLongQueryTimeout()); err != nil { pm.lggr.Errorw("Failed to prune transmit requests table", "err", err) } } diff --git a/core/services/relay/evm/mercury/persistence_manager_test.go b/core/services/relay/evm/mercury/persistence_manager_test.go index 1b4a72f47f5..211e2c20c32 100644 --- a/core/services/relay/evm/mercury/persistence_manager_test.go +++ b/core/services/relay/evm/mercury/persistence_manager_test.go @@ -14,12 +14,13 @@ import ( ) func bootstrapPersistenceManager(t *testing.T) *PersistenceManager { + t.Helper() db := pgtest.NewSqlxDB(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`) lggr := logger.TestLogger(t) orm := NewORM(db, lggr, pgtest.NewQConfig(true)) - return NewPersistenceManager(lggr, orm, 0) + return NewPersistenceManager(lggr, orm, 0, 2, 10*time.Millisecond, 10*time.Millisecond) } func TestPersistenceManager(t *testing.T) { @@ -61,7 +62,6 @@ func TestPersistenceManagerAsyncDelete(t *testing.T) { err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[1]}, ocrtypes.ReportContext{}) require.NoError(t, err) - flushDeletesFrequency = 10 * time.Millisecond err = pm.Start(ctx) require.NoError(t, err) @@ -103,8 +103,6 @@ func TestPersistenceManagerPrune(t *testing.T) { err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[2]}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}}) require.NoError(t, err) - maxTransmitQueueSize = 2 - pruneFrequency = 10 * time.Millisecond err = pm.Start(ctx) require.NoError(t, err) diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go index f01ee474885..d259ab7a0ff 100644 --- a/core/services/relay/evm/mercury/transmitter.go +++ b/core/services/relay/evm/mercury/transmitter.go @@ -15,19 +15,16 @@ import ( pkgerrors "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "golang.org/x/exp/maps" - "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/sqlx" + "golang.org/x/exp/maps" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" - mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -122,7 +119,7 @@ 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) *mercuryTransmitter { feedIDHex := fmt.Sprintf("0x%x", feedID[:]) - persistenceManager := NewPersistenceManager(lggr, NewORM(db, lggr, cfg), jobID) + persistenceManager := NewPersistenceManager(lggr, NewORM(db, lggr, cfg), jobID, maxTransmitQueueSize, flushDeletesFrequency, pruneFrequency) return &mercuryTransmitter{ utils.StartStopOnce{}, lggr.Named("MercuryTransmitter").With("feedID", feedIDHex), From 9586f0774e409217fce7c97cf2d78875788b656d Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Thu, 7 Sep 2023 11:07:31 +0100 Subject: [PATCH 47/88] Upsert only if we filter store had a registered filter before (#10531) --- .../ocr2keeper/evm21/logprovider/provider_life_cycle.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go index baf04ee7e2f..52acb392e0e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go @@ -112,9 +112,10 @@ func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filt } lggr := p.lggr.With("upkeepID", ufilter.upkeepID.String()) logPollerHasFilter := p.poller.HasFilter(lpFilter.Name) - if logPollerHasFilter { + filterStoreHasFilter := p.filterStore.Has(ufilter.upkeepID) + if filterStoreHasFilter { + // removing filter in case of an update so we can recreate it with updated values lggr.Debugw("Upserting upkeep filter") - // removing filter so we can recreate it with updated values err := p.poller.UnregisterFilter(lpFilter.Name) if err != nil { return fmt.Errorf("failed to upsert (unregister) upkeep filter %s: %w", ufilter.upkeepID.String(), err) @@ -125,7 +126,7 @@ func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filt } p.filterStore.AddActiveUpkeeps(ufilter) if logPollerHasFilter { - // already registered, no need to backfill + // already registered in DB before, no need to backfill return nil } backfillBlock := latest - int64(LogBackfillBuffer) From f6586c0297a0ab8156ac88ebe0884d648df69b29 Mon Sep 17 00:00:00 2001 From: Makram Date: Thu, 7 Sep 2023 14:20:46 +0400 Subject: [PATCH 48/88] chore: add subscription api forge tests (#10446) * chore: add subscription api forge tests * add more tests update gethwrappers * chore: bump vrf snapshot * chore: prettier --- .../src/v0.8/dev/vrf/SubscriptionAPI.sol | 18 +- .../ExposedVRFCoordinatorV2Plus.sol | 32 + .../vrf/VRFV2PlusSubscriptionAPI.t.sol | 605 ++++++++++++++++++ .../vrf_coordinator_v2plus.go | 4 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 5 files changed, 653 insertions(+), 8 deletions(-) create mode 100644 contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol diff --git a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol index e9652d0bf6b..9e3181978f5 100644 --- a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol +++ b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol @@ -36,6 +36,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr error FailedToSendEther(); error FailedToTransferLink(); error IndexOutOfRange(); + error LinkNotSet(); // We use the subscription struct (1 word) // at fulfillment time. @@ -158,6 +159,14 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr * @param to address to send link to */ function recoverFunds(address to) external onlyOwner { + // If LINK is not set, we cannot recover funds. + // It is possible that this coordinator address was funded with LINK + // by accident by a user but the LINK token needs to be set first + // before we can recover it. + if (address(LINK) == address(0)) { + revert LinkNotSet(); + } + uint256 externalBalance = LINK.balanceOf(address(this)); uint256 internalBalance = uint256(s_totalBalance); if (internalBalance > externalBalance) { @@ -200,6 +209,9 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr * @param amount amount to withdraw */ function oracleWithdraw(address recipient, uint96 amount) external nonReentrant { + if (address(LINK) == address(0)) { + revert LinkNotSet(); + } if (s_withdrawableTokens[msg.sender] < amount) { revert InsufficientBalance(); } @@ -239,7 +251,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr if (s_subscriptionConfigs[subId].owner == address(0)) { revert InvalidSubscription(); } - // We do not check that the msg.sender is the subscription owner, + // We do not check that the sender is the subscription owner, // anyone can fund a subscription. uint256 oldBalance = s_subscriptions[subId].balance; s_subscriptions[subId].balance += uint96(amount); @@ -426,8 +438,4 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr } _; } - - function getConsumerKey(address consumer, uint256 subId) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(subId, consumer)); - } } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol index 82f4068112d..0d493867370 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol @@ -33,4 +33,36 @@ contract ExposedVRFCoordinatorV2Plus is VRFCoordinatorV2Plus { function getActiveSubscriptionIdsLength() external view returns (uint256) { return s_subIds.length(); } + + function getSubscriptionConfig(uint256 subId) external view returns (SubscriptionConfig memory) { + return s_subscriptionConfigs[subId]; + } + + function getSubscriptionStruct(uint256 subId) external view returns (Subscription memory) { + return s_subscriptions[subId]; + } + + function setTotalBalanceTestingOnlyXXX(uint96 newBalance) external { + s_totalBalance = newBalance; + } + + function setTotalEthBalanceTestingOnlyXXX(uint96 newBalance) external { + s_totalEthBalance = newBalance; + } + + function setWithdrawableTokensTestingOnlyXXX(address oracle, uint96 newBalance) external { + s_withdrawableTokens[oracle] = newBalance; + } + + function getWithdrawableTokensTestingOnlyXXX(address oracle) external view returns (uint96) { + return s_withdrawableTokens[oracle]; + } + + function setWithdrawableEthTestingOnlyXXX(address oracle, uint96 newBalance) external { + s_withdrawableEth[oracle] = newBalance; + } + + function getWithdrawableEthTestingOnlyXXX(address oracle) external view returns (uint96) { + return s_withdrawableEth[oracle]; + } } diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol new file mode 100644 index 00000000000..813b3d4c808 --- /dev/null +++ b/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol @@ -0,0 +1,605 @@ +pragma solidity 0.8.6; + +import "../BaseTest.t.sol"; +import {ExposedVRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol"; +import {SubscriptionAPI} from "../../../../src/v0.8/dev/vrf/SubscriptionAPI.sol"; +import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; +import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; // for Strings.toString + +contract VRFV2PlusSubscriptionAPITest is BaseTest { + event SubscriptionFunded(uint256 indexed subId, uint256 oldBalance, uint256 newBalance); + event SubscriptionFundedWithEth(uint256 indexed subId, uint256 oldEthBalance, uint256 newEthBalance); + event SubscriptionCanceled(uint256 indexed subId, address to, uint256 amountLink, uint256 amountEth); + event FundsRecovered(address to, uint256 amountLink); + event EthFundsRecovered(address to, uint256 amountEth); + event SubscriptionOwnerTransferRequested(uint256 indexed subId, address from, address to); + event SubscriptionOwnerTransferred(uint256 indexed subId, address from, address to); + event SubscriptionConsumerAdded(uint256 indexed subId, address consumer); + + ExposedVRFCoordinatorV2Plus s_subscriptionAPI; + + function setUp() public override { + BaseTest.setUp(); + address bhs = makeAddr("bhs"); + s_subscriptionAPI = new ExposedVRFCoordinatorV2Plus(bhs); + } + + function testDefaultState() public { + assertEq(address(s_subscriptionAPI.LINK()), address(0)); + assertEq(address(s_subscriptionAPI.LINK_ETH_FEED()), address(0)); + assertEq(s_subscriptionAPI.s_currentSubNonce(), 0); + assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); + assertEq(s_subscriptionAPI.s_totalBalance(), 0); + assertEq(s_subscriptionAPI.s_totalEthBalance(), 0); + } + + function testSetLINKAndLINKETHFeed() public { + address link = makeAddr("link"); + address linkEthFeed = makeAddr("linkEthFeed"); + s_subscriptionAPI.setLINKAndLINKETHFeed(link, linkEthFeed); + assertEq(address(s_subscriptionAPI.LINK()), link); + assertEq(address(s_subscriptionAPI.LINK_ETH_FEED()), linkEthFeed); + + // try setting it again, should revert + vm.expectRevert(SubscriptionAPI.LinkAlreadySet.selector); + s_subscriptionAPI.setLINKAndLINKETHFeed(link, linkEthFeed); + } + + function testOwnerCancelSubscriptionNoFunds() public { + // CASE: new subscription w/ no funds at all + // Should cancel trivially + + // Note that the link token is not set, but this should still + // not fail in that case. + + // Create the subscription from a separate address + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // change back to owner and cancel the subscription + changePrank(OWNER); + vm.expectEmit(true, false, false, true); + emit SubscriptionCanceled(subId, subOwner, 0, 0); + s_subscriptionAPI.ownerCancelSubscription(subId); + + // assert that the subscription no longer exists + assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, address(0)); + // no point in checking s_subscriptions because all fields are zeroed out + // due to no balance and no requests made + } + + function testOwnerCancelSubscriptionNativeFundsOnly() public { + // CASE: new subscription with native funds only + // no link funds. + // should cancel and return the native funds + + // Create the subscription from a separate address + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // fund the subscription with ether + vm.deal(subOwner, 10 ether); + vm.expectEmit(true, false, false, true); + emit SubscriptionFundedWithEth(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + + // change back to owner and cancel the subscription + changePrank(OWNER); + vm.expectEmit(true, false, false, true); + emit SubscriptionCanceled(subId, subOwner, 0 /* link balance */, 5 ether /* native balance */); + s_subscriptionAPI.ownerCancelSubscription(subId); + + // assert that the subscription no longer exists + assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, address(0)); + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).ethBalance, 0); + + // check the ether balance of the subOwner, should be 10 ether + assertEq(address(subOwner).balance, 10 ether); + } + + function testOwnerCancelSubscriptionLinkFundsOnly() public { + // CASE: new subscription with link funds only + // no native funds. + // should cancel and return the link funds + + // Create link token and set the link token on the subscription api object + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // Create the subscription from a separate address + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // fund the subscription with link + // can do it from the owner acct because anyone can fund a subscription + changePrank(OWNER); + vm.expectEmit(true, false, false, true); + emit SubscriptionFunded(subId, 0, 5 ether); + bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId)); + assertTrue(success, "failed link transfer and call"); + + // change back to owner and cancel the subscription + vm.expectEmit(true, false, false, true); + emit SubscriptionCanceled(subId, subOwner, 5 ether /* link balance */, 0 /* native balance */); + s_subscriptionAPI.ownerCancelSubscription(subId); + + // assert that the subscription no longer exists + assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, address(0)); + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).balance, 0); + + // check the link balance of the sub owner, should be 5 LINK + assertEq(linkToken.balanceOf(subOwner), 5 ether); + } + + function testOwnerCancelSubscriptionNativeAndLinkFunds() public { + // CASE: new subscription with link and native funds + // should cancel and return both link and native funds + + // Create link token and set the link token on the subscription api object + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // Create the subscription from a separate address + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // fund the subscription with link + changePrank(OWNER); + vm.expectEmit(true, false, false, true); + emit SubscriptionFunded(subId, 0, 5 ether); + bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId)); + assertTrue(success, "failed link transfer and call"); + + // fund the subscription with ether + vm.deal(subOwner, 10 ether); + changePrank(subOwner); + vm.expectEmit(true, false, false, true); + emit SubscriptionFundedWithEth(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + + // change back to owner and cancel the subscription + changePrank(OWNER); + vm.expectEmit(true, false, false, true); + emit SubscriptionCanceled(subId, subOwner, 5 ether /* link balance */, 5 ether /* native balance */); + s_subscriptionAPI.ownerCancelSubscription(subId); + + // assert that the subscription no longer exists + assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, address(0)); + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).balance, 0); + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).ethBalance, 0); + + // check the link balance of the sub owner, should be 5 LINK + assertEq(linkToken.balanceOf(subOwner), 5 ether, "link balance incorrect"); + // check the ether balance of the sub owner, should be 10 ether + assertEq(address(subOwner).balance, 10 ether, "eth balance incorrect"); + } + + function testRecoverFundsLINKNotSet() public { + // CASE: link token not set + // should revert with error LinkNotSet + + // call recoverFunds + vm.expectRevert(SubscriptionAPI.LinkNotSet.selector); + s_subscriptionAPI.recoverFunds(OWNER); + } + + function testRecoverFundsBalanceInvariantViolated() public { + // CASE: link token set + // and internal balance is greater than external balance + + // Create link token and set the link token on the subscription api object + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // set the total balance to be greater than the external balance + // so that we trigger the invariant violation + // note that this field is not modifiable in the actual contracts + // other than through onTokenTransfer or similar functions + s_subscriptionAPI.setTotalBalanceTestingOnlyXXX(100 ether); + + // call recoverFunds + vm.expectRevert(abi.encodeWithSelector(SubscriptionAPI.BalanceInvariantViolated.selector, 100 ether, 0)); + s_subscriptionAPI.recoverFunds(OWNER); + } + + function testRecoverFundsAmountToTransfer() public { + // CASE: link token set + // and internal balance is less than external balance + // (i.e invariant is not violated) + // should recover funds successfully + + // Create link token and set the link token on the subscription api object + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // transfer 10 LINK to the contract to recover + bool success = linkToken.transfer(address(s_subscriptionAPI), 10 ether); + assertTrue(success, "failed link transfer"); + + // call recoverFunds + vm.expectEmit(true, false, false, true); + emit FundsRecovered(OWNER, 10 ether); + s_subscriptionAPI.recoverFunds(OWNER); + } + + function testRecoverFundsNothingToTransfer() public { + // CASE: link token set + // and there is nothing to transfer + // should do nothing at all + + // Create link token and set the link token on the subscription api object + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // create a subscription and fund it with 5 LINK + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // fund the subscription with link + changePrank(OWNER); + vm.expectEmit(true, false, false, true); + emit SubscriptionFunded(subId, 0, 5 ether); + bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId)); + assertTrue(success, "failed link transfer and call"); + + // call recoverFunds, nothing should happen because external balance == internal balance + s_subscriptionAPI.recoverFunds(OWNER); + assertEq(linkToken.balanceOf(address(s_subscriptionAPI)), s_subscriptionAPI.s_totalBalance()); + } + + function testRecoverEthFundsBalanceInvariantViolated() public { + // set the total balance to be greater than the external balance + // so that we trigger the invariant violation + // note that this field is not modifiable in the actual contracts + // other than through onTokenTransfer or similar functions + s_subscriptionAPI.setTotalEthBalanceTestingOnlyXXX(100 ether); + + // call recoverFunds + vm.expectRevert(abi.encodeWithSelector(SubscriptionAPI.BalanceInvariantViolated.selector, 100 ether, 0)); + s_subscriptionAPI.recoverEthFunds(payable(OWNER)); + } + + function testRecoverEthFundsAmountToTransfer() public { + // transfer 10 LINK to the contract to recover + vm.deal(address(s_subscriptionAPI), 10 ether); + + // call recoverFunds + vm.expectEmit(true, false, false, true); + emit EthFundsRecovered(OWNER, 10 ether); + s_subscriptionAPI.recoverEthFunds(payable(OWNER)); + } + + function testRecoverEthFundsNothingToTransfer() public { + // create a subscription and fund it with 5 ether + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // fund the subscription with ether + vm.deal(subOwner, 5 ether); + changePrank(subOwner); + vm.expectEmit(true, false, false, true); + emit SubscriptionFundedWithEth(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + + // call recoverEthFunds, nothing should happen because external balance == internal balance + changePrank(OWNER); + s_subscriptionAPI.recoverEthFunds(payable(OWNER)); + assertEq(address(s_subscriptionAPI).balance, s_subscriptionAPI.s_totalEthBalance()); + } + + function testOracleWithdrawNoLink() public { + // CASE: no link token set + vm.expectRevert(SubscriptionAPI.LinkNotSet.selector); + s_subscriptionAPI.oracleWithdraw(OWNER, 1 ether); + } + + function testOracleWithdrawInsufficientBalance() public { + // CASE: link token set, trying to withdraw + // more than balance + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // call oracleWithdraw + vm.expectRevert(SubscriptionAPI.InsufficientBalance.selector); + s_subscriptionAPI.oracleWithdraw(OWNER, 1 ether); + } + + function testOracleWithdrawSufficientBalanceLinkSet() public { + // CASE: link token set, trying to withdraw + // less than balance + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // transfer 10 LINK to the contract to withdraw + bool success = linkToken.transfer(address(s_subscriptionAPI), 10 ether); + assertTrue(success, "failed link transfer"); + + // set the withdrawable tokens of the oracle to be 1 ether + address oracle = makeAddr("oracle"); + s_subscriptionAPI.setWithdrawableTokensTestingOnlyXXX(oracle, 1 ether); + assertEq(s_subscriptionAPI.getWithdrawableTokensTestingOnlyXXX(oracle), 1 ether); + + // set the total balance to be the same as the link balance for consistency + // (this is not necessary for the test, but just to be sane) + s_subscriptionAPI.setTotalBalanceTestingOnlyXXX(10 ether); + + // call oracleWithdraw from oracle address + changePrank(oracle); + s_subscriptionAPI.oracleWithdraw(oracle, 1 ether); + // assert link balance of oracle + assertEq(linkToken.balanceOf(oracle), 1 ether, "oracle link balance incorrect"); + // assert state of subscription api + assertEq(s_subscriptionAPI.getWithdrawableTokensTestingOnlyXXX(oracle), 0, "oracle withdrawable tokens incorrect"); + // assert that total balance is changed by the withdrawn amount + assertEq(s_subscriptionAPI.s_totalBalance(), 9 ether, "total balance incorrect"); + } + + function testOracleWithdrawEthInsufficientBalance() public { + // CASE: trying to withdraw more than balance + // should revert with InsufficientBalance + + // call oracleWithdrawEth + vm.expectRevert(SubscriptionAPI.InsufficientBalance.selector); + s_subscriptionAPI.oracleWithdrawEth(payable(OWNER), 1 ether); + } + + function testOracleWithdrawEthSufficientBalance() public { + // CASE: trying to withdraw less than balance + // should withdraw successfully + + // transfer 10 ether to the contract to withdraw + vm.deal(address(s_subscriptionAPI), 10 ether); + + // set the withdrawable eth of the oracle to be 1 ether + address oracle = makeAddr("oracle"); + s_subscriptionAPI.setWithdrawableEthTestingOnlyXXX(oracle, 1 ether); + assertEq(s_subscriptionAPI.getWithdrawableEthTestingOnlyXXX(oracle), 1 ether); + + // set the total balance to be the same as the eth balance for consistency + // (this is not necessary for the test, but just to be sane) + s_subscriptionAPI.setTotalEthBalanceTestingOnlyXXX(10 ether); + + // call oracleWithdrawEth from oracle address + changePrank(oracle); + s_subscriptionAPI.oracleWithdrawEth(payable(oracle), 1 ether); + // assert eth balance of oracle + assertEq(address(oracle).balance, 1 ether, "oracle eth balance incorrect"); + // assert state of subscription api + assertEq(s_subscriptionAPI.getWithdrawableEthTestingOnlyXXX(oracle), 0, "oracle withdrawable eth incorrect"); + // assert that total balance is changed by the withdrawn amount + assertEq(s_subscriptionAPI.s_totalEthBalance(), 9 ether, "total eth balance incorrect"); + } + + function testOnTokenTransferCallerNotLink() public { + vm.expectRevert(SubscriptionAPI.OnlyCallableFromLink.selector); + s_subscriptionAPI.onTokenTransfer(makeAddr("someaddress"), 1 ether, abi.encode(uint256(1))); + } + + function testOnTokenTransferInvalidCalldata() public { + // create and set link token on subscription api + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // call link.transferAndCall with invalid calldata + vm.expectRevert(SubscriptionAPI.InvalidCalldata.selector); + linkToken.transferAndCall(address(s_subscriptionAPI), 1 ether, abi.encode(uint256(1), address(1))); + } + + function testOnTokenTransferInvalidSubscriptionId() public { + // create and set link token on subscription api + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // generate bogus sub id + uint256 subId = uint256(keccak256("idontexist")); + + // try to fund bogus sub id + vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector); + linkToken.transferAndCall(address(s_subscriptionAPI), 1 ether, abi.encode(subId)); + } + + function testOnTokenTransferSuccess() public { + // happy path link funding test + // create and set link token on subscription api + MockLinkToken linkToken = new MockLinkToken(); + s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); + + // create a subscription and fund it with 5 LINK + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // fund the subscription with link + changePrank(OWNER); + vm.expectEmit(true, false, false, true); + emit SubscriptionFunded(subId, 0, 5 ether); + bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId)); + assertTrue(success, "failed link transfer and call"); + + // assert that the subscription is funded + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).balance, 5 ether); + } + + function testFundSubscriptionWithEthInvalidSubscriptionId() public { + // CASE: invalid subscription id + // should revert with InvalidSubscription + + uint256 subId = uint256(keccak256("idontexist")); + + // try to fund the subscription with ether, should fail + address funder = makeAddr("funder"); + vm.deal(funder, 5 ether); + changePrank(funder); + vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector); + s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + } + + function testFundSubscriptionWithEth() public { + // happy path test + // funding subscription with ether + + // create a subscription and fund it with ether + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + + // fund the subscription with ether + vm.deal(subOwner, 5 ether); + changePrank(subOwner); + vm.expectEmit(true, false, false, true); + emit SubscriptionFundedWithEth(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + + // assert that the subscription is funded + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).ethBalance, 5 ether); + } + + function testCreateSubscription() public { + // test that the subscription is created successfully + // and test the initial state of the subscription + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 1); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, subOwner); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 0); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).requestedOwner, address(0)); + } + + function testCreateSubscriptionRecreate() public { + // create two subscriptions from the same eoa + // they should never be the same due to nonce incrementation + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); + uint256 subId1 = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); + uint256 subId2 = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 2); + assertTrue(subId1 != subId2); + } + + function testSubscriptionOwnershipTransfer() public { + // create two eoa's, and create a subscription from one of them + // and transfer ownership to the other + // assert that the subscription is now owned by the other eoa + address oldOwner = makeAddr("oldOwner"); + address newOwner = makeAddr("newOwner"); + + // create sub + changePrank(oldOwner); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, oldOwner); + + // request ownership transfer + changePrank(oldOwner); + vm.expectEmit(true, false, false, true); + emit SubscriptionOwnerTransferRequested(subId, oldOwner, newOwner); + s_subscriptionAPI.requestSubscriptionOwnerTransfer(subId, newOwner); + + // accept ownership transfer from newOwner + changePrank(newOwner); + vm.expectEmit(true, false, false, true); + emit SubscriptionOwnerTransferred(subId, oldOwner, newOwner); + s_subscriptionAPI.acceptSubscriptionOwnerTransfer(subId); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).requestedOwner, address(0)); + } + + function testAddConsumerTooManyConsumers() public { + // add 100 consumers to a sub and then + // try adding one more and see the revert + address subOwner = makeAddr("subOwner"); + changePrank(subOwner); + uint256 subId = s_subscriptionAPI.createSubscription(); + for (uint256 i = 0; i < 100; i++) { + address consumer = makeAddr(Strings.toString(i)); + vm.expectEmit(true, false, false, true); + emit SubscriptionConsumerAdded(subId, consumer); + s_subscriptionAPI.addConsumer(subId, consumer); + } + + // try adding one more consumer, should revert + address consumer = makeAddr("consumer"); + changePrank(subOwner); + vm.expectRevert(SubscriptionAPI.TooManyConsumers.selector); + s_subscriptionAPI.addConsumer(subId, consumer); + } + + function testAddConsumerReaddSameConsumer() public { + // try adding the same consumer twice + // should be a no-op + // assert state is unchanged after the 2nd add + address subOwner = makeAddr("subOwner"); + address consumer = makeAddr("consumer"); + changePrank(subOwner); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 0); + changePrank(subOwner); + vm.expectEmit(true, false, false, true); + emit SubscriptionConsumerAdded(subId, consumer); + s_subscriptionAPI.addConsumer(subId, consumer); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 1); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers[0], consumer); + + // add consumer again, should be no-op + changePrank(subOwner); + s_subscriptionAPI.addConsumer(subId, consumer); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 1); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers[0], consumer); + } + + function testAddConsumer() public { + // create a subscription and add a consumer + // assert subscription state afterwards + address subOwner = makeAddr("subOwner"); + address consumer = makeAddr("consumer"); + changePrank(subOwner); + uint256 subId = s_subscriptionAPI.createSubscription(); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 0); + changePrank(subOwner); + vm.expectEmit(true, false, false, true); + emit SubscriptionConsumerAdded(subId, consumer); + s_subscriptionAPI.addConsumer(subId, consumer); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 1); + assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers[0], consumer); + } +} diff --git a/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go b/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go index 710e2ae2ab7..53dab6a4788 100644 --- a/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go +++ b/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go @@ -66,8 +66,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } var VRFCoordinatorV2PlusMetaData = &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\":\"FailedToSendEther\",\"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\":[{\"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\":\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"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\":\"EthFundsRecovered\",\"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\":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\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"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\":\"amountEth\",\"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\":\"oldEthBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newEthBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithEth\",\"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_ETH_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\":\"structVRFCoordinatorV2Plus.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithEth\",\"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\":\"ethBalance\",\"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\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdrawEth\",\"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\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverEthFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"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\"}],\"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\":[],\"name\":\"s_feeConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"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\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"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_totalEthBalance\",\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKETHFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620060fa380380620060fa833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615f1f620001db600039600081816105ee0152613a340152615f1f6000f3fe6080604052600436106102dc5760003560e01c80638da5cb5b1161017f578063bec4c08c116100e1578063dc311dd31161008a578063e95704bd11610064578063e95704bd1461095d578063ee9d2d3814610984578063f2fde38b146109b157600080fd5b8063dc311dd3146108f9578063e72f6e301461092a578063e8509bff1461094a57600080fd5b8063d98e620e116100bb578063d98e620e14610883578063da2f2610146108a3578063dac83d29146108d957600080fd5b8063bec4c08c14610823578063caf70c4a14610843578063cb6317971461086357600080fd5b8063a8cb447b11610143578063aefb212f1161011d578063aefb212f146107b6578063b08c8795146107e3578063b2a7cac51461080357600080fd5b8063a8cb447b14610756578063aa433aff14610776578063ad1783611461079657600080fd5b80638da5cb5b146106ab5780639b1c385e146106c95780639d40a6fd146106e9578063a21a23e414610721578063a4c0ed361461073657600080fd5b806340d6bb821161024357806366316d8d116101ec5780636f64f03f116101c65780636f64f03f1461065657806379ba50971461067657806386fe91c71461068b57600080fd5b806366316d8d146105bc578063689c4517146105dc5780636b6feccc1461061057600080fd5b806357133e641161021d57806357133e64146105675780635d06b4ab1461058757806364d51a2a146105a757600080fd5b806340d6bb82146104ec57806341af6c871461051757806346d8d4861461054757600080fd5b80630ae09540116102a5578063294daa491161027f578063294daa4914610478578063330987b314610494578063405b84fa146104cc57600080fd5b80630ae09540146103f857806315c48b84146104185780631b6b6d231461044057600080fd5b8062012291146102e157806304104edb1461030e578063043bd6ae14610330578063088070f51461035457806308821d58146103d8575b600080fd5b3480156102ed57600080fd5b506102f66109d1565b60405161030593929190615a83565b60405180910390f35b34801561031a57600080fd5b5061032e6103293660046153d0565b610a4d565b005b34801561033c57600080fd5b5061034660115481565b604051908152602001610305565b34801561036057600080fd5b50600d546103a09061ffff81169063ffffffff62010000820481169160ff600160301b820416916701000000000000008204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a001610305565b3480156103e457600080fd5b5061032e6103f3366004615510565b610c0f565b34801561040457600080fd5b5061032e6104133660046157b2565b610da3565b34801561042457600080fd5b5061042d60c881565b60405161ffff9091168152602001610305565b34801561044c57600080fd5b50600254610460906001600160a01b031681565b6040516001600160a01b039091168152602001610305565b34801561048457600080fd5b5060405160018152602001610305565b3480156104a057600080fd5b506104b46104af3660046155e2565b610e71565b6040516001600160601b039091168152602001610305565b3480156104d857600080fd5b5061032e6104e73660046157b2565b61135b565b3480156104f857600080fd5b506105026101f481565b60405163ffffffff9091168152602001610305565b34801561052357600080fd5b50610537610532366004615565565b611782565b6040519015158152602001610305565b34801561055357600080fd5b5061032e6105623660046153ed565b611983565b34801561057357600080fd5b5061032e610582366004615422565b611b00565b34801561059357600080fd5b5061032e6105a23660046153d0565b611b60565b3480156105b357600080fd5b5061042d606481565b3480156105c857600080fd5b5061032e6105d73660046153ed565b611c1e565b3480156105e857600080fd5b506104607f000000000000000000000000000000000000000000000000000000000000000081565b34801561061c57600080fd5b506012546106399063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610305565b34801561066257600080fd5b5061032e61067136600461545b565b611dbd565b34801561068257600080fd5b5061032e611ebc565b34801561069757600080fd5b50600a546104b4906001600160601b031681565b3480156106b757600080fd5b506000546001600160a01b0316610460565b3480156106d557600080fd5b506103466106e43660046156bf565b611f6d565b3480156106f557600080fd5b50600754610709906001600160401b031681565b6040516001600160401b039091168152602001610305565b34801561072d57600080fd5b50610346612362565b34801561074257600080fd5b5061032e610751366004615488565b6125b2565b34801561076257600080fd5b5061032e6107713660046153d0565b612752565b34801561078257600080fd5b5061032e610791366004615565565b61286d565b3480156107a257600080fd5b50600354610460906001600160a01b031681565b3480156107c257600080fd5b506107d66107d13660046157d7565b6128cd565b60405161030591906159e8565b3480156107ef57600080fd5b5061032e6107fe366004615714565b6129ce565b34801561080f57600080fd5b5061032e61081e366004615565565b612b62565b34801561082f57600080fd5b5061032e61083e3660046157b2565b612c98565b34801561084f57600080fd5b5061034661085e36600461552c565b612e34565b34801561086f57600080fd5b5061032e61087e3660046157b2565b612e64565b34801561088f57600080fd5b5061034661089e366004615565565b613167565b3480156108af57600080fd5b506104606108be366004615565565b600e602052600090815260409020546001600160a01b031681565b3480156108e557600080fd5b5061032e6108f43660046157b2565b613188565b34801561090557600080fd5b50610919610914366004615565565b6132a7565b604051610305959493929190615beb565b34801561093657600080fd5b5061032e6109453660046153d0565b6133a2565b61032e610958366004615565565b613561565b34801561096957600080fd5b50600a546104b490600160601b90046001600160601b031681565b34801561099057600080fd5b5061034661099f366004615565565b60106020526000908152604090205481565b3480156109bd57600080fd5b5061032e6109cc3660046153d0565b6136a0565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a3b57602002820191906000526020600020905b815481526020019060010190808311610a27575b50505050509050925092509250909192565b610a556136b1565b60135460005b81811015610be257826001600160a01b031660138281548110610a8057610a80615ec3565b6000918252602090912001546001600160a01b03161415610bd0576013610aa8600184615dbc565b81548110610ab857610ab8615ec3565b600091825260209091200154601380546001600160a01b039092169183908110610ae457610ae4615ec3565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826013610b1b600185615dbc565b81548110610b2b57610b2b615ec3565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506013805480610b6a57610b6a615ead565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bda81615e2b565b915050610a5b565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c176136b1565b604080518082018252600091610c46919084906002908390839080828437600092019190915250612e34915050565b6000818152600e60205260409020549091506001600160a01b031680610c8257604051631dfd6e1360e21b815260048101839052602401610c03565b6000828152600e6020526040812080546001600160a01b03191690555b600f54811015610d5a5782600f8281548110610cbd57610cbd615ec3565b90600052602060002001541415610d4857600f805460009190610ce290600190615dbc565b81548110610cf257610cf2615ec3565b9060005260206000200154905080600f8381548110610d1357610d13615ec3565b600091825260209091200155600f805480610d3057610d30615ead565b60019003818190600052602060002001600090559055505b80610d5281615e2b565b915050610c9f565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610d9691815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610ddb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e0f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615610e3a5760405163769dd35360e11b815260040160405180910390fd5b610e4384611782565b15610e6157604051631685ecdd60e31b815260040160405180910390fd5b610e6b848461370d565b50505050565b600d54600090600160301b900460ff1615610e9f5760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610eb085856138c9565b90506000846060015163ffffffff166001600160401b03811115610ed657610ed6615ed9565b604051908082528060200260200182016040528015610eff578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610f7f57826040015181604051602001610f37929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c828281518110610f6257610f62615ec3565b602090810291909101015280610f7781615e2b565b915050610f05565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610fb791908690602401615af6565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805466ff0000000000001916600160301b17905590880151608089015191925060009161101f9163ffffffff169084613b56565b600d805466ff00000000000019169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316611062816001615d3c565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a015180516110af90600190615dbc565b815181106110bf576110bf615ec3565b602091010151600d5460f89190911c60011491506000906110f0908a90600160581b900463ffffffff163a85613ba4565b905081156111f9576020808c01516000908152600690915260409020546001600160601b03808316600160601b90920416101561114057604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90611177908490600160601b90046001600160601b0316615dd3565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c9091528120805485945090926111d091859116615d67565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506112e5565b6020808c01516000908152600690915260409020546001600160601b038083169116101561123a57604051631e9acf1760e31b815260040160405180910390fd5b6020808c0151600090815260069091526040812080548392906112679084906001600160601b0316615dd3565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b9091528120805485945090926112c091859116615d67565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051611342939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff16156113865760405163769dd35360e11b815260040160405180910390fd5b61138f81613bf4565b6113b757604051635428d44960e01b81526001600160a01b0382166004820152602401610c03565b6000806000806113c6866132a7565b945094505093509350336001600160a01b0316826001600160a01b0316146114305760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c03565b61143986611782565b156114865760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c03565b60006040518060c0016040528061149b600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016114ef9190615a0e565b604051602081830303815290604052905061150988613c5e565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906115429085906004016159fb565b6000604051808303818588803b15801561155b57600080fd5b505af115801561156f573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611598905057506001600160601b03861615155b156116775760025460405163a9059cbb60e01b81526001600160a01b0389811660048301526001600160601b03891660248301529091169063a9059cbb90604401602060405180830381600087803b1580156115f357600080fd5b505af1158015611607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162b9190615548565b6116775760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c03565b600d805466ff0000000000001916600160301b17905560005b8351811015611725578381815181106116ab576116ab615ec3565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b50505050808061171d90615e2b565b915050611690565b50600d805466ff00000000000019169055604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561180c57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116117ee575b505050505081525050905060005b8160400151518110156119795760005b600f5481101561196657600061192f600f838154811061184c5761184c615ec3565b90600052602060002001548560400151858151811061186d5761186d615ec3565b602002602001015188600460008960400151898151811061189057611890615ec3565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e82528252829020548251808301889052959093168583015260608501939093526001600160401b039091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b50600081815260106020526040902054909150156119535750600195945050505050565b508061195e81615e2b565b91505061182a565b508061197181615e2b565b91505061181a565b5060009392505050565b600d54600160301b900460ff16156119ae5760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b03808316911610156119ea57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c602052604081208054839290611a129084906001600160601b0316615dd3565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316611a5a9190615dd3565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114611ad4576040519150601f19603f3d011682016040523d82523d6000602084013e611ad9565b606091505b5050905080611afb57604051630dcf35db60e41b815260040160405180910390fd5b505050565b611b086136b1565b6002546001600160a01b031615611b3257604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b611b686136b1565b611b7181613bf4565b15611b9a5760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610c03565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b600d54600160301b900460ff1615611c495760405163769dd35360e11b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b0380831691161015611c8557604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b602052604081208054839290611cad9084906001600160601b0316615dd3565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b0316611cf59190615dd3565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611d6457600080fd5b505af1158015611d78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9c9190615548565b611db957604051631e9acf1760e31b815260040160405180910390fd5b5050565b611dc56136b1565b604080518082018252600091611df4919084906002908390839080828437600092019190915250612e34915050565b6000818152600e60205260409020549091506001600160a01b031615611e3057604051634a0b8fa760e01b815260048101829052602401610c03565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610d96565b6001546001600160a01b03163314611f165760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c03565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600d54600090600160301b900460ff1615611f9b5760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611fd657604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680612027576040516379bfd40160e01b815260208401356004820152336024820152604401610c03565b600d5461ffff1661203e60608501604086016156f9565b61ffff161080612061575060c861205b60608501604086016156f9565b61ffff16115b156120a75761207660608401604085016156f9565b600d5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c03565b600d5462010000900463ffffffff166120c660808501606086016157f9565b63ffffffff161115612116576120e260808401606085016157f9565b600d54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610c03565b6101f461212960a08501608086016157f9565b63ffffffff16111561216f5761214560a08401608085016157f9565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610c03565b600061217c826001615d3c565b604080518635602080830182905233838501528089013560608401526001600160401b0385166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e08085018490528551808603909101815261010090940190945282519201919091209293509060009061220c9061220790890189615c40565b613ead565b9050600061221982613f2a565b905083612224613f9b565b60208a013561223960808c0160608d016157f9565b61224960a08d0160808e016157f9565b33866040516020016122619796959493929190615b4e565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d60400160208101906122d891906156f9565b8e60600160208101906122eb91906157f9565b8f60800160208101906122fe91906157f9565b8960405161231196959493929190615b0f565b60405180910390a450503360009081526004602090815260408083208983013584529091529020805467ffffffffffffffff19166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff16156123905760405163769dd35360e11b815260040160405180910390fd5b60003361239e600143615dbc565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b0390911690600061241d83615e46565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b0381111561245c5761245c615ed9565b604051908082528060200260200182016040528015612485578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b03928316178355925160018301805490941691161790915592518051949550909361256692600285019201906150e6565b5061257691506008905083614034565b5060405133815282907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a250905090565b600d54600160301b900460ff16156125dd5760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03163314612608576040516344b0e3c360e01b815260040160405180910390fd5b6020811461262957604051638129bbcd60e01b815260040160405180910390fd5b600061263782840184615565565b6000818152600560205260409020549091506001600160a01b031661266f57604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906126968385615d67565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166126de9190615d67565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846127319190615d24565b604080519283526020830191909152015b60405180910390a2505050505050565b61275a6136b1565b600a544790600160601b90046001600160601b03168181111561279a576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611afb5760006127ae8284615dbc565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d80600081146127fd576040519150601f19603f3d011682016040523d82523d6000602084013e612802565b606091505b505090508061282457604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317910160405180910390a15050505050565b6128756136b1565b6000818152600560205260409020546001600160a01b03166128aa57604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c0c9082906001600160a01b031661370d565b606060006128db6008614040565b90508084106128fd57604051631390f2a160e01b815260040160405180910390fd5b60006129098486615d24565b905081811180612917575083155b6129215780612923565b815b905060006129318683615dbc565b6001600160401b0381111561294857612948615ed9565b604051908082528060200260200182016040528015612971578160200160208202803683370190505b50905060005b81518110156129c45761299561298d8883615d24565b60089061404a565b8282815181106129a7576129a7615ec3565b6020908102919091010152806129bc81615e2b565b915050612977565b5095945050505050565b6129d66136b1565b60c861ffff87161115612a105760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c03565b60008213612a34576040516321ea67b360e11b815260048101839052602401610c03565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff19168817620100008702176effffffffffffffffff000000000000191667010000000000000085026effffffff0000000000000000000000191617600160581b83021790558a51601280548d87015192891667ffffffffffffffff199091161764010000000092891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff1615612b8d5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316612bc257604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612c1b576000818152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610c03565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691015b60405180910390a25050565b60008281526005602052604090205482906001600160a01b031680612cd057604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612d0457604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612d2f5760405163769dd35360e11b815260040160405180910390fd5b60008481526005602052604090206002015460641415612d62576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b031615612d9957610e6b565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a250505050565b600081604051602001612e4791906159da565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612e9c57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612ed057604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612efb5760405163769dd35360e11b815260040160405180910390fd5b612f0484611782565b15612f2257604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316612f7e576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c03565b600084815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612fe157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612fc3575b50505050509050600060018251612ff89190615dbc565b905060005b825181101561310457856001600160a01b031683828151811061302257613022615ec3565b60200260200101516001600160a01b031614156130f257600083838151811061304d5761304d615ec3565b6020026020010151905080600560008a8152602001908152602001600020600201838154811061307f5761307f615ec3565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558981526005909152604090206002018054806130ca576130ca615ead565b600082815260209020810160001990810180546001600160a01b031916905501905550613104565b806130fc81615e2b565b915050612ffd565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79101612742565b600f818154811061317757600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b0316806131c057604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146131f457604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff161561321f5760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b03848116911614610e6b5760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612e26565b6000818152600560205260408120548190819081906060906001600160a01b03166132e557604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b039094169391839183018282801561338857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161336a575b505050505090509450945094509450945091939590929450565b6133aa6136b1565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156133ee57600080fd5b505afa158015613402573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613426919061557e565b600a549091506001600160601b031681811115613460576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611afb5760006134748284615dbc565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b1580156134c457600080fd5b505af11580156134d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134fc9190615548565b61351957604051631f01ff1360e21b815260040160405180910390fd5b604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b600d54600160301b900460ff161561358c5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b03166135c157604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c6135f08385615d67565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b03166136389190615d67565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde82348461368b9190615d24565b60408051928352602083019190915201612c8c565b6136a86136b1565b610c0c81614056565b6000546001600160a01b0316331461370b5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c03565b565b60008061371984613c5e565b60025491935091506001600160a01b03161580159061374057506001600160601b03821615155b156137f05760025460405163a9059cbb60e01b81526001600160a01b0385811660048301526001600160601b03851660248301529091169063a9059cbb90604401602060405180830381600087803b15801561379b57600080fd5b505af11580156137af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137d39190615548565b6137f057604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613846576040519150601f19603f3d011682016040523d82523d6000602084013e61384b565b606091505b505090508061386d57604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006138f58460000151612e34565b6000818152600e60205260409020549091506001600160a01b03168061393157604051631dfd6e1360e21b815260048101839052602401610c03565b6000828660800151604051602001613953929190918252602082015260400190565b60408051601f198184030181529181528151602092830120600081815260109093529120549091508061399957604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d015193516139c8978a979096959101615b98565b6040516020818303038152906040528051906020012081146139fd5760405163354a450b60e21b815260040160405180910390fd5b6000613a0c8760000151614100565b905080613ae4578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b158015613a7e57600080fd5b505afa158015613a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab6919061557e565b905080613ae457865160405163175dadad60e01b81526001600160401b039091166004820152602401610c03565b6000886080015182604051602001613b06929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506000613b2d8a836141ea565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a611388811015613b6857600080fd5b611388810390508460408204820311613b8057600080fd5b50823b613b8c57600080fd5b60008083516020850160008789f190505b9392505050565b60008115613bd257601254613bcb9086908690640100000000900463ffffffff1686614255565b9050613bec565b601254613be9908690869063ffffffff16866142bf565b90505b949350505050565b6000805b601354811015613c5557826001600160a01b031660138281548110613c1f57613c1f615ec3565b6000918252602090912001546001600160a01b03161415613c435750600192915050565b80613c4d81615e2b565b915050613bf8565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613cea57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613ccc575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613dc7576004600084604001518381518110613d7657613d76615ec3565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff1916905580613dbf81615e2b565b915050613d4f565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613dff600283018261514b565b5050600085815260066020526040812055613e1b6008866143ad565b50600a8054859190600090613e3a9084906001600160601b0316615dd3565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613e829190615dd3565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081019091526000815281613ed65750604080516020810190915260008152611355565b63125fa26760e31b613ee88385615dfb565b6001600160e01b03191614613f1057604051632923fee760e11b815260040160405180910390fd5b613f1d8260048186615cfa565b810190613b9d9190615597565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613f6391511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480613fb0575062066eed81145b1561402d5760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613fef57600080fd5b505afa158015614003573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614027919061557e565b91505090565b4391505090565b6000613b9d83836143b9565b6000611355825490565b6000613b9d8383614408565b6001600160a01b0381163314156140af5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c03565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480614115575062066eed81145b156141db57610100836001600160401b031661412f613f9b565b6141399190615dbc565b11806141555750614148613f9b565b836001600160401b031610155b156141635750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a829060240160206040518083038186803b1580156141a357600080fd5b505afa1580156141b7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9d919061557e565b50506001600160401b03164090565b600061421e8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614432565b60038360200151604051602001614236929190615ae2565b60408051601f1981840301815291905280516020909101209392505050565b60008061426061465d565b905060005a61426f8888615d24565b6142799190615dbc565b6142839085615d9d565b9050600061429c63ffffffff871664e8d4a51000615d9d565b9050826142a98284615d24565b6142b39190615d24565b98975050505050505050565b6000806142ca6146b9565b9050600081136142f0576040516321ea67b360e11b815260048101829052602401610c03565b60006142fa61465d565b9050600082825a61430b8b8b615d24565b6143159190615dbc565b61431f9088615d9d565b6143299190615d24565b61433b90670de0b6b3a7640000615d9d565b6143459190615d89565b9050600061435e63ffffffff881664e8d4a51000615d9d565b9050614376816b033b2e3c9fd0803ce8000000615dbc565b8211156143965760405163e80fa38160e01b815260040160405180910390fd5b6143a08183615d24565b9998505050505050505050565b6000613b9d8383614788565b600081815260018301602052604081205461440057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611355565b506000611355565b600082600001828154811061441f5761441f615ec3565b9060005260206000200154905092915050565b61443b8961487b565b6144875760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c03565b6144908861487b565b6144dc5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c03565b6144e58361487b565b6145315760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c03565b61453a8261487b565b6145865760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c03565b614592878a8887614954565b6145de5760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c03565b60006145ea8a87614a77565b905060006145fd898b878b868989614adb565b9050600061460e838d8d8a86614bfb565b9050808a1461464f5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610c03565b505050505050505050505050565b60004661a4b1811480614672575062066eed81145b156146b157606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613fef57600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093670100000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561471b57600080fd5b505afa15801561472f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147539190615814565b509450909250849150508015614777575061476e8242615dbc565b8463ffffffff16105b15613bec5750601154949350505050565b600081815260018301602052604081205480156148715760006147ac600183615dbc565b85549091506000906147c090600190615dbc565b90508181146148255760008660000182815481106147e0576147e0615ec3565b906000526020600020015490508087600001848154811061480357614803615ec3565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061483657614836615ead565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611355565b6000915050611355565b80516000906401000003d019116148d45760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0191161492d5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d01990800961494d8360005b6020020151614c3b565b1492915050565b60006001600160a01b03821661499a5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610c03565b6020840151600090600116156149b157601c6149b4565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614a4f573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614a7f615169565b614aac60018484604051602001614a98939291906159b9565b604051602081830303815290604052614c5f565b90505b614ab88161487b565b611355578051604080516020810192909252614ad49101614a98565b9050614aaf565b614ae3615169565b825186516401000003d0199081900691061415614b425760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c03565b614b4d878988614cad565b614b995760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c03565b614ba4848685614cad565b614bf05760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c03565b6142b3868484614dd5565b600060028686868587604051602001614c199695949392919061595a565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614c67615169565b614c7082614e9c565b8152614c85614c80826000614943565b614ed7565b60208201819052600290066001141561235d576020810180516401000003d019039052919050565b600082614cea5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610c03565b83516020850151600090614d0090600290615e6d565b15614d0c57601c614d0f565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614d81573d6000803e3d6000fd5b505050602060405103519050600086604051602001614da09190615948565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614ddd615169565b835160208086015185519186015160009384938493614dfe93909190614ef7565b919450925090506401000003d019858209600114614e5e5760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c03565b60405180604001604052806401000003d01980614e7d57614e7d615e97565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d019811061235d57604080516020808201939093528151808203840181529082019091528051910120614ea4565b6000611355826002614ef06401000003d0196001615d24565b901c614fd7565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614f3783838585615079565b9098509050614f4888828e8861509d565b9098509050614f5988828c8761509d565b90985090506000614f6c8d878b8561509d565b9098509050614f7d88828686615079565b9098509050614f8e88828e8961509d565b9098509050818114614fc3576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614fc7565b8196505b5050505050509450945094915050565b600080614fe2615187565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a08201526150146151a5565b60208160c0846005600019fa92508261506f5760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c03565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b82805482825590600052602060002090810192821561513b579160200282015b8281111561513b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615106565b506151479291506151c3565b5090565b5080546000825590600052602060002090810190610c0c91906151c3565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b8082111561514757600081556001016151c4565b803561235d81615eef565b806040810183101561135557600080fd5b600082601f83011261520557600080fd5b61520d615c8d565b80838560408601111561521f57600080fd5b60005b6002811015615241578135845260209384019390910190600101615222565b509095945050505050565b600082601f83011261525d57600080fd5b81356001600160401b038082111561527757615277615ed9565b604051601f8301601f19908116603f0116810190828211818310171561529f5761529f615ed9565b816040528381528660208588010111156152b857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060c082840312156152ea57600080fd5b6152f2615cb5565b905081356001600160401b03808216821461530c57600080fd5b818352602084013560208401526153256040850161538b565b60408401526153366060850161538b565b6060840152615347608085016151d8565b608084015260a084013591508082111561536057600080fd5b5061536d8482850161524c565b60a08301525092915050565b803561ffff8116811461235d57600080fd5b803563ffffffff8116811461235d57600080fd5b805169ffffffffffffffffffff8116811461235d57600080fd5b80356001600160601b038116811461235d57600080fd5b6000602082840312156153e257600080fd5b8135613b9d81615eef565b6000806040838503121561540057600080fd5b823561540b81615eef565b9150615419602084016153b9565b90509250929050565b6000806040838503121561543557600080fd5b823561544081615eef565b9150602083013561545081615eef565b809150509250929050565b6000806060838503121561546e57600080fd5b823561547981615eef565b915061541984602085016151e3565b6000806000806060858703121561549e57600080fd5b84356154a981615eef565b93506020850135925060408501356001600160401b03808211156154cc57600080fd5b818701915087601f8301126154e057600080fd5b8135818111156154ef57600080fd5b88602082850101111561550157600080fd5b95989497505060200194505050565b60006040828403121561552257600080fd5b613b9d83836151e3565b60006040828403121561553e57600080fd5b613b9d83836151f4565b60006020828403121561555a57600080fd5b8151613b9d81615f04565b60006020828403121561557757600080fd5b5035919050565b60006020828403121561559057600080fd5b5051919050565b6000602082840312156155a957600080fd5b604051602081018181106001600160401b03821117156155cb576155cb615ed9565b60405282356155d981615f04565b81529392505050565b6000808284036101c08112156155f757600080fd5b6101a08082121561560757600080fd5b61560f615cd7565b915061561b86866151f4565b825261562a86604087016151f4565b60208301526080850135604083015260a0850135606083015260c0850135608083015261565960e086016151d8565b60a083015261010061566d878288016151f4565b60c08401526156808761014088016151f4565b60e0840152610180860135908301529092508301356001600160401b038111156156a957600080fd5b6156b5858286016152d8565b9150509250929050565b6000602082840312156156d157600080fd5b81356001600160401b038111156156e757600080fd5b820160c08185031215613b9d57600080fd5b60006020828403121561570b57600080fd5b613b9d82615379565b60008060008060008086880360e081121561572e57600080fd5b61573788615379565b96506157456020890161538b565b95506157536040890161538b565b94506157616060890161538b565b9350608088013592506040609f198201121561577c57600080fd5b50615785615c8d565b61579160a0890161538b565b815261579f60c0890161538b565b6020820152809150509295509295509295565b600080604083850312156157c557600080fd5b82359150602083013561545081615eef565b600080604083850312156157ea57600080fd5b50508035926020909101359150565b60006020828403121561580b57600080fd5b613b9d8261538b565b600080600080600060a0868803121561582c57600080fd5b6158358661539f565b94506020860151935060408601519250606086015191506158586080870161539f565b90509295509295909350565b600081518084526020808501945080840160005b8381101561589d5781516001600160a01b031687529582019590820190600101615878565b509495945050505050565b8060005b6002811015610e6b5781518452602093840193909101906001016158ac565b600081518084526020808501945080840160005b8381101561589d578151875295820195908201906001016158df565b6000815180845260005b8181101561592157602081850181015186830182015201615905565b81811115615933576000602083870101525b50601f01601f19169290920160200192915050565b61595281836158a8565b604001919050565b86815261596a60208201876158a8565b61597760608201866158a8565b61598460a08201856158a8565b61599160e08201846158a8565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b8381526159c960208201846158a8565b606081019190915260800192915050565b6040810161135582846158a8565b602081526000613b9d60208301846158cb565b602081526000613b9d60208301846158fb565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c06080840152615a5460e0840182615864565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615ad457845183529383019391830191600101615ab8565b509098975050505050505050565b82815260608101613b9d60208301846158a8565b828152604060208201526000613bec60408301846158cb565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526142b360c08301846158fb565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143a060e08301846158fb565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143a060e08301846158fb565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a06080830152615c3560a0830184615864565b979650505050505050565b6000808335601e19843603018112615c5757600080fd5b8301803591506001600160401b03821115615c7157600080fd5b602001915036819003821315615c8657600080fd5b9250929050565b604080519081016001600160401b0381118282101715615caf57615caf615ed9565b60405290565b60405160c081016001600160401b0381118282101715615caf57615caf615ed9565b60405161012081016001600160401b0381118282101715615caf57615caf615ed9565b60008085851115615d0a57600080fd5b83861115615d1757600080fd5b5050820193919092039150565b60008219821115615d3757615d37615e81565b500190565b60006001600160401b03808316818516808303821115615d5e57615d5e615e81565b01949350505050565b60006001600160601b03808316818516808303821115615d5e57615d5e615e81565b600082615d9857615d98615e97565b500490565b6000816000190483118215151615615db757615db7615e81565b500290565b600082821015615dce57615dce615e81565b500390565b60006001600160601b0383811690831681811015615df357615df3615e81565b039392505050565b6001600160e01b03198135818116916004851015615e235780818660040360031b1b83161692505b505092915050565b6000600019821415615e3f57615e3f615e81565b5060010190565b60006001600160401b0380831681811415615e6357615e63615e81565b6001019392505050565b600082615e7c57615e7c615e97565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c0c57600080fd5b8015158114610c0c57600080fdfea164736f6c6343000806000a", + 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\":\"FailedToSendEther\",\"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\":[{\"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\":[],\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"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\":\"EthFundsRecovered\",\"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\":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\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"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\":\"amountEth\",\"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\":\"oldEthBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newEthBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithEth\",\"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_ETH_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\":\"structVRFCoordinatorV2Plus.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithEth\",\"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\":\"ethBalance\",\"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\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdrawEth\",\"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\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverEthFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"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\"}],\"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\":[],\"name\":\"s_feeConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"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\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"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_totalEthBalance\",\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKETHFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200614c3803806200614c833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615f71620001db600039600081816105ee0152613a860152615f716000f3fe6080604052600436106102dc5760003560e01c80638da5cb5b1161017f578063bec4c08c116100e1578063dc311dd31161008a578063e95704bd11610064578063e95704bd1461095d578063ee9d2d3814610984578063f2fde38b146109b157600080fd5b8063dc311dd3146108f9578063e72f6e301461092a578063e8509bff1461094a57600080fd5b8063d98e620e116100bb578063d98e620e14610883578063da2f2610146108a3578063dac83d29146108d957600080fd5b8063bec4c08c14610823578063caf70c4a14610843578063cb6317971461086357600080fd5b8063a8cb447b11610143578063aefb212f1161011d578063aefb212f146107b6578063b08c8795146107e3578063b2a7cac51461080357600080fd5b8063a8cb447b14610756578063aa433aff14610776578063ad1783611461079657600080fd5b80638da5cb5b146106ab5780639b1c385e146106c95780639d40a6fd146106e9578063a21a23e414610721578063a4c0ed361461073657600080fd5b806340d6bb821161024357806366316d8d116101ec5780636f64f03f116101c65780636f64f03f1461065657806379ba50971461067657806386fe91c71461068b57600080fd5b806366316d8d146105bc578063689c4517146105dc5780636b6feccc1461061057600080fd5b806357133e641161021d57806357133e64146105675780635d06b4ab1461058757806364d51a2a146105a757600080fd5b806340d6bb82146104ec57806341af6c871461051757806346d8d4861461054757600080fd5b80630ae09540116102a5578063294daa491161027f578063294daa4914610478578063330987b314610494578063405b84fa146104cc57600080fd5b80630ae09540146103f857806315c48b84146104185780631b6b6d231461044057600080fd5b8062012291146102e157806304104edb1461030e578063043bd6ae14610330578063088070f51461035457806308821d58146103d8575b600080fd5b3480156102ed57600080fd5b506102f66109d1565b60405161030593929190615ad5565b60405180910390f35b34801561031a57600080fd5b5061032e610329366004615422565b610a4d565b005b34801561033c57600080fd5b5061034660115481565b604051908152602001610305565b34801561036057600080fd5b50600d546103a09061ffff81169063ffffffff62010000820481169160ff600160301b820416916701000000000000008204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a001610305565b3480156103e457600080fd5b5061032e6103f3366004615562565b610c0f565b34801561040457600080fd5b5061032e610413366004615804565b610da3565b34801561042457600080fd5b5061042d60c881565b60405161ffff9091168152602001610305565b34801561044c57600080fd5b50600254610460906001600160a01b031681565b6040516001600160a01b039091168152602001610305565b34801561048457600080fd5b5060405160018152602001610305565b3480156104a057600080fd5b506104b46104af366004615634565b610e71565b6040516001600160601b039091168152602001610305565b3480156104d857600080fd5b5061032e6104e7366004615804565b61135b565b3480156104f857600080fd5b506105026101f481565b60405163ffffffff9091168152602001610305565b34801561052357600080fd5b506105376105323660046155b7565b611782565b6040519015158152602001610305565b34801561055357600080fd5b5061032e61056236600461543f565b611983565b34801561057357600080fd5b5061032e610582366004615474565b611b00565b34801561059357600080fd5b5061032e6105a2366004615422565b611b60565b3480156105b357600080fd5b5061042d606481565b3480156105c857600080fd5b5061032e6105d736600461543f565b611c1e565b3480156105e857600080fd5b506104607f000000000000000000000000000000000000000000000000000000000000000081565b34801561061c57600080fd5b506012546106399063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610305565b34801561066257600080fd5b5061032e6106713660046154ad565b611de6565b34801561068257600080fd5b5061032e611ee5565b34801561069757600080fd5b50600a546104b4906001600160601b031681565b3480156106b757600080fd5b506000546001600160a01b0316610460565b3480156106d557600080fd5b506103466106e4366004615711565b611f96565b3480156106f557600080fd5b50600754610709906001600160401b031681565b6040516001600160401b039091168152602001610305565b34801561072d57600080fd5b5061034661238b565b34801561074257600080fd5b5061032e6107513660046154da565b6125db565b34801561076257600080fd5b5061032e610771366004615422565b61277b565b34801561078257600080fd5b5061032e6107913660046155b7565b612896565b3480156107a257600080fd5b50600354610460906001600160a01b031681565b3480156107c257600080fd5b506107d66107d1366004615829565b6128f6565b6040516103059190615a3a565b3480156107ef57600080fd5b5061032e6107fe366004615766565b6129f7565b34801561080f57600080fd5b5061032e61081e3660046155b7565b612b8b565b34801561082f57600080fd5b5061032e61083e366004615804565b612cc1565b34801561084f57600080fd5b5061034661085e36600461557e565b612e5d565b34801561086f57600080fd5b5061032e61087e366004615804565b612e8d565b34801561088f57600080fd5b5061034661089e3660046155b7565b613190565b3480156108af57600080fd5b506104606108be3660046155b7565b600e602052600090815260409020546001600160a01b031681565b3480156108e557600080fd5b5061032e6108f4366004615804565b6131b1565b34801561090557600080fd5b506109196109143660046155b7565b6132d0565b604051610305959493929190615c3d565b34801561093657600080fd5b5061032e610945366004615422565b6133cb565b61032e6109583660046155b7565b6135b3565b34801561096957600080fd5b50600a546104b490600160601b90046001600160601b031681565b34801561099057600080fd5b5061034661099f3660046155b7565b60106020526000908152604090205481565b3480156109bd57600080fd5b5061032e6109cc366004615422565b6136f2565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a3b57602002820191906000526020600020905b815481526020019060010190808311610a27575b50505050509050925092509250909192565b610a55613703565b60135460005b81811015610be257826001600160a01b031660138281548110610a8057610a80615f15565b6000918252602090912001546001600160a01b03161415610bd0576013610aa8600184615e0e565b81548110610ab857610ab8615f15565b600091825260209091200154601380546001600160a01b039092169183908110610ae457610ae4615f15565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826013610b1b600185615e0e565b81548110610b2b57610b2b615f15565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506013805480610b6a57610b6a615eff565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bda81615e7d565b915050610a5b565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c17613703565b604080518082018252600091610c46919084906002908390839080828437600092019190915250612e5d915050565b6000818152600e60205260409020549091506001600160a01b031680610c8257604051631dfd6e1360e21b815260048101839052602401610c03565b6000828152600e6020526040812080546001600160a01b03191690555b600f54811015610d5a5782600f8281548110610cbd57610cbd615f15565b90600052602060002001541415610d4857600f805460009190610ce290600190615e0e565b81548110610cf257610cf2615f15565b9060005260206000200154905080600f8381548110610d1357610d13615f15565b600091825260209091200155600f805480610d3057610d30615eff565b60019003818190600052602060002001600090559055505b80610d5281615e7d565b915050610c9f565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610d9691815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610ddb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e0f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615610e3a5760405163769dd35360e11b815260040160405180910390fd5b610e4384611782565b15610e6157604051631685ecdd60e31b815260040160405180910390fd5b610e6b848461375f565b50505050565b600d54600090600160301b900460ff1615610e9f5760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610eb0858561391b565b90506000846060015163ffffffff166001600160401b03811115610ed657610ed6615f2b565b604051908082528060200260200182016040528015610eff578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610f7f57826040015181604051602001610f37929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c828281518110610f6257610f62615f15565b602090810291909101015280610f7781615e7d565b915050610f05565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610fb791908690602401615b48565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805466ff0000000000001916600160301b17905590880151608089015191925060009161101f9163ffffffff169084613ba8565b600d805466ff00000000000019169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316611062816001615d8e565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a015180516110af90600190615e0e565b815181106110bf576110bf615f15565b602091010151600d5460f89190911c60011491506000906110f0908a90600160581b900463ffffffff163a85613bf6565b905081156111f9576020808c01516000908152600690915260409020546001600160601b03808316600160601b90920416101561114057604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90611177908490600160601b90046001600160601b0316615e25565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c9091528120805485945090926111d091859116615db9565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506112e5565b6020808c01516000908152600690915260409020546001600160601b038083169116101561123a57604051631e9acf1760e31b815260040160405180910390fd5b6020808c0151600090815260069091526040812080548392906112679084906001600160601b0316615e25565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b9091528120805485945090926112c091859116615db9565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051611342939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff16156113865760405163769dd35360e11b815260040160405180910390fd5b61138f81613c46565b6113b757604051635428d44960e01b81526001600160a01b0382166004820152602401610c03565b6000806000806113c6866132d0565b945094505093509350336001600160a01b0316826001600160a01b0316146114305760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c03565b61143986611782565b156114865760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c03565b60006040518060c0016040528061149b600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016114ef9190615a60565b604051602081830303815290604052905061150988613cb0565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b03881690611542908590600401615a4d565b6000604051808303818588803b15801561155b57600080fd5b505af115801561156f573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611598905057506001600160601b03861615155b156116775760025460405163a9059cbb60e01b81526001600160a01b0389811660048301526001600160601b03891660248301529091169063a9059cbb90604401602060405180830381600087803b1580156115f357600080fd5b505af1158015611607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162b919061559a565b6116775760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c03565b600d805466ff0000000000001916600160301b17905560005b8351811015611725578381815181106116ab576116ab615f15565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b50505050808061171d90615e7d565b915050611690565b50600d805466ff00000000000019169055604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561180c57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116117ee575b505050505081525050905060005b8160400151518110156119795760005b600f5481101561196657600061192f600f838154811061184c5761184c615f15565b90600052602060002001548560400151858151811061186d5761186d615f15565b602002602001015188600460008960400151898151811061189057611890615f15565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e82528252829020548251808301889052959093168583015260608501939093526001600160401b039091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b50600081815260106020526040902054909150156119535750600195945050505050565b508061195e81615e7d565b91505061182a565b508061197181615e7d565b91505061181a565b5060009392505050565b600d54600160301b900460ff16156119ae5760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b03808316911610156119ea57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c602052604081208054839290611a129084906001600160601b0316615e25565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316611a5a9190615e25565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114611ad4576040519150601f19603f3d011682016040523d82523d6000602084013e611ad9565b606091505b5050905080611afb57604051630dcf35db60e41b815260040160405180910390fd5b505050565b611b08613703565b6002546001600160a01b031615611b3257604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b611b68613703565b611b7181613c46565b15611b9a5760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610c03565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b600d54600160301b900460ff1615611c495760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b0316611c725760405163c1f0c0a160e01b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b0380831691161015611cae57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b602052604081208054839290611cd69084906001600160601b0316615e25565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b0316611d1e9190615e25565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611d8d57600080fd5b505af1158015611da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc5919061559a565b611de257604051631e9acf1760e31b815260040160405180910390fd5b5050565b611dee613703565b604080518082018252600091611e1d919084906002908390839080828437600092019190915250612e5d915050565b6000818152600e60205260409020549091506001600160a01b031615611e5957604051634a0b8fa760e01b815260048101829052602401610c03565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610d96565b6001546001600160a01b03163314611f3f5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c03565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600d54600090600160301b900460ff1615611fc45760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611fff57604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680612050576040516379bfd40160e01b815260208401356004820152336024820152604401610c03565b600d5461ffff16612067606085016040860161574b565b61ffff16108061208a575060c8612084606085016040860161574b565b61ffff16115b156120d05761209f606084016040850161574b565b600d5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c03565b600d5462010000900463ffffffff166120ef608085016060860161584b565b63ffffffff16111561213f5761210b608084016060850161584b565b600d54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610c03565b6101f461215260a085016080860161584b565b63ffffffff1611156121985761216e60a084016080850161584b565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610c03565b60006121a5826001615d8e565b604080518635602080830182905233838501528089013560608401526001600160401b0385166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e0808501849052855180860390910181526101009094019094528251920191909120929350906000906122359061223090890189615c92565b613eff565b9050600061224282613f7c565b90508361224d613fed565b60208a013561226260808c0160608d0161584b565b61227260a08d0160808e0161584b565b338660405160200161228a9796959493929190615ba0565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190612301919061574b565b8e6060016020810190612314919061584b565b8f6080016020810190612327919061584b565b8960405161233a96959493929190615b61565b60405180910390a450503360009081526004602090815260408083208983013584529091529020805467ffffffffffffffff19166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff16156123b95760405163769dd35360e11b815260040160405180910390fd5b6000336123c7600143615e0e565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b0390911690600061244683615e98565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b0381111561248557612485615f2b565b6040519080825280602002602001820160405280156124ae578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b03928316178355925160018301805490941691161790915592518051949550909361258f9260028501920190615138565b5061259f91506008905083614086565b5060405133815282907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a250905090565b600d54600160301b900460ff16156126065760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03163314612631576040516344b0e3c360e01b815260040160405180910390fd5b6020811461265257604051638129bbcd60e01b815260040160405180910390fd5b6000612660828401846155b7565b6000818152600560205260409020549091506001600160a01b031661269857604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906126bf8385615db9565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166127079190615db9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a82878461275a9190615d76565b604080519283526020830191909152015b60405180910390a2505050505050565b612783613703565b600a544790600160601b90046001600160601b0316818111156127c3576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611afb5760006127d78284615e0e565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114612826576040519150601f19603f3d011682016040523d82523d6000602084013e61282b565b606091505b505090508061284d57604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317910160405180910390a15050505050565b61289e613703565b6000818152600560205260409020546001600160a01b03166128d357604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c0c9082906001600160a01b031661375f565b606060006129046008614092565b905080841061292657604051631390f2a160e01b815260040160405180910390fd5b60006129328486615d76565b905081811180612940575083155b61294a578061294c565b815b9050600061295a8683615e0e565b6001600160401b0381111561297157612971615f2b565b60405190808252806020026020018201604052801561299a578160200160208202803683370190505b50905060005b81518110156129ed576129be6129b68883615d76565b60089061409c565b8282815181106129d0576129d0615f15565b6020908102919091010152806129e581615e7d565b9150506129a0565b5095945050505050565b6129ff613703565b60c861ffff87161115612a395760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c03565b60008213612a5d576040516321ea67b360e11b815260048101839052602401610c03565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff19168817620100008702176effffffffffffffffff000000000000191667010000000000000085026effffffff0000000000000000000000191617600160581b83021790558a51601280548d87015192891667ffffffffffffffff199091161764010000000092891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff1615612bb65760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316612beb57604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612c44576000818152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610c03565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691015b60405180910390a25050565b60008281526005602052604090205482906001600160a01b031680612cf957604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612d2d57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612d585760405163769dd35360e11b815260040160405180910390fd5b60008481526005602052604090206002015460641415612d8b576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b031615612dc257610e6b565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a250505050565b600081604051602001612e709190615a2c565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612ec557604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612ef957604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612f245760405163769dd35360e11b815260040160405180910390fd5b612f2d84611782565b15612f4b57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316612fa7576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c03565b60008481526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561300a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612fec575b505050505090506000600182516130219190615e0e565b905060005b825181101561312d57856001600160a01b031683828151811061304b5761304b615f15565b60200260200101516001600160a01b0316141561311b57600083838151811061307657613076615f15565b6020026020010151905080600560008a815260200190815260200160002060020183815481106130a8576130a8615f15565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558981526005909152604090206002018054806130f3576130f3615eff565b600082815260209020810160001990810180546001600160a01b03191690550190555061312d565b8061312581615e7d565b915050613026565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7910161276b565b600f81815481106131a057600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b0316806131e957604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461321d57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156132485760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b03848116911614610e6b5760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612e4f565b6000818152600560205260408120548190819081906060906001600160a01b031661330e57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b03909416939183918301828280156133b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613393575b505050505090509450945094509450945091939590929450565b6133d3613703565b6002546001600160a01b03166133fc5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561344057600080fd5b505afa158015613454573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347891906155d0565b600a549091506001600160601b0316818111156134b2576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611afb5760006134c68284615e0e565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561351657600080fd5b505af115801561352a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354e919061559a565b61356b57604051631f01ff1360e21b815260040160405180910390fd5b604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b600d54600160301b900460ff16156135de5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661361357604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c6136428385615db9565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b031661368a9190615db9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde8234846136dd9190615d76565b60408051928352602083019190915201612cb5565b6136fa613703565b610c0c816140a8565b6000546001600160a01b0316331461375d5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c03565b565b60008061376b84613cb0565b60025491935091506001600160a01b03161580159061379257506001600160601b03821615155b156138425760025460405163a9059cbb60e01b81526001600160a01b0385811660048301526001600160601b03851660248301529091169063a9059cbb90604401602060405180830381600087803b1580156137ed57600080fd5b505af1158015613801573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613825919061559a565b61384257604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613898576040519150601f19603f3d011682016040523d82523d6000602084013e61389d565b606091505b50509050806138bf57604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006139478460000151612e5d565b6000818152600e60205260409020549091506001600160a01b03168061398357604051631dfd6e1360e21b815260048101839052602401610c03565b60008286608001516040516020016139a5929190918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526010909352912054909150806139eb57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613a1a978a979096959101615bea565b604051602081830303815290604052805190602001208114613a4f5760405163354a450b60e21b815260040160405180910390fd5b6000613a5e8760000151614152565b905080613b36578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b158015613ad057600080fd5b505afa158015613ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0891906155d0565b905080613b3657865160405163175dadad60e01b81526001600160401b039091166004820152602401610c03565b6000886080015182604051602001613b58929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506000613b7f8a8361423c565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a611388811015613bba57600080fd5b611388810390508460408204820311613bd257600080fd5b50823b613bde57600080fd5b60008083516020850160008789f190505b9392505050565b60008115613c2457601254613c1d9086908690640100000000900463ffffffff16866142a7565b9050613c3e565b601254613c3b908690869063ffffffff1686614311565b90505b949350505050565b6000805b601354811015613ca757826001600160a01b031660138281548110613c7157613c71615f15565b6000918252602090912001546001600160a01b03161415613c955750600192915050565b80613c9f81615e7d565b915050613c4a565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613d3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d1e575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613e19576004600084604001518381518110613dc857613dc8615f15565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff1916905580613e1181615e7d565b915050613da1565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613e51600283018261519d565b5050600085815260066020526040812055613e6d6008866143ff565b50600a8054859190600090613e8c9084906001600160601b0316615e25565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613ed49190615e25565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081019091526000815281613f285750604080516020810190915260008152611355565b63125fa26760e31b613f3a8385615e4d565b6001600160e01b03191614613f6257604051632923fee760e11b815260040160405180910390fd5b613f6f8260048186615d4c565b810190613bef91906155e9565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613fb591511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480614002575062066eed81145b1561407f5760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561404157600080fd5b505afa158015614055573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061407991906155d0565b91505090565b4391505090565b6000613bef838361440b565b6000611355825490565b6000613bef838361445a565b6001600160a01b0381163314156141015760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c03565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480614167575062066eed81145b1561422d57610100836001600160401b0316614181613fed565b61418b9190615e0e565b11806141a7575061419a613fed565b836001600160401b031610155b156141b55750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a829060240160206040518083038186803b1580156141f557600080fd5b505afa158015614209573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bef91906155d0565b50506001600160401b03164090565b60006142708360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614484565b60038360200151604051602001614288929190615b34565b60408051601f1981840301815291905280516020909101209392505050565b6000806142b26146af565b905060005a6142c18888615d76565b6142cb9190615e0e565b6142d59085615def565b905060006142ee63ffffffff871664e8d4a51000615def565b9050826142fb8284615d76565b6143059190615d76565b98975050505050505050565b60008061431c61470b565b905060008113614342576040516321ea67b360e11b815260048101829052602401610c03565b600061434c6146af565b9050600082825a61435d8b8b615d76565b6143679190615e0e565b6143719088615def565b61437b9190615d76565b61438d90670de0b6b3a7640000615def565b6143979190615ddb565b905060006143b063ffffffff881664e8d4a51000615def565b90506143c8816b033b2e3c9fd0803ce8000000615e0e565b8211156143e85760405163e80fa38160e01b815260040160405180910390fd5b6143f28183615d76565b9998505050505050505050565b6000613bef83836147da565b600081815260018301602052604081205461445257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611355565b506000611355565b600082600001828154811061447157614471615f15565b9060005260206000200154905092915050565b61448d896148cd565b6144d95760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c03565b6144e2886148cd565b61452e5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c03565b614537836148cd565b6145835760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c03565b61458c826148cd565b6145d85760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c03565b6145e4878a88876149a6565b6146305760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c03565b600061463c8a87614ac9565b9050600061464f898b878b868989614b2d565b90506000614660838d8d8a86614c4d565b9050808a146146a15760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610c03565b505050505050505050505050565b60004661a4b18114806146c4575062066eed81145b1561470357606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561404157600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093670100000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561476d57600080fd5b505afa158015614781573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147a59190615866565b5094509092508491505080156147c957506147c08242615e0e565b8463ffffffff16105b15613c3e5750601154949350505050565b600081815260018301602052604081205480156148c35760006147fe600183615e0e565b855490915060009061481290600190615e0e565b905081811461487757600086600001828154811061483257614832615f15565b906000526020600020015490508087600001848154811061485557614855615f15565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061488857614888615eff565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611355565b6000915050611355565b80516000906401000003d019116149265760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0191161497f5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d01990800961499f8360005b6020020151614c8d565b1492915050565b60006001600160a01b0382166149ec5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610c03565b602084015160009060011615614a0357601c614a06565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614aa1573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614ad16151bb565b614afe60018484604051602001614aea93929190615a0b565b604051602081830303815290604052614cb1565b90505b614b0a816148cd565b611355578051604080516020810192909252614b269101614aea565b9050614b01565b614b356151bb565b825186516401000003d0199081900691061415614b945760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c03565b614b9f878988614cff565b614beb5760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c03565b614bf6848685614cff565b614c425760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c03565b614305868484614e27565b600060028686868587604051602001614c6b969594939291906159ac565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614cb96151bb565b614cc282614eee565b8152614cd7614cd2826000614995565b614f29565b602082018190526002900660011415612386576020810180516401000003d019039052919050565b600082614d3c5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610c03565b83516020850151600090614d5290600290615ebf565b15614d5e57601c614d61565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614dd3573d6000803e3d6000fd5b505050602060405103519050600086604051602001614df2919061599a565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614e2f6151bb565b835160208086015185519186015160009384938493614e5093909190614f49565b919450925090506401000003d019858209600114614eb05760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c03565b60405180604001604052806401000003d01980614ecf57614ecf615ee9565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d019811061238657604080516020808201939093528151808203840181529082019091528051910120614ef6565b6000611355826002614f426401000003d0196001615d76565b901c615029565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614f89838385856150cb565b9098509050614f9a88828e886150ef565b9098509050614fab88828c876150ef565b90985090506000614fbe8d878b856150ef565b9098509050614fcf888286866150cb565b9098509050614fe088828e896150ef565b9098509050818114615015576401000003d019818a0998506401000003d01982890997506401000003d0198183099650615019565b8196505b5050505050509450945094915050565b6000806150346151d9565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a08201526150666151f7565b60208160c0846005600019fa9250826150c15760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c03565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b82805482825590600052602060002090810192821561518d579160200282015b8281111561518d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615158565b50615199929150615215565b5090565b5080546000825590600052602060002090810190610c0c9190615215565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b808211156151995760008155600101615216565b803561238681615f41565b806040810183101561135557600080fd5b600082601f83011261525757600080fd5b61525f615cdf565b80838560408601111561527157600080fd5b60005b6002811015615293578135845260209384019390910190600101615274565b509095945050505050565b600082601f8301126152af57600080fd5b81356001600160401b03808211156152c9576152c9615f2b565b604051601f8301601f19908116603f011681019082821181831017156152f1576152f1615f2b565b8160405283815286602085880101111561530a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060c0828403121561533c57600080fd5b615344615d07565b905081356001600160401b03808216821461535e57600080fd5b81835260208401356020840152615377604085016153dd565b6040840152615388606085016153dd565b60608401526153996080850161522a565b608084015260a08401359150808211156153b257600080fd5b506153bf8482850161529e565b60a08301525092915050565b803561ffff8116811461238657600080fd5b803563ffffffff8116811461238657600080fd5b805169ffffffffffffffffffff8116811461238657600080fd5b80356001600160601b038116811461238657600080fd5b60006020828403121561543457600080fd5b8135613bef81615f41565b6000806040838503121561545257600080fd5b823561545d81615f41565b915061546b6020840161540b565b90509250929050565b6000806040838503121561548757600080fd5b823561549281615f41565b915060208301356154a281615f41565b809150509250929050565b600080606083850312156154c057600080fd5b82356154cb81615f41565b915061546b8460208501615235565b600080600080606085870312156154f057600080fd5b84356154fb81615f41565b93506020850135925060408501356001600160401b038082111561551e57600080fd5b818701915087601f83011261553257600080fd5b81358181111561554157600080fd5b88602082850101111561555357600080fd5b95989497505060200194505050565b60006040828403121561557457600080fd5b613bef8383615235565b60006040828403121561559057600080fd5b613bef8383615246565b6000602082840312156155ac57600080fd5b8151613bef81615f56565b6000602082840312156155c957600080fd5b5035919050565b6000602082840312156155e257600080fd5b5051919050565b6000602082840312156155fb57600080fd5b604051602081018181106001600160401b038211171561561d5761561d615f2b565b604052823561562b81615f56565b81529392505050565b6000808284036101c081121561564957600080fd5b6101a08082121561565957600080fd5b615661615d29565b915061566d8686615246565b825261567c8660408701615246565b60208301526080850135604083015260a0850135606083015260c085013560808301526156ab60e0860161522a565b60a08301526101006156bf87828801615246565b60c08401526156d2876101408801615246565b60e0840152610180860135908301529092508301356001600160401b038111156156fb57600080fd5b6157078582860161532a565b9150509250929050565b60006020828403121561572357600080fd5b81356001600160401b0381111561573957600080fd5b820160c08185031215613bef57600080fd5b60006020828403121561575d57600080fd5b613bef826153cb565b60008060008060008086880360e081121561578057600080fd5b615789886153cb565b9650615797602089016153dd565b95506157a5604089016153dd565b94506157b3606089016153dd565b9350608088013592506040609f19820112156157ce57600080fd5b506157d7615cdf565b6157e360a089016153dd565b81526157f160c089016153dd565b6020820152809150509295509295509295565b6000806040838503121561581757600080fd5b8235915060208301356154a281615f41565b6000806040838503121561583c57600080fd5b50508035926020909101359150565b60006020828403121561585d57600080fd5b613bef826153dd565b600080600080600060a0868803121561587e57600080fd5b615887866153f1565b94506020860151935060408601519250606086015191506158aa608087016153f1565b90509295509295909350565b600081518084526020808501945080840160005b838110156158ef5781516001600160a01b0316875295820195908201906001016158ca565b509495945050505050565b8060005b6002811015610e6b5781518452602093840193909101906001016158fe565b600081518084526020808501945080840160005b838110156158ef57815187529582019590820190600101615931565b6000815180845260005b8181101561597357602081850181015186830182015201615957565b81811115615985576000602083870101525b50601f01601f19169290920160200192915050565b6159a481836158fa565b604001919050565b8681526159bc60208201876158fa565b6159c960608201866158fa565b6159d660a08201856158fa565b6159e360e08201846158fa565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b838152615a1b60208201846158fa565b606081019190915260800192915050565b6040810161135582846158fa565b602081526000613bef602083018461591d565b602081526000613bef602083018461594d565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c06080840152615aa660e08401826158b6565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615b2657845183529383019391830191600101615b0a565b509098975050505050505050565b82815260608101613bef60208301846158fa565b828152604060208201526000613c3e604083018461591d565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261430560c083018461594d565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143f260e083018461594d565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143f260e083018461594d565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a06080830152615c8760a08301846158b6565b979650505050505050565b6000808335601e19843603018112615ca957600080fd5b8301803591506001600160401b03821115615cc357600080fd5b602001915036819003821315615cd857600080fd5b9250929050565b604080519081016001600160401b0381118282101715615d0157615d01615f2b565b60405290565b60405160c081016001600160401b0381118282101715615d0157615d01615f2b565b60405161012081016001600160401b0381118282101715615d0157615d01615f2b565b60008085851115615d5c57600080fd5b83861115615d6957600080fd5b5050820193919092039150565b60008219821115615d8957615d89615ed3565b500190565b60006001600160401b03808316818516808303821115615db057615db0615ed3565b01949350505050565b60006001600160601b03808316818516808303821115615db057615db0615ed3565b600082615dea57615dea615ee9565b500490565b6000816000190483118215151615615e0957615e09615ed3565b500290565b600082821015615e2057615e20615ed3565b500390565b60006001600160601b0383811690831681811015615e4557615e45615ed3565b039392505050565b6001600160e01b03198135818116916004851015615e755780818660040360031b1b83161692505b505092915050565b6000600019821415615e9157615e91615ed3565b5060010190565b60006001600160401b0380831681811415615eb557615eb5615ed3565b6001019392505050565b600082615ece57615ece615ee9565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c0c57600080fd5b8015158114610c0c57600080fdfea164736f6c6343000806000a", } var VRFCoordinatorV2PlusABI = VRFCoordinatorV2PlusMetaData.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 a6c491ac6b2..90f5219cb7a 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 @@ -75,7 +75,7 @@ vrf_consumer_v2_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2Up vrf_coordinator_mock: ../../contracts/solc/v0.8.6/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock.bin 5c495cf8df1f46d8736b9150cdf174cce358cb8352f60f0d5bb9581e23920501 vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2.bin 75c87cf1624a401ac6303df9c8e04896aa8a53849e8b0c3d7340a9d089ef6d4b vrf_coordinator_v2_plus_v2_example: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.bin 50d881ecf2551c0e56b84cb932f068b703b38b00c73eb05d4e4b80754ecf6b6d -vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.bin bcd16361198eea25b9ca2fb41f019d0ff02f4e7b05289608c37f2e4c9440754d +vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.bin f80932e5292602d0b3adbde425f9c0774926f786c12ad020463e4f8e025426d3 vrf_external_sub_owner_example: ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample.bin 14f888eb313930b50233a6f01ea31eba0206b7f41a41f6311670da8bb8a26963 vrf_load_test_external_sub_owner: ../../contracts/solc/v0.8.6/VRFLoadTestExternalSubOwner.abi ../../contracts/solc/v0.8.6/VRFLoadTestExternalSubOwner.bin 2097faa70265e420036cc8a3efb1f1e0836ad2d7323b295b9a26a125dbbe6c7d vrf_load_test_ownerless_consumer: ../../contracts/solc/v0.8.6/VRFLoadTestOwnerlessConsumer.abi ../../contracts/solc/v0.8.6/VRFLoadTestOwnerlessConsumer.bin 74f914843cbc70b9c3079c3e1c709382ce415225e8bb40113e7ac018bfcb0f5c From dcf265ddb326ec10f428a7d9c84cd4f6ec68c3ed Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Thu, 7 Sep 2023 14:02:59 +0100 Subject: [PATCH 49/88] add more info to pipeline transmitter error (#10537) * add more info to pipeline transmitter error * update notation --- core/services/ocrcommon/transmitter_pipeline.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/services/ocrcommon/transmitter_pipeline.go b/core/services/ocrcommon/transmitter_pipeline.go index 23b672a5e32..d07be5a5409 100644 --- a/core/services/ocrcommon/transmitter_pipeline.go +++ b/core/services/ocrcommon/transmitter_pipeline.go @@ -86,7 +86,7 @@ func (t *pipelineTransmitter) CreateEthTransaction(ctx context.Context, toAddres } if run.State != pipeline.RunStatusCompleted { - return fmt.Errorf("unexpected pipeline run state: %s", run.State) + return fmt.Errorf("unexpected pipeline run state: %s with fatal errors %w", run.State, run.FatalErrors.ToError()) } return nil From 72d431e189fb6254ebf69fa41ffaa9818a835f21 Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 7 Sep 2023 07:54:37 -0600 Subject: [PATCH 50/88] [TT-418] automation e2e docker migration (#10432) * Update the automation tests * Update CI to remove the k8s e2e runners * merge conflict fix * More fixes for CI * merge conflict fixes * merge conflict fixes * Add test comparison check and test list matrix builder * cleanup * bump ctf * more cleanup from review comments * add build test image back in when build-test-image label is added to PR --- .github/workflows/integration-tests.yml | 180 +++--------- integration-tests/actions/actions_local.go | 25 ++ .../actions/automation_ocr_helpers_local.go | 258 ++++++++++++++++++ integration-tests/docker/test_env/cl_node.go | 36 ++- integration-tests/go.mod | 4 +- integration-tests/go.sum | 8 +- .../scripts/buildTestMatrixList.sh | 58 ++++ integration-tests/scripts/compareTestList.sh | 48 ++++ integration-tests/smoke/automation_test.go | 236 ++++++---------- .../smoke/automation_test.go_test_list.json | 106 +++++++ .../smoke/keeper_test.go_test_list.json | 70 +++++ 11 files changed, 722 insertions(+), 307 deletions(-) create mode 100644 integration-tests/actions/actions_local.go create mode 100644 integration-tests/actions/automation_ocr_helpers_local.go create mode 100755 integration-tests/scripts/buildTestMatrixList.sh create mode 100755 integration-tests/scripts/compareTestList.sh create mode 100644 integration-tests/smoke/automation_test.go_test_list.json create mode 100644 integration-tests/smoke/keeper_test.go_test_list.json diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 2e4a710ac97..1b0d0d091ed 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -110,6 +110,7 @@ jobs: echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY build-test-image: + if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'schedule' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || contains(join(github.event.pull_request.labels.*.name, ' '), 'build-test-image') environment: integration permissions: id-token: write @@ -139,14 +140,36 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - eth-smoke-tests-matrix: + compare-tests: + needs: [changes] + runs-on: ubuntu-latest + name: Compare/Build Automation Test List + outputs: + matrix: ${{ env.MATRIX_JSON }} + steps: + - name: Checkout the repo + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - name: Compare Test Lists + run: | + cd ./integration-tests + ./scripts/compareTestList.sh ./smoke/automation_test.go + ./scripts/compareTestList.sh ./smoke/keeper_test.go + - name: Build Test Matrix Lists + id: build-test-matrix-list + run: | + cd ./integration-tests + MATRIX_JSON_AUTOMATION=$(./scripts/buildTestMatrixList.sh ./smoke/automation_test.go automation ubuntu20.04-8cores-32GB) + MATRIX_JSON_KEEPER=$(./scripts/buildTestMatrixList.sh ./smoke/keeper_test.go keeper ubuntu20.04-8cores-32GB) + COMBINED_ARRAY=$(jq -c -n "$MATRIX_JSON_AUTOMATION + $MATRIX_JSON_KEEPER") + echo "MATRIX_JSON=${COMBINED_ARRAY}" >> $GITHUB_ENV + eth-smoke-tests-matrix-automation: environment: integration permissions: checks: write pull-requests: write id-token: write contents: read - needs: [build-chainlink, changes, build-test-image] + needs: [build-chainlink, changes, compare-tests] env: SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2 CHAINLINK_COMMIT_SHA: ${{ github.sha }} @@ -155,16 +178,7 @@ jobs: strategy: fail-fast: false matrix: - product: - - name: automation - nodes: 19 - os: ubuntu-latest - pyroscope_env: ci-smoke-automation-evm-simulated - # temporarily disabled - # - name: ocr2vrf - # nodes: 2 - # os: ubuntu-latest - # pyroscope_env: ci-smoke-ocr2vrf-evm-simulated + product: ${{fromJson(needs.compare-tests.outputs.matrix)}} runs-on: ${{ matrix.product.os }} name: ETH Smoke Tests ${{ matrix.product.name }} steps: @@ -172,23 +186,31 @@ jobs: uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Build Go Test Command + id: build-go-test-command + run: | + # if the matrix.product.run is set, use it for a different command + if [ "${{ matrix.product.run }}" != "" ]; then + echo "run_command=${{ matrix.product.run }} ./smoke/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" + else + echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" + fi ## 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@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 env: - TESTCONTAINERS_RYUK_DISABLED: true PYROSCOPE_SERVER: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} with: - test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ./smoke/${{ matrix.product.name }}_test.go 2>&1 | tee /tmp/gotest.log | gotestfmt + test_command_to_run: make test_need_operator_assets && 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 cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ github.sha }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_location: ./integration-tests/smoke/logs - publish_check_name: EVM Smoke Test Results ${{ matrix.product.name }} + publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} @@ -196,28 +218,6 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - ## 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@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 - 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 }} - cache_restore_only: 'true' - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - - name: Upload test log - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 - if: failure() - with: - name: test-log-${{ matrix.product.name }} - path: /tmp/gotest.log - retention-days: 7 - continue-on-error: true - name: Collect Metrics if: always() id: collect-gha-metrics @@ -228,8 +228,7 @@ jobs: this-job-name: ETH Smoke Tests ${{ matrix.product.name }} test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' continue-on-error: true - - eth-smoke-tests-matrix-docker: + eth-smoke-tests-matrix: environment: integration permissions: checks: write @@ -286,98 +285,6 @@ jobs: nodes: 1 os: ubuntu20.04-8cores-32GB pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated - - # Keeper tests split out to use minimal environments - - name: keeper-1 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperBasicSmoke$ - - name: keeper-2 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperBlockCountPerTurn/registry_1_1$ - - name: keeper-3 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperBlockCountPerTurn/registry_1_2$ - - name: keeper-4 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperBlockCountPerTurn/registry_1_3$ - - name: keeper-5 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperSimulation$ - - name: keeper-6 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperCheckPerformGasLimit/registry_1_2$ - - name: keeper-7 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperCheckPerformGasLimit/registry_1_3$ - - name: keeper-8 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperRegisterUpkeep$ - - name: keeper-9 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperAddFunds$ - - name: keeper-10 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperRemove$ - - name: keeper-11 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperPauseRegistry$ - - name: keeper-12 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperMigrateRegistry$ - - name: keeper-13 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperNodeDown/registry_1_1$ - - name: keeper-14 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperNodeDown/registry_1_2$ - - name: keeper-15 - nodes: 1 - os: ubuntu20.04-8cores-32GB - pyroscope_env: ci-smoke-keeper-evm-simulated - file: keeper - run: -run ^TestKeeperNodeDown/registry_1_3$ runs-on: ${{ matrix.product.os }} name: ETH Smoke Tests ${{ matrix.product.name }} steps: @@ -409,7 +316,7 @@ jobs: cl_image_tag: ${{ github.sha }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_location: ./integration-tests/smoke/logs - publish_check_name: EVM Smoke Test Results ${{ matrix.product.name }} + publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} @@ -454,10 +361,10 @@ jobs: if: always() runs-on: ubuntu-latest name: ETH Smoke Tests - needs: [eth-smoke-tests-matrix,eth-smoke-tests-matrix-docker] + needs: [eth-smoke-tests-matrix, eth-smoke-tests-matrix-automation] steps: - name: Check smoke test matrix status - if: needs.eth-smoke-tests-matrix.result != 'success' || needs.eth-smoke-tests-matrix-docker.result != 'success' + if: needs.eth-smoke-tests-matrix.result != 'success' || needs.eth-smoke-tests-matrix-automation.result != 'success' run: exit 1 - name: Collect Metrics if: always() @@ -699,7 +606,7 @@ jobs: CONTRACT_ARTIFACTS_PATH: contracts/target/deploy steps: - name: Collect Metrics - if: needs.changes.outputs.src == 'true' + if: needs.changes.outputs.src == 'true' && needs.solana-test-image-exists.outputs.exists == 'false' id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: @@ -708,6 +615,7 @@ jobs: this-job-name: Solana Build Test Image continue-on-error: true - name: Checkout the repo + if: needs.changes.outputs.src == 'true' && needs.solana-test-image-exists.outputs.exists == 'false' uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: smartcontractkit/chainlink-solana @@ -721,6 +629,8 @@ 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 }} + - run: echo "this exists so we don't have to run anything else if the build is skipped" + if: needs.changes.outputs.src == 'false' || needs.solana-test-image-exists.outputs.exists == 'true' solana-smoke-tests: environment: integration diff --git a/integration-tests/actions/actions_local.go b/integration-tests/actions/actions_local.go new file mode 100644 index 00000000000..d2e2fde3217 --- /dev/null +++ b/integration-tests/actions/actions_local.go @@ -0,0 +1,25 @@ +// Package actions enables common chainlink interactions +package actions + +import ( + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" +) + +// UpgradeChainlinkNodeVersions upgrades all Chainlink nodes to a new version, and then runs the test environment +// to apply the upgrades +func UpgradeChainlinkNodeVersionsLocal( + newImage, newVersion string, + nodes ...*test_env.ClNode, +) error { + if newImage == "" && newVersion == "" { + return errors.New("unable to upgrade node version, found empty image and version, must provide either a new image or a new version") + } + for _, node := range nodes { + if err := node.UpgradeVersion(node.NodeConfig, newImage, newVersion); err != nil { + return err + } + } + return nil +} diff --git a/integration-tests/actions/automation_ocr_helpers_local.go b/integration-tests/actions/automation_ocr_helpers_local.go new file mode 100644 index 00000000000..dce55e42275 --- /dev/null +++ b/integration-tests/actions/automation_ocr_helpers_local.go @@ -0,0 +1,258 @@ +package actions + +//revive:disable:dot-imports +import ( + "encoding/json" + "fmt" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/lib/pq" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/stretchr/testify/require" + "gopkg.in/guregu/null.v4" + + "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + ocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocr2keepers20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config" + ocr2keepers30config "github.com/smartcontractkit/ocr2keepers/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" +) + +func BuildAutoOCR2ConfigVarsLocal( + t *testing.T, + chainlinkNodes []*client.ChainlinkClient, + registryConfig contracts.KeeperRegistrySettings, + registrar string, + deltaStage time.Duration, +) (contracts.OCRv2Config, error) { + return BuildAutoOCR2ConfigVarsWithKeyIndexLocal(t, chainlinkNodes, registryConfig, registrar, deltaStage, 0) +} + +func BuildAutoOCR2ConfigVarsWithKeyIndexLocal( + t *testing.T, + chainlinkNodes []*client.ChainlinkClient, + registryConfig contracts.KeeperRegistrySettings, + registrar string, + deltaStage time.Duration, + keyIndex int, +) (contracts.OCRv2Config, error) { + l := utils.GetTestLogger(t) + S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndexLocal(chainlinkNodes, keyIndex) + if err != nil { + return contracts.OCRv2Config{}, err + } + + var offC []byte + var signerOnchainPublicKeys []types.OnchainPublicKey + var transmitterAccounts []types.Account + var f uint8 + var offchainConfigVersion uint64 + var offchainConfig []byte + + if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 { + offC, err = json.Marshal(ocr2keepers30config.OffchainConfig{ + TargetProbability: "0.999", + TargetInRounds: 1, + PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose + GasLimitPerReport: 5_300_000, + GasOverheadPerUpkeep: 300_000, + MinConfirmations: 0, + MaxUpkeepBatchSize: 1, + }) + if err != nil { + return contracts.OCRv2Config{}, err + } + + signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr3.ContractSetConfigArgsForTests( + 10*time.Second, // deltaProgress time.Duration, + 15*time.Second, // deltaResend time.Duration, + 500*time.Millisecond, // deltaInitial time.Duration, + 1000*time.Millisecond, // deltaRound time.Duration, + 200*time.Millisecond, // deltaGrace time.Duration, + 300*time.Millisecond, // deltaCertifiedCommitRequest time.Duration + deltaStage, // deltaStage time.Duration, + 24, // rMax uint64, + S, // s []int, + oracleIdentities, // oracles []OracleIdentityExtra, + offC, // reportingPluginConfig []byte, + 20*time.Millisecond, // maxDurationQuery time.Duration, + 20*time.Millisecond, // maxDurationObservation time.Duration, // good to here + 1200*time.Millisecond, // maxDurationShouldAcceptAttestedReport time.Duration, + 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, + 1, // f int, + nil, // onchainConfig []byte, + ) + if err != nil { + return contracts.OCRv2Config{}, err + } + } else { + offC, err = json.Marshal(ocr2keepers20config.OffchainConfig{ + TargetProbability: "0.999", + TargetInRounds: 1, + PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose + GasLimitPerReport: 5_300_000, + GasOverheadPerUpkeep: 300_000, + SamplingJobDuration: 3000, + MinConfirmations: 0, + MaxUpkeepBatchSize: 1, + }) + if err != nil { + return contracts.OCRv2Config{}, err + } + + signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr2.ContractSetConfigArgsForTests( + 10*time.Second, // deltaProgress time.Duration, + 15*time.Second, // deltaResend time.Duration, + 3000*time.Millisecond, // deltaRound time.Duration, + 200*time.Millisecond, // deltaGrace time.Duration, + deltaStage, // deltaStage time.Duration, + 24, // rMax uint8, + S, // s []int, + oracleIdentities, // oracles []OracleIdentityExtra, + offC, // reportingPluginConfig []byte, + 20*time.Millisecond, // maxDurationQuery time.Duration, + 20*time.Millisecond, // maxDurationObservation time.Duration, + 1200*time.Millisecond, // maxDurationReport time.Duration, + 20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration, + 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, + 1, // f int, + nil, // onchainConfig []byte, + ) + if err != nil { + return contracts.OCRv2Config{}, err + } + } + + var signers []common.Address + for _, signer := range signerOnchainPublicKeys { + require.Equal(t, 20, len(signer), "OnChainPublicKey '%v' has wrong length for address", signer) + signers = append(signers, common.BytesToAddress(signer)) + } + + var transmitters []common.Address + for _, transmitter := range transmitterAccounts { + require.True(t, common.IsHexAddress(string(transmitter)), "TransmitAccount '%s' is not a valid Ethereum address", string(transmitter)) + transmitters = append(transmitters, common.HexToAddress(string(transmitter))) + } + + onchainConfig, err := registryConfig.EncodeOnChainConfig(registrar) + if err != nil { + return contracts.OCRv2Config{}, err + } + + l.Info().Msg("Done building OCR config") + return contracts.OCRv2Config{ + Signers: signers, + Transmitters: transmitters, + F: f, + OnchainConfig: onchainConfig, + OffchainConfigVersion: offchainConfigVersion, + OffchainConfig: offchainConfig, + }, nil +} + +// CreateOCRKeeperJobs bootstraps the first node and to the other nodes sends ocr jobs +func CreateOCRKeeperJobsLocal( + chainlinkNodes []*client.ChainlinkClient, + registryAddr string, + chainID int64, + keyIndex int, + registryVersion ethereum.KeeperRegistryVersion, +) error { + bootstrapNode := chainlinkNodes[0] + bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys() + if err != nil { + log.Error().Err(err).Msg("Shouldn't fail reading P2P keys from bootstrap node") + return err + } + bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID + + var contractVersion string + if registryVersion == ethereum.RegistryVersion_2_1 { + contractVersion = "v2.1" + } else if registryVersion == ethereum.RegistryVersion_2_0 { + contractVersion = "v2.0" + } else { + return errors.New("v2.0 and v2.1 are the only supported versions") + } + + bootstrapSpec := &client.OCR2TaskJobSpec{ + Name: "ocr2 bootstrap node " + registryAddr, + JobType: "bootstrap", + OCR2OracleSpec: job.OCR2OracleSpec{ + ContractID: registryAddr, + Relay: "evm", + RelayConfig: map[string]interface{}{ + "chainID": int(chainID), + }, + ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15), + }, + } + _, err = bootstrapNode.MustCreateJob(bootstrapSpec) + if err != nil { + log.Error().Err(err).Msg("Shouldn't fail creating bootstrap job on bootstrap node") + return err + } + + P2Pv2Bootstrapper := fmt.Sprintf("%s@%s:%d", bootstrapP2PId, bootstrapNode.InternalIP(), 6690) + for nodeIndex := 1; nodeIndex < len(chainlinkNodes); nodeIndex++ { + nodeTransmitterAddress, err := chainlinkNodes[nodeIndex].EthAddresses() + if err != nil { + log.Error().Err(err).Msgf("Shouldn't fail getting primary ETH address from OCR node %d", nodeIndex+1) + return err + } + nodeOCRKeys, err := chainlinkNodes[nodeIndex].MustReadOCR2Keys() + if err != nil { + log.Error().Err(err).Msgf("Shouldn't fail getting OCR keys from OCR node %d", nodeIndex+1) + return err + } + var nodeOCRKeyId []string + for _, key := range nodeOCRKeys.Data { + if key.Attributes.ChainType == string(chaintype.EVM) { + nodeOCRKeyId = append(nodeOCRKeyId, key.ID) + break + } + } + + autoOCR2JobSpec := client.OCR2TaskJobSpec{ + Name: "ocr2 " + registryAddr, + JobType: "offchainreporting2", + OCR2OracleSpec: job.OCR2OracleSpec{ + PluginType: "ocr2automation", + Relay: "evm", + RelayConfig: map[string]interface{}{ + "chainID": int(chainID), + }, + PluginConfig: map[string]interface{}{ + "mercuryCredentialName": "\"cred1\"", + "contractVersion": "\"" + contractVersion + "\"", + }, + ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15), + ContractID: registryAddr, // registryAddr + OCRKeyBundleID: null.StringFrom(nodeOCRKeyId[0]), // get node ocr2config.ID + TransmitterID: null.StringFrom(nodeTransmitterAddress[keyIndex]), // node addr + P2PV2Bootstrappers: pq.StringArray{P2Pv2Bootstrapper}, // bootstrap node key and address @bootstrap:8000 + }, + } + + _, err = chainlinkNodes[nodeIndex].MustCreateJob(&autoOCR2JobSpec) + if err != nil { + log.Error().Err(err).Msgf("Shouldn't fail creating OCR Task job on OCR node %d err: %+v", nodeIndex+1, err) + return err + } + + } + log.Info().Msg("Done creating OCR automation jobs") + return nil +} diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index a78f9e52ad6..4c2213b03ee 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -46,6 +46,8 @@ type ClNode struct { NodeSecretsConfigTOML string PostgresDb *test_env.PostgresDb lw *logwatch.LogWatch + ContainerImage string + ContainerVersion string } type ClNodeOption = func(c *ClNode) @@ -101,6 +103,19 @@ func (n *ClNode) Restart(cfg *chainlink.Config) error { return n.StartContainer() } +// UpgradeVersion restarts the cl node with new image and version +func (n *ClNode) UpgradeVersion(cfg *chainlink.Config, newImage, newVersion string) error { + if newVersion == "" { + return fmt.Errorf("new version is empty") + } + if newImage == "" { + newImage = os.Getenv("CHAINLINK_IMAGE") + } + n.ContainerImage = newImage + n.ContainerVersion = newVersion + return n.Restart(n.NodeConfig) +} + func (n *ClNode) PrimaryETHAddress() (string, error) { return n.API.PrimaryEthAddress() } @@ -203,7 +218,6 @@ func (n *ClNode) Fund(evmClient blockchain.EVMClient, amount *big.Float) error { } return evmClient.Fund(toAddress, amount, gasEstimates) } - func (n *ClNode) StartContainer() error { err := n.PostgresDb.StartContainer() if err != nil { @@ -313,18 +327,24 @@ func (n *ClNode) getContainerRequest() ( adminCredsPath := "/home/admin-credentials.txt" apiCredsPath := "/home/api-credentials.txt" - image, ok := os.LookupEnv("CHAINLINK_IMAGE") - if !ok { - return nil, errors.New("CHAINLINK_IMAGE env must be set") + if n.ContainerImage == "" { + image, ok := os.LookupEnv("CHAINLINK_IMAGE") + if !ok { + return nil, errors.New("CHAINLINK_IMAGE env must be set") + } + n.ContainerImage = image } - tag, ok := os.LookupEnv("CHAINLINK_VERSION") - if !ok { - return nil, errors.New("CHAINLINK_VERSION env must be set") + if n.ContainerVersion == "" { + version, ok := os.LookupEnv("CHAINLINK_VERSION") + if !ok { + return nil, errors.New("CHAINLINK_VERSION env must be set") + } + n.ContainerVersion = version } return &tc.ContainerRequest{ Name: n.ContainerName, - Image: fmt.Sprintf("%s:%s", image, tag), + Image: fmt.Sprintf("%s:%s", n.ContainerImage, n.ContainerVersion), ExposedPorts: []string{"6688/tcp"}, Entrypoint: []string{"chainlink", "-c", configPath, diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0874c743853..f485252941d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -20,7 +20,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-env v0.36.0 - github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230829222228-4afd1b3d385c + github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 github.com/smartcontractkit/ocr2keepers v0.7.20 @@ -360,7 +360,7 @@ require ( github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // 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.25.0 // indirect + github.com/prometheus/alertmanager v0.25.1 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index c3a08560bda..029573053cf 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2119,8 +2119,8 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg 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.15.0 h1:6tY5aDqFknY6VZkorFGgZtWygodZQxfmmEF4rqyJW9k= -github.com/prometheus/alertmanager v0.25.0 h1:vbXKUR6PYRiZPRIKfmXaG+dmCKG52RtPL4Btl8hQGvg= -github.com/prometheus/alertmanager v0.25.0/go.mod h1:MEZ3rFVHqKZsw7IcNS/m4AWZeXThmJhumpiWR4eHU/w= +github.com/prometheus/alertmanager v0.25.1 h1:LGBNMspOfv8h7brb+LWj2wnwBCg2ZuuKWTh6CAVw2/Y= +github.com/prometheus/alertmanager v0.25.1/go.mod h1:MEZ3rFVHqKZsw7IcNS/m4AWZeXThmJhumpiWR4eHU/w= 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= @@ -2258,8 +2258,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97ac github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918/go.mod h1:/yp/sqD8Iz5GU5fcercjrw0ivJF7HDcupYg+Gjr7EPg= -github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230829222228-4afd1b3d385c h1:8/L+5JupikVsMga6z0WBElp1RgRO6BB5BF+QsBsSrOI= -github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230829222228-4afd1b3d385c/go.mod h1:t6FJX3akEfAO31p96ru0ilNPfE9P2UshUlXTIkI58LM= +github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2 h1:llbIpJD17IXj0TPwE1r/bgB3X7Gkk9LKsxsXkTBmGe0= +github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2/go.mod h1:xtLIwNaVw/4zWSMnA7j8u1t9tKh0OykvIsYI4xZT3B4= github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI= github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= diff --git a/integration-tests/scripts/buildTestMatrixList.sh b/integration-tests/scripts/buildTestMatrixList.sh new file mode 100755 index 00000000000..25f72715095 --- /dev/null +++ b/integration-tests/scripts/buildTestMatrixList.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# requires a path to a test file to compare the test list against +# requires a matrix job name to be passed in, for example "automation" +# requires a node label to be passed in, for example "ubuntu-latest" + +set -e + +# get this scripts directory +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) + +cd "$SCRIPT_DIR"/../ || exit 1 + +FILENAME=$1 +MATRIX_JOB_NAME=$2 +NODE_LABEL=$3 + +# Get list of test names from JSON file +JSONFILE="${FILENAME}_test_list.json" +COUNTER=1 + +# Build a JSON object in the format expected by our integration-tests workflow matrix +matrix_output() { + local counter=$1 + local job_name=$2 + local test_name=$3 + local node_label=$4 + local counter_out=$(printf "%02d\n" $counter) + echo -n "{\"name\": \"${job_name}-${counter_out}\", \"file\": \"${job_name}\",\"nodes\": 1, \"os\": \"${node_label}\", \"pyroscope_env\": \"ci-smoke-${job_name}-evm-simulated\", \"run\": \"-run '^${test_name}$'\"}" +} + +# Read the JSON file and loop through 'tests' and 'run' +jq -c '.tests[]' ${JSONFILE} | while read -r test; do + testName=$(echo ${test} | jq -r '.name') + subTests=$(echo ${test} | jq -r '.run[]?.name // empty') + output="" + + # Loop through subtests, if any, and print in the desired format + if [ -n "$subTests" ]; then + for subTest in $subTests; do + if [ $COUNTER -ne 1 ]; then + echo -n "," + fi + matrix_output $COUNTER $MATRIX_JOB_NAME "${testName}/${subTest}" ${NODE_LABEL} + ((COUNTER++)) + done + else + if [ $COUNTER -ne 1 ]; then + echo -n "," + fi + matrix_output $COUNTER $MATRIX_JOB_NAME "${testName}" ${NODE_LABEL} + ((COUNTER++)) + fi + +done > "./tmpout.json" +OUTPUT=$(cat ./tmpout.json) +echo "[${OUTPUT}]" +rm ./tmpout.json diff --git a/integration-tests/scripts/compareTestList.sh b/integration-tests/scripts/compareTestList.sh new file mode 100755 index 00000000000..8cc916c7d63 --- /dev/null +++ b/integration-tests/scripts/compareTestList.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# accepts a path to a test file to compare the test list against + +set -e + +# get this scripts directory +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) + +cd "$SCRIPT_DIR"/../ || exit 1 + +FILENAME=$1 + +TESTLIST=$(cat ${FILENAME} | grep "func Test.*\(t \*testing.T\)" | grep -o 'Test[A-Za-z0-9_]*') + +# convert the test list from above into json in the form {"tests":[{"name":"TestName"}]} +TESTLISTJSON=$(echo $TESTLIST | jq -R -s -c '{tests: split(" ") | map({"name":.})}') + +# Get list of test names from JSON file +JSONFILE="${FILENAME}_test_list.json" +JSONTESTLIST=$(jq -r '.tests[].name' ${JSONFILE}) + +# Convert lists to arrays +TESTLIST_ARRAY=($(echo "$TESTLIST")) +JSONTESTLIST_ARRAY=($(echo "$JSONTESTLIST")) + +ERRORS_FOUND=false + +# Compare TESTLIST_ARRAY against JSONTESTLIST_ARRAY +for test in "${TESTLIST_ARRAY[@]}"; do + if [[ ! " ${JSONTESTLIST_ARRAY[@]} " =~ " ${test} " ]]; then + echo "$test exists only in ${FILENAME}." + ERRORS_FOUND=true + fi +done + +# Compare JSONTESTLIST_ARRAY against TESTLIST_ARRAY +for test in "${JSONTESTLIST_ARRAY[@]}"; do + if [[ ! " ${TESTLIST_ARRAY[@]} " =~ " ${test} " ]]; then + echo "$test exists only in ${JSONFILE}." + ERRORS_FOUND=true + fi +done + +if [ "$ERRORS_FOUND" = true ] ; then + echo "Test lists do not match. Please update ${JSONFILE} with the updated tests to run in CI." + exit 1 +fi diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 57ca733b594..109f681ea81 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -6,19 +6,13 @@ import ( "math/big" "os" "strconv" - "strings" "testing" "time" "github.com/onsi/gomega" - "github.com/rs/zerolog/log" "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - "github.com/smartcontractkit/chainlink-env/environment" "github.com/smartcontractkit/chainlink-env/logging" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - eth "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" @@ -26,7 +20,11 @@ import ( "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/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" + it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/smartcontractkit/chainlink/v2/core/store/models" ) const ( @@ -38,25 +36,6 @@ const ( ) var ( - automationBaseTOML = `[Feature] -LogPoller = true - -[OCR2] -Enabled = true - -[Keeper] -TurnLookBack = 0 - -[Keeper.Registry] -SyncInterval = '5m' -PerformGasOverhead = 150_000 - -[P2P] -[P2P.V2] -Enabled = true -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"]` - defaultOCRRegistryConfig = contracts.KeeperRegistrySettings{ PaymentPremiumPPB: uint32(200000000), FlatFeeMicroLINK: uint32(0), @@ -128,12 +107,9 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { require.NoError(t, err, "Error getting upgrade version") testName = "node-upgrade" } - chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, testEnv := setupAutomationTest( + chainClient, _, contractDeployer, linkToken, registry, registrar, testEnv := setupAutomationTestDocker( t, testName, registryVersion, defaultOCRRegistryConfig, nodeUpgrade, ) - if onlyStartRunner { - return - } // Use the name to determine if this is a log trigger or not isLogTrigger := name == "registry_2_1_logtrigger" @@ -181,7 +157,7 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { expect := 5 // Upgrade the nodes one at a time and check that the upkeeps are still being performed for i := 0; i < 5; i++ { - actions.UpgradeChainlinkNodeVersions(testEnv, upgradeImage, upgradeVersion, chainlinkNodes[i]) + actions.UpgradeChainlinkNodeVersionsLocal(upgradeImage, upgradeVersion, testEnv.CLNodes[i]) time.Sleep(time.Second * 10) expect = expect + 5 gom.Eventually(func(g gomega.Gomega) { @@ -242,13 +218,9 @@ func TestAutomationAddFunds(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - - chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "add-funds", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(1), automationDefaultUpkeepGasLimit, false) @@ -298,13 +270,9 @@ func TestAutomationPauseUnPause(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - - chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "pause-unpause", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) @@ -386,13 +354,9 @@ func TestAutomationRegisterUpkeep(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - - chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "register-upkeep", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) @@ -462,12 +426,9 @@ func TestAutomationPauseRegistry(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "pause-registry", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) gom := gomega.NewGomegaWithT(t) @@ -524,13 +485,9 @@ func TestAutomationKeeperNodesDown(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - - chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "keeper-nodes-down", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) gom := gomega.NewGomegaWithT(t) @@ -614,13 +571,9 @@ func TestAutomationPerformSimulation(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - - chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "perform-simulation", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } consumersPerformance, _ := actions.DeployPerformanceConsumers( t, @@ -683,13 +636,9 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - - chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "gas-limit", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } consumersPerformance, upkeepIDs := actions.DeployPerformanceConsumers( t, @@ -767,7 +716,7 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { highCheckGasLimit := automationDefaultRegistryConfig highCheckGasLimit.CheckGasLimit = uint32(5000000) highCheckGasLimit.RegistryVersion = registryVersion - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, highCheckGasLimit, registrar.Address(), 30*time.Second) + ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(t, nodesWithoutBootstrap, highCheckGasLimit, registrar.Address(), 30*time.Second) require.NoError(t, err, "Error building OCR config") err = registry.SetConfig(highCheckGasLimit, ocrConfig) @@ -801,13 +750,9 @@ func TestUpdateCheckData(t *testing.T) { registryVersion := rv t.Run(name, func(t *testing.T) { t.Parallel() - - chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest( + chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( t, "update-check-data", registryVersion, defaultOCRRegistryConfig, false, ) - if onlyStartRunner { - return - } performDataChecker, upkeepIDs := actions.DeployPerformDataCheckerConsumers( t, @@ -865,103 +810,78 @@ func TestUpdateCheckData(t *testing.T) { } } -func setupAutomationTest( +func setupAutomationTestDocker( t *testing.T, testName string, registryVersion ethereum.KeeperRegistryVersion, registryConfig contracts.KeeperRegistrySettings, statefulDb bool, ) ( - chainClient blockchain.EVMClient, - chainlinkNodes []*client.ChainlinkK8sClient, - contractDeployer contracts.ContractDeployer, - linkToken contracts.LinkToken, - registry contracts.KeeperRegistry, - registrar contracts.KeeperRegistrar, - onlyStartRunner bool, - testEnvironment *environment.Environment, + blockchain.EVMClient, + []*client.ChainlinkClient, + contracts.ContractDeployer, + contracts.LinkToken, + contracts.KeeperRegistry, + contracts.KeeperRegistrar, + *test_env.CLClusterTestEnv, ) { // Add registry version to config registryConfig.RegistryVersion = registryVersion - network := networks.SelectedNetwork - evmConfig := eth.New(nil) - if !network.Simulated { - evmConfig = eth.New(ð.Props{ - NetworkName: network.Name, - Simulated: network.Simulated, - WsURLs: network.URLs, - }) - } - chainlinkProps := map[string]any{ - "toml": client.AddNetworksConfig(automationBaseTOML, network), - "secretsToml": client.AddSecretTomlConfig("https://google.com", "username1", "password1"), - "db": map[string]any{ - "stateful": statefulDb, - }, - } - - cd, err := chainlink.NewDeployment(5, chainlinkProps) - require.NoError(t, err, "Failed to create chainlink deployment") - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-automation-%s-%s", testName, strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")), - Test: t, - }). - AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() - - require.NoError(t, err, "Error setting up test environment") - - onlyStartRunner = testEnvironment.WillUseRemoteRunner() - if !onlyStartRunner { - chainClient, err = blockchain.NewEVMClient(network, testEnvironment) - require.NoError(t, err, "Error connecting to blockchain") - contractDeployer, err = contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Error building contract deployer") - chainlinkNodes, err = client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Error connecting to Chainlink nodes") - t.Cleanup(func() { - if err := actions.ReturnFunds(chainlinkNodes, chainClient); err != nil { - log.Error().Err(err).Msg("Error returning funds") - } - }) - chainClient.ParallelTransactions(true) - - txCost, err := chainClient.EstimateCostForChainlinkOperations(1000) - require.NoError(t, err, "Error estimating cost for Chainlink Operations") - err = actions.FundChainlinkNodes(chainlinkNodes, chainClient, txCost) - require.NoError(t, err, "Error funding Chainlink nodes") - - linkToken, err = contractDeployer.DeployLinkTokenContract() - require.NoError(t, err, "Error deploying LINK token") - - registry, registrar = actions.DeployAutoOCRRegistryAndRegistrar( - t, - registryVersion, - registryConfig, - linkToken, - contractDeployer, - chainClient, - ) - - // Fund the registry with LINK - err = linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(defaultAmountOfUpkeeps)))) - require.NoError(t, err, "Funding keeper registry contract shouldn't fail") - - actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion) - nodesWithoutBootstrap := chainlinkNodes[1:] - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, registryConfig, registrar.Address(), 30*time.Second) - require.NoError(t, err, "Error building OCR config vars") - err = registry.SetConfig(automationDefaultRegistryConfig, ocrConfig) - require.NoError(t, err, "Registry config should be set successfully") - require.NoError(t, chainClient.WaitForEvents(), "Waiting for config to be set") - // Register cleanup for any test - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - } - return chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, testEnvironment + // build the node config + clNodeConfig := node.NewConfig(node.BaseConf) + syncInterval := models.MustMakeDuration(5 * time.Minute) + clNodeConfig.Feature.LogPoller = it_utils.Ptr[bool](true) + clNodeConfig.OCR2.Enabled = it_utils.Ptr[bool](true) + clNodeConfig.Keeper.TurnLookBack = it_utils.Ptr[int64](int64(0)) + clNodeConfig.Keeper.Registry.SyncInterval = &syncInterval + clNodeConfig.Keeper.Registry.PerformGasOverhead = it_utils.Ptr[uint32](uint32(150000)) + clNodeConfig.P2P.V2.Enabled = it_utils.Ptr[bool](true) + clNodeConfig.P2P.V2.AnnounceAddresses = &[]string{"0.0.0.0:6690"} + clNodeConfig.P2P.V2.ListenAddresses = &[]string{"0.0.0.0:6690"} + + // launch the environment + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(5). + WithCLNodeConfig(clNodeConfig). + WithFunding(big.NewFloat(.5)). + Build() + require.NoError(t, err, "Error deploying test environment") + env.ParallelTransactions(true) + + txCost, err := env.EVMClient.EstimateCostForChainlinkOperations(1000) + require.NoError(t, err, "Error estimating cost for Chainlink Operations") + nodeClients := env.GetAPIs() + workerNodes := nodeClients[1:] + err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, txCost) + require.NoError(t, err, "Error funding Chainlink nodes") + + linkToken, err := env.ContractDeployer.DeployLinkTokenContract() + require.NoError(t, err, "Error deploying LINK token") + + registry, registrar := actions.DeployAutoOCRRegistryAndRegistrar( + t, + registryVersion, + registryConfig, + linkToken, + env.ContractDeployer, + env.EVMClient, + ) + + // Fund the registry with LINK + err = linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(defaultAmountOfUpkeeps)))) + require.NoError(t, err, "Funding keeper registry contract shouldn't fail") + + err = actions.CreateOCRKeeperJobsLocal(nodeClients, registry.Address(), network.ChainID, 0, registryVersion) + require.NoError(t, err, "Error creating OCR Keeper Jobs") + ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(t, workerNodes, registryConfig, registrar.Address(), 30*time.Second) + require.NoError(t, err, "Error building OCR config vars") + err = registry.SetConfig(automationDefaultRegistryConfig, ocrConfig) + require.NoError(t, err, "Registry config should be set successfully") + require.NoError(t, env.EVMClient.WaitForEvents(), "Waiting for config to be set") + + return env.EVMClient, nodeClients, env.ContractDeployer, linkToken, registry, registrar, env } diff --git a/integration-tests/smoke/automation_test.go_test_list.json b/integration-tests/smoke/automation_test.go_test_list.json new file mode 100644 index 00000000000..badb7d6b3eb --- /dev/null +++ b/integration-tests/smoke/automation_test.go_test_list.json @@ -0,0 +1,106 @@ +{ + "tests": [ + { + "name": "TestAutomationBasic", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1_conditional" + }, + { + "name": "registry_2_1_logtrigger" + } + ] + }, + { + "name": "TestAutomationAddFunds", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + }, + { + "name": "TestAutomationPauseUnPause", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + }, + { + "name": "TestAutomationRegisterUpkeep", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + }, + { + "name": "TestAutomationPauseRegistry", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + }, + { + "name": "TestAutomationKeeperNodesDown", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + }, + { + "name": "TestAutomationPerformSimulation", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + }, + { + "name": "TestAutomationCheckPerformGasLimit", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + }, + { + "name": "TestUpdateCheckData", + "run": [ + { + "name": "registry_2_0" + }, + { + "name": "registry_2_1" + } + ] + } + ] +} diff --git a/integration-tests/smoke/keeper_test.go_test_list.json b/integration-tests/smoke/keeper_test.go_test_list.json new file mode 100644 index 00000000000..864dbfdb1cf --- /dev/null +++ b/integration-tests/smoke/keeper_test.go_test_list.json @@ -0,0 +1,70 @@ +{ + "tests": [ + { + "name": "TestKeeperBasicSmoke" + }, + { + "name": "TestKeeperBlockCountPerTurn", + "run": [ + { + "name": "registry_1_1" + }, + { + "name": "registry_1_2" + }, + { + "name": "registry_1_3" + } + ] + }, + { + "name": "TestKeeperSimulation" + }, + { + "name": "TestKeeperCheckPerformGasLimit", + "run": [ + { + "name": "registry_1_2" + }, + { + "name": "registry_1_3" + } + ] + }, + { + "name": "TestKeeperRegisterUpkeep" + }, + { + "name": "TestKeeperAddFunds" + }, + { + "name": "TestKeeperRemove" + }, + { + "name": "TestKeeperPauseRegistry" + }, + { + "name": "TestKeeperMigrateRegistry" + }, + { + "name": "TestKeeperNodeDown", + "run": [ + { + "name": "registry_1_1" + }, + { + "name": "registry_1_2" + }, + { + "name": "registry_1_3" + } + ] + }, + { + "name": "TestKeeperPauseUnPauseUpkeep" + }, + { + "name": "TestKeeperUpdateCheckData" + } + ] +} From 4e6ab6df8da9a571b37627a955b4d660b4616e2d Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:29:39 +0100 Subject: [PATCH 51/88] Improve checkBlockTooOld error detection (#10536) --- .../ocr2keeper/evm21/registry_check_pipeline.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go index bf57ce496a3..abe11c00aef 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go @@ -15,6 +15,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" ) +const ( + // checkBlockTooOldRange is the number of blocks that can be behind the latest block before + // we return a CheckBlockTooOld error + checkBlockTooOldRange = 128 +) + type checkResult struct { cr []ocr2keepers.CheckResult err error @@ -234,10 +240,12 @@ func (r *EvmRegistry) checkUpkeeps(ctx context.Context, payloads []ocr2keepers.U for i, req := range checkReqs { index := indices[i] if req.Error != nil { + latestBlock := r.bs.latestBlock.Load() + checkBlock, _, _ := r.getBlockAndUpkeepId(payloads[index].UpkeepID, payloads[index].Trigger) // primitive way of checking errors - if strings.Contains(req.Error.Error(), "header not found") { - // Check block not found in RPC, non-retryable error - r.lggr.Warnf("header not found error encountered in check result for upkeepId %s: %s", results[index].UpkeepID.String(), req.Error) + if strings.Contains(req.Error.Error(), "header not found") && int64(latestBlock.Number)-checkBlock.Int64() > checkBlockTooOldRange { + // Check block not found in RPC and it is too old, non-retryable error + r.lggr.Warnf("header not found error encountered in check result for upkeepId %s, check block %d, latest block %d: %s", results[index].UpkeepID.String(), checkBlock.Int64(), int64(latestBlock.Number), req.Error) results[index].Retryable = false results[index].PipelineExecutionState = uint8(encoding.CheckBlockTooOld) } else { From b435d938150b7685c23f29eaef38e2fe85a520bd Mon Sep 17 00:00:00 2001 From: aalu1418 <50029043+aalu1418@users.noreply.github.com> Date: Thu, 7 Sep 2023 09:12:35 -0600 Subject: [PATCH 52/88] move CLI update to dev section in changelog --- docs/CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f75628dcfb5..5ce56b429cb 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,13 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Unauthenticated users executing CLI commands previously generated a confusing error log, which is now removed: ```[ERROR] Error in transaction, rolling back: session missing or expired, please login again pg/transaction.go:118 ``` - Fixed a bug that was preventing job runs to be displayed when the job `chainID` was disabled. +- `chainlink txs evm create` returns a transaction hash for the attempted transaction in the CLI. Previously only the sender, receipient and `unstarted` state were returned. ... ## 2.5.0 - UNRELEASED -### Fixed -- `chainlink txs evm create` returns a transaction hash for the attempted transaction in the CLI. Previously only the sender, receipient and `unstarted` state were returned. - ### Upcoming Required Configuration Change - Starting in 2.6.0, chainlink nodes will no longer allow insecure configuration for production builds. Any TOML configuration that sets the following line will fail validation checks in `node start` or `node validate`: From c325f960e366d4d1b5dd368a29e68d66b54684d2 Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Thu, 7 Sep 2023 18:41:10 +0100 Subject: [PATCH 53/88] Include logBlockHash in trigger and workID (#10476) * Include logBlockHash in trigger and workID * update ocr2keepers ref * update wrappers * update packer * fix merge in event provider.go * fix test * fix test * fix test * fix test * fix test * fix test * fix reorg protection for log upkeeps in pipeline and recoverer * fix test * fix test * update comment * update dependency * fix test * fix tests * fix another test * fix test * update log struct * update bytecode * update ocr2keepers to tag --- .../automation/2_1/KeeperRegistryBase2_1.sol | 3 +- .../v0.8/automation/KeeperRegistry2_1.test.ts | 12 ++- .../automation_utils_2_1.go | 13 +-- .../keeper_registry_wrapper_2_1.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 4 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- .../ocr2keeper/evm21/core/payload_test.go | 16 +-- .../plugins/ocr2keeper/evm21/core/trigger.go | 10 +- .../ocr2keeper/evm21/core/trigger_test.go | 11 +- .../ocr2keeper/evm21/encoding/encoder.go | 2 + .../ocr2keeper/evm21/encoding/encoder_test.go | 11 +- .../ocr2keeper/evm21/encoding/interface.go | 1 + .../ocr2keeper/evm21/logprovider/buffer.go | 2 +- .../evm21/logprovider/buffer_test.go | 36 +++---- .../evm21/logprovider/log_packer.go | 2 +- .../ocr2keeper/evm21/logprovider/recoverer.go | 28 ++--- .../evm21/logprovider/recoverer_test.go | 100 +++++++++++++++++- .../evm21/registry_check_pipeline.go | 8 +- .../evm21/registry_check_pipeline_test.go | 22 +++- .../evm21/transmit/event_provider.go | 6 +- .../evm21/transmit/event_provider_test.go | 6 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- 26 files changed, 224 insertions(+), 89 deletions(-) diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol index e58dbf05f87..ccd286fda2f 100644 --- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol +++ b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol @@ -398,6 +398,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { * not necessarily the block number that the log was emitted in!!!! */ struct LogTrigger { + bytes32 logBlockHash; bytes32 txHash; uint32 logIndex; uint32 blockNum; @@ -794,7 +795,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { UpkeepTransmitInfo memory transmitInfo ) internal returns (bool, bytes32) { LogTrigger memory trigger = abi.decode(rawTrigger, (LogTrigger)); - bytes32 dedupID = keccak256(abi.encodePacked(upkeepId, trigger.txHash, trigger.logIndex)); + bytes32 dedupID = keccak256(abi.encodePacked(upkeepId, trigger.logBlockHash, trigger.txHash, trigger.logIndex)); if ( (trigger.blockHash != bytes32("") && _blockHash(trigger.blockNum) != trigger.blockHash) || trigger.blockNum >= _blockNum() diff --git a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts index a14946a06a9..b65f2faea50 100644 --- a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts +++ b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts @@ -64,7 +64,7 @@ describe('KeeperRegistry2_1 - Frozen [ @skip-coverage ]', () => { it('has not changed', () => { assert.equal( ethers.utils.id(KeeperRegistryFactory.bytecode), - '0xd94f351a1cd64aa81dd7238301f680f4bfc2a0f84c4b5451525f3f879488f033', + '0xd8dfe20e746039e8420349326becc0a15dcd8fa3cd6aa0924d214328a7c45206', 'KeeperRegistry bytecode has changed', ) assert.equal( @@ -741,6 +741,7 @@ describe('KeeperRegistry2_1', () => { performData?: string checkBlockNum?: number checkBlockHash?: string + logBlockHash?: BytesLike txHash?: BytesLike logIndex?: number timestamp?: number @@ -763,6 +764,7 @@ describe('KeeperRegistry2_1', () => { checkBlockHash: latestBlock.hash, logIndex: 0, txHash: undefined, // assigned uniquely below + logBlockHash: undefined, // assigned uniquely below timestamp: now(), gasLimit: undefined, gasPrice: undefined, @@ -780,6 +782,7 @@ describe('KeeperRegistry2_1', () => { break case Trigger.LOG: trigger = encodeLogTrigger({ + logBlockHash: config.logBlockHash || ethers.utils.randomBytes(32), txHash: config.txHash || ethers.utils.randomBytes(32), logIndex: config.logIndex, blockNum: config.checkBlockNum, @@ -1238,18 +1241,19 @@ describe('KeeperRegistry2_1', () => { }) it('handles duplicate log triggers', async () => { + const logBlockHash = ethers.utils.randomBytes(32) const txHash = ethers.utils.randomBytes(32) const logIndex = 0 const expectedDedupKey = ethers.utils.solidityKeccak256( - ['uint256', 'bytes32', 'uint32'], - [logUpkeepId, txHash, logIndex], + ['uint256', 'bytes32', 'bytes32', 'uint32'], + [logUpkeepId, logBlockHash, txHash, logIndex], ) assert.isFalse(await registry.hasDedupKey(expectedDedupKey)) const tx = await getTransmitTx( registry, keeper1, [logUpkeepId, logUpkeepId], - { txHash, logIndex }, // will result in the same dedup key + { logBlockHash, txHash, logIndex }, // will result in the same dedup key ) const receipt = await tx.wait() const staleUpkeepReport = parseStaleUpkeepReportLogs(receipt) diff --git a/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go b/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go index 6d6991546f0..6e22e4423f5 100644 --- a/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go +++ b/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go @@ -34,10 +34,11 @@ type KeeperRegistryBase21ConditionalTrigger struct { } type KeeperRegistryBase21LogTrigger struct { - TxHash [32]byte - LogIndex uint32 - BlockNum uint32 - BlockHash [32]byte + LogBlockHash [32]byte + TxHash [32]byte + LogIndex uint32 + BlockNum uint32 + BlockHash [32]byte } type KeeperRegistryBase21OnchainConfig struct { @@ -88,8 +89,8 @@ type LogTriggerConfig struct { } var AutomationUtilsMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structKeeperRegistryBase2_1.ConditionalTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_conditionalTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"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\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structKeeperRegistryBase2_1.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\":\"structKeeperRegistryBase2_1.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\":\"structKeeperRegistryBase2_1.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506108be806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c80634b6df294116100505780634b6df294146100a6578063e65d6546146100b4578063e9720a49146100c257600080fd5b80631c8d82601461007757806321f373d71461008a5780632ff92a8114610098575b600080fd5b6100886100853660046101d8565b50565b005b61008861008536600461026e565b6100886100853660046103d5565b61008861008536600461052f565b6100886100853660046106ef565b6100886100853660046107dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715610123576101236100d0565b60405290565b60405160c0810167ffffffffffffffff81118282101715610123576101236100d0565b604051610100810167ffffffffffffffff81118282101715610123576101236100d0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101b7576101b76100d0565b604052919050565b803563ffffffff811681146101d357600080fd5b919050565b6000608082840312156101ea57600080fd5b6040516080810181811067ffffffffffffffff8211171561020d5761020d6100d0565b60405282358152610220602084016101bf565b6020820152610231604084016101bf565b6040820152606083013560608201528091505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d357600080fd5b600060c0828403121561028057600080fd5b60405160c0810181811067ffffffffffffffff821117156102a3576102a36100d0565b6040526102af8361024a565b8152602083013560ff811681146102c557600080fd5b8060208301525060408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b803562ffffff811681146101d357600080fd5b803561ffff811681146101d357600080fd5b80356bffffffffffffffffffffffff811681146101d357600080fd5b600067ffffffffffffffff821115610359576103596100d0565b5060051b60200190565b600082601f83011261037457600080fd5b813560206103896103848361033f565b610170565b82815260059290921b840181019181810190868411156103a857600080fd5b8286015b848110156103ca576103bd8161024a565b83529183019183016103ac565b509695505050505050565b6000602082840312156103e757600080fd5b813567ffffffffffffffff808211156103ff57600080fd5b908301906101e0828603121561041457600080fd5b61041c6100ff565b610425836101bf565b8152610433602084016101bf565b6020820152610444604084016101bf565b6040820152610455606084016102fe565b606082015261046660808401610311565b608082015261047760a08401610323565b60a082015261048860c084016101bf565b60c082015261049960e084016101bf565b60e08201526101006104ac8185016101bf565b908201526101206104be8482016101bf565b90820152610140838101359082015261016080840135908201526101806104e681850161024a565b908201526101a083810135838111156104fe57600080fd5b61050a88828701610363565b8284015250506101c0915061052082840161024a565b91810191909152949350505050565b60006040828403121561054157600080fd5b6040516040810181811067ffffffffffffffff82111715610564576105646100d0565b604052610570836101bf565b8152602083013560208201528091505092915050565b600082601f83011261059757600080fd5b813560206105a76103848361033f565b82815260059290921b840181019181810190868411156105c657600080fd5b8286015b848110156103ca57803583529183019183016105ca565b600082601f8301126105f257600080fd5b813567ffffffffffffffff81111561060c5761060c6100d0565b61063d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610170565b81815284602083860101111561065257600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261068057600080fd5b813560206106906103848361033f565b82815260059290921b840181019181810190868411156106af57600080fd5b8286015b848110156103ca57803567ffffffffffffffff8111156106d35760008081fd5b6106e18986838b01016105e1565b8452509183019183016106b3565b60006020828403121561070157600080fd5b813567ffffffffffffffff8082111561071957600080fd5b9083019060c0828603121561072d57600080fd5b610735610129565b823581526020830135602082015260408301358281111561075557600080fd5b61076187828601610586565b60408301525060608301358281111561077957600080fd5b61078587828601610586565b60608301525060808301358281111561079d57600080fd5b6107a98782860161066f565b60808301525060a0830135828111156107c157600080fd5b6107cd8782860161066f565b60a08301525095945050505050565b6000602082840312156107ee57600080fd5b813567ffffffffffffffff8082111561080657600080fd5b90830190610100828603121561081b57600080fd5b61082361014c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261085b60a0840161024a565b60a082015260c08301358281111561087257600080fd5b61087e87828601610586565b60c08301525060e08301358281111561089657600080fd5b6108a2878286016105e1565b60e0830152509594505050505056fea164736f6c6343000810000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structKeeperRegistryBase2_1.ConditionalTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_conditionalTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"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\":\"structKeeperRegistryBase2_1.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\":\"structKeeperRegistryBase2_1.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\":\"structKeeperRegistryBase2_1.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506108ca806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063776f306111610050578063776f3061146100a6578063e65d6546146100b4578063e9720a49146100c257600080fd5b806321f373d7146100775780632ff92a811461008a5780634b6df29414610098575b600080fd5b6100886100853660046101e8565b50565b005b610088610085366004610363565b6100886100853660046104bd565b610088610085366004610514565b6100886100853660046106fb565b6100886100853660046107e8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715610123576101236100d0565b60405290565b60405160c0810167ffffffffffffffff81118282101715610123576101236100d0565b604051610100810167ffffffffffffffff81118282101715610123576101236100d0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101b7576101b76100d0565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101e357600080fd5b919050565b600060c082840312156101fa57600080fd5b60405160c0810181811067ffffffffffffffff8211171561021d5761021d6100d0565b604052610229836101bf565b8152602083013560ff8116811461023f57600080fd5b8060208301525060408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b803563ffffffff811681146101e357600080fd5b803562ffffff811681146101e357600080fd5b803561ffff811681146101e357600080fd5b80356bffffffffffffffffffffffff811681146101e357600080fd5b600067ffffffffffffffff8211156102e7576102e76100d0565b5060051b60200190565b600082601f83011261030257600080fd5b81356020610317610312836102cd565b610170565b82815260059290921b8401810191818101908684111561033657600080fd5b8286015b848110156103585761034b816101bf565b835291830191830161033a565b509695505050505050565b60006020828403121561037557600080fd5b813567ffffffffffffffff8082111561038d57600080fd5b908301906101e082860312156103a257600080fd5b6103aa6100ff565b6103b383610278565b81526103c160208401610278565b60208201526103d260408401610278565b60408201526103e36060840161028c565b60608201526103f46080840161029f565b608082015261040560a084016102b1565b60a082015261041660c08401610278565b60c082015261042760e08401610278565b60e082015261010061043a818501610278565b9082015261012061044c848201610278565b90820152610140838101359082015261016080840135908201526101806104748185016101bf565b908201526101a0838101358381111561048c57600080fd5b610498888287016102f1565b8284015250506101c091506104ae8284016101bf565b91810191909152949350505050565b6000604082840312156104cf57600080fd5b6040516040810181811067ffffffffffffffff821117156104f2576104f26100d0565b6040526104fe83610278565b8152602083013560208201528091505092915050565b600060a0828403121561052657600080fd5b60405160a0810181811067ffffffffffffffff82111715610549576105496100d0565b8060405250823581526020830135602082015261056860408401610278565b604082015261057960608401610278565b6060820152608083013560808201528091505092915050565b600082601f8301126105a357600080fd5b813560206105b3610312836102cd565b82815260059290921b840181019181810190868411156105d257600080fd5b8286015b8481101561035857803583529183019183016105d6565b600082601f8301126105fe57600080fd5b813567ffffffffffffffff811115610618576106186100d0565b61064960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610170565b81815284602083860101111561065e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261068c57600080fd5b8135602061069c610312836102cd565b82815260059290921b840181019181810190868411156106bb57600080fd5b8286015b8481101561035857803567ffffffffffffffff8111156106df5760008081fd5b6106ed8986838b01016105ed565b8452509183019183016106bf565b60006020828403121561070d57600080fd5b813567ffffffffffffffff8082111561072557600080fd5b9083019060c0828603121561073957600080fd5b610741610129565b823581526020830135602082015260408301358281111561076157600080fd5b61076d87828601610592565b60408301525060608301358281111561078557600080fd5b61079187828601610592565b6060830152506080830135828111156107a957600080fd5b6107b58782860161067b565b60808301525060a0830135828111156107cd57600080fd5b6107d98782860161067b565b60a08301525095945050505050565b6000602082840312156107fa57600080fd5b813567ffffffffffffffff8082111561081257600080fd5b90830190610100828603121561082757600080fd5b61082f61014c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261086760a084016101bf565b60a082015260c08301358281111561087e57600080fd5b61088a87828601610592565b60c08301525060e0830135828111156108a257600080fd5b6108ae878286016105ed565b60e0830152509594505050505056fea164736f6c6343000810000a", } var AutomationUtilsABI = AutomationUtilsMetaData.ABI diff --git a/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go b/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go index 4bbd827dc52..1db34ca3953 100644 --- a/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go +++ b/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go @@ -50,7 +50,7 @@ type KeeperRegistryBase21OnchainConfig struct { var KeeperRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractKeeperRegistryLogicB2_1\",\"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\":\"structKeeperRegistryBase2_1.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: "0x6101406040523480156200001257600080fd5b50604051620054b9380380620054b98339810160408190526200003591620003df565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000406565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003df565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003df565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003df565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003df565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b9816200031b565b505050846002811115620002d157620002d162000429565b60e0816002811115620002e857620002e862000429565b9052506001600160a01b0393841660805291831660a052821660c0528116610100529190911661012052506200043f9050565b336001600160a01b03821603620003755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003dc57600080fd5b50565b600060208284031215620003f257600080fd5b8151620003ff81620003c6565b9392505050565b6000602082840312156200041957600080fd5b815160038110620003ff57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e0516101005161012051615018620004a16000396000818160d6015261016f01526000505060008181612eb701528181613220015281816133b30152613a3e01526000505060005050600061043b01526150186000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e29b753c1161005b578063e29b753c146102e8578063e3d0e712146102fb578063f2fde38b1461030e576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102d5576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601481526020017f4b6565706572526567697374727920322e312e3000000000000000000000000081525081565b6040516101649190613cbd565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610321565b61020e60145460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613d46565b610423565b610275610270366004613da2565b61063f565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102e3366004613e33565b6107a7565b6101196102f63660046142ae565b6112ea565b61011961030936600461437b565b6121e6565b61011961031c36600461440a565b61220f565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610492576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104cc576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104da82840184614427565b60008181526004602052604090205490915065010000000000900463ffffffff90811614610534576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461056f9085906c0100000000000000000000000090046bffffffffffffffffffffffff1661446f565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556018546105da908590614494565b6018556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b60008061064a612223565b6012546e010000000000000000000000000000900460ff1615610699576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f8901859004850281018501909552878552909361079893899089908190840183828082843760009201919091525061225d92505050565b9093509150505b935093915050565b60005a604080516101208101825260125460ff808216835261010080830463ffffffff90811660208601526501000000000084048116958501959095526901000000000000000000830462ffffff1660608501526c01000000000000000000000000830461ffff1660808501526e0100000000000000000000000000008304821615801560a08601526f010000000000000000000000000000008404909216151560c085015270010000000000000000000000000000000083046bffffffffffffffffffffffff1660e08501527c0100000000000000000000000000000000000000000000000000000000909204909316908201529192506108d5576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff1661091e576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a351461095a576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516109679060016144d6565b60ff16861415806109785750858414155b156109af576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109bf8a8a8a8a8a8a8a8a612468565b60006109cb8a8a6126d1565b9050600081604001515167ffffffffffffffff8111156109ed576109ed613eea565b604051908082528060200260200182016040528015610ab157816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610a0b5790505b5090506000805b836040015151811015610efa576004600085604001518381518110610adf57610adf6144a7565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201528351849083908110610bc457610bc46144a7565b602002602001015160000181905250610bf984604001518281518110610bec57610bec6144a7565b602002602001015161278c565b838281518110610c0b57610c0b6144a7565b6020026020010151608001906001811115610c2857610c286144ef565b90816001811115610c3b57610c3b6144ef565b81525050610caf85848381518110610c5557610c556144a7565b60200260200101516080015186606001518481518110610c7757610c776144a7565b60200260200101518760a001518581518110610c9557610c956144a7565b602002602001015151886000015189602001516001612837565b838281518110610cc157610cc16144a7565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff1681525050610d4d84604001518281518110610d0857610d086144a7565b602002602001015185608001518381518110610d2657610d266144a7565b6020026020010151858481518110610d4057610d406144a7565b6020026020010151612882565b848381518110610d5f57610d5f6144a7565b6020026020010151602001858481518110610d7c57610d7c6144a7565b602002602001015160e0018281525082151515158152505050828181518110610da757610da76144a7565b60200260200101516020015115610dca57610dc360018361451e565b9150610dcf565b610ee8565b610e35838281518110610de457610de46144a7565b6020026020010151600001516060015185606001518381518110610e0a57610e0a6144a7565b60200260200101518660a001518481518110610e2857610e286144a7565b602002602001015161225d565b848381518110610e4757610e476144a7565b6020026020010151606001858481518110610e6457610e646144a7565b602002602001015160a0018281525082151515158152505050828181518110610e8f57610e8f6144a7565b602002602001015160a0015186610ea69190614539565b9550610ee884604001518281518110610ec157610ec16144a7565b6020026020010151848381518110610edb57610edb6144a7565b6020026020010151612a01565b80610ef28161454c565b915050610ab8565b508061ffff16600003610f115750505050506112e0565b8351610f1e9060016144d6565b610f2d9060ff1661044c614584565b616b6c610f3b8d6010614584565b5a610f469089614539565b610f509190614494565b610f5a9190614494565b610f649190614494565b9450611b58610f7761ffff8316876145f0565b610f819190614494565b945060008060008060005b87604001515181101561118257868181518110610fab57610fab6144a7565b60200260200101516020015115611170576110078a888381518110610fd257610fd26144a7565b6020026020010151608001518a60a001518481518110610ff457610ff46144a7565b6020026020010151518c60000151612b13565b878281518110611019576110196144a7565b602002602001015160c00181815250506110758989604001518381518110611043576110436144a7565b602002602001015189848151811061105d5761105d6144a7565b60200260200101518b600001518c602001518b612b33565b9093509150611084828561446f565b9350611090838661446f565b94508681815181106110a4576110a46144a7565b6020026020010151606001511515886040015182815181106110c8576110c86144a7565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866110fd919061446f565b8a858151811061110f5761110f6144a7565b602002602001015160a001518b868151811061112d5761112d6144a7565b602002602001015160c001518d60800151878151811061114f5761114f6144a7565b60200260200101516040516111679493929190614604565b60405180910390a35b8061117a8161454c565b915050610f8c565b5050336000908152600b6020526040902080548492506002906111ba9084906201000090046bffffffffffffffffffffffff1661446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160108282829054906101000a90046bffffffffffffffffffffffff16611214919061446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008f600160038110611257576112576144a7565b602002013560001c9050600060088264ffffffffff16901c905087610100015163ffffffff168163ffffffff1611156112d657601280547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff8416021790555b5050505050505050505b5050505050505050565b6112f2612c26565b601f8651111561132e576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff1660000361136b576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451865114158061138a5750611382846003614641565b60ff16865111155b156113c1576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e547001000000000000000000000000000000009091046bffffffffffffffffffffffff169060005b816bffffffffffffffffffffffff1681101561145657611443600e828154811061141a5761141a6144a7565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612ca7565b508061144e8161454c565b9150506113ee565b5060008060005b836bffffffffffffffffffffffff1681101561155f57600d8181548110611486576114866144a7565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff909216945090829081106114c1576114c16144a7565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690559150806115578161454c565b91505061145d565b5061156c600d6000613b92565b611578600e6000613b92565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c518110156119e157600c60008e83815181106115bd576115bd6144a7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611628576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110611652576116526144a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116a7576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f84815181106116d8576116d86144a7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110611780576117806144a7565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117f0576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506118ab576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806119d98161454c565b91505061159e565b50508a516119f79150600d9060208d0190613bb0565b508851611a0b90600e9060208c0190613bb0565b506040518061012001604052808960ff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020016012600001600e9054906101000a900460ff16151581526020016012600001600f9054906101000a900460ff1615158152602001856bffffffffffffffffffffffff168152602001600063ffffffff16815250601260008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160096101000a81548162ffffff021916908362ffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548160ff02191690831515021790555060c082015181600001600f6101000a81548160ff02191690831515021790555060e08201518160000160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601360010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601360010160149054906101000a900463ffffffff1663ffffffff168152602001601360010160189054906101000a900463ffffffff1663ffffffff1681526020016013600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601360008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160168190555086610160015160178190555060006013600101601c9054906101000a900463ffffffff169050611fcd612eb1565b601480547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891612048918591780100000000000000000000000000000000000000000000000090041661466a565b92506101000a81548163ffffffff021916908363ffffffff16021790555060008860405160200161207991906146d8565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526014549091506120e290469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612f66565b60115560005b6120f26009613010565b8110156121225761210f61210760098361301a565b600990613026565b508061211a8161454c565b9150506120e8565b5060005b896101a0015151811015612179576121668a6101a00151828151811061214e5761214e6144a7565b6020026020010151600961304890919063ffffffff16565b50806121718161454c565b915050612126565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601360010160189054906101000a900463ffffffff168f8f8f878f8f6040516121d09998979695949392919061483c565b60405180910390a1505050505050505050505050565b61220786868686806020019051810190612200919061496d565b86866112ea565b505050505050565b612217612c26565b6122208161306a565b50565b321561225b576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081906f01000000000000000000000000000000900460ff16156122b2576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f010000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061231f908590602401613cbd565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906123f29087908790600401614ac7565b60408051808303816000875af1158015612410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124349190614ae0565b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff16905590969095509350505050565b6000878760405161247a929190614b13565b604051908190038120612491918b90602001614b23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612668576001858783602081106124fd576124fd6144a7565b61250a91901a601b6144d6565b8c8c8581811061251c5761251c6144a7565b905060200201358b8b86818110612535576125356144a7565b9050602002013560405160008152602001604052604051612572949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612594573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612642576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b8401935080806126609061454c565b9150506124e0565b50827e010101010101010101010101010101010101010101010101010101010101018416146126c3576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61270a6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061271883850185614c14565b604081015151606082015151919250908114158061273b57508082608001515114155b8061274b5750808260a001515114155b15612782576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b6000818160045b600f811015612819577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106127d1576127d16144a7565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461280757506000949350505050565b806128118161454c565b915050612793565b5081600f1a600181111561282f5761282f6144ef565b949350505050565b60008061284988878b6000015161315f565b90506000806128648b8a63ffffffff16858a8a60018b6131eb565b9092509050612873818361446f565b9b9a5050505050505050505050565b60008080808460800151600181111561289d5761289d6144ef565b036128c1576128ad868686613644565b6128bc5760009250905061079f565b612938565b6001846080015160018111156128d9576128d96144ef565b036129065760006128eb878787613738565b9250905080612900575060009250905061079f565b50612938565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612940612eb1565b84516040015163ffffffff161161299457857fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636866040516129819190613cbd565b60405180910390a260009250905061079f565b83604001516bffffffffffffffffffffffff16846000015160a001516bffffffffffffffffffffffff1610156129f457857f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02866040516129819190613cbd565b6001969095509350505050565b600081608001516001811115612a1957612a196144ef565b03612a8b57612a26612eb1565b6000838152600460205260409020600101805463ffffffff929092167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555050565b600181608001516001811115612aa357612aa36144ef565b03612b0f5760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b5050565b6000612b2084848461315f565b90508085101561282f5750929392505050565b600080612b4e888760a001518860c0015188888860016131eb565b90925090506000612b5f828461446f565b600089815260046020526040902060010180549192508291600c90612ba39084906c0100000000000000000000000090046bffffffffffffffffffffffff16614d01565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a815260046020526040812060010180548594509092612bec9185911661446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161039e565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612ea3576000816060015185612d3f9190614d01565b90506000612d4d8583614d26565b90508083604001818151612d61919061446f565b6bffffffffffffffffffffffff16905250612d7c8582614d51565b83606001818151612d8d919061446f565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b6040015190505b9392505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115612ee757612ee76144ef565b03612f6157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5c9190614d85565b905090565b504390565b6000808a8a8a8a8a8a8a8a8a604051602001612f8a99989796959493929190614d9e565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000612786825490565b6000612eaa83836138c5565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166138ef565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166139e9565b3373ffffffffffffffffffffffffffffffffffffffff8216036130e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161039e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008080856001811115613175576131756144ef565b03613184575062015f906131a3565b6001856001811115613198576131986144ef565b0361290657506201adb05b6131b463ffffffff85166014614584565b6131bf8460016144d6565b6131ce9060ff16611d4c614584565b6131d89083614494565b6131e29190614494565b95945050505050565b6000806000896080015161ffff16876132049190614584565b90508380156132125750803a105b1561321a57503a5b600060027f00000000000000000000000000000000000000000000000000000000000000006002811115613250576132506144ef565b036133af5760408051600081526020810190915285156132ae57600036604051806080016040528060488152602001614fc46048913960405160200161329893929190614e33565b6040516020818303038152906040529050613316565b6015546132ca90640100000000900463ffffffff166004614e5a565b63ffffffff1667ffffffffffffffff8111156132e8576132e8613eea565b6040519080825280601f01601f191660200182016040528015613312576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e90613366908490600401613cbd565b602060405180830381865afa158015613383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a79190614d85565b915050613509565b60017f000000000000000000000000000000000000000000000000000000000000000060028111156133e3576133e36144ef565b0361350957841561346557606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561343a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345e9190614d85565b9050613509565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190614e7d565b50506015549294506134fa93505050640100000000900463ffffffff1682614584565b613505906010614584565b9150505b8461352557808b6080015161ffff166135229190614584565b90505b61353361ffff8716826145f0565b9050600087826135438c8e614494565b61354d9086614584565b6135579190614494565b61356990670de0b6b3a7640000614584565b61357391906145f0565b905060008c6040015163ffffffff1664e8d4a510006135929190614584565b898e6020015163ffffffff16858f886135ab9190614584565b6135b59190614494565b6135c390633b9aca00614584565b6135cd9190614584565b6135d791906145f0565b6135e19190614494565b90506b033b2e3c9fd0803ce80000006135fa8284614494565b1115613632576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000808380602001905181019061365b9190614ec7565b835160c00151815191925063ffffffff908116911610156136b857847f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8856040516136a69190613cbd565b60405180910390a26000915050612eaa565b6020810151158015906136df5750602081015181516136dc9063ffffffff16613a38565b14155b806136f857506136ed612eb1565b815163ffffffff1610155b1561372d57847f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301856040516136a69190613cbd565b506001949350505050565b6000806000848060200190518101906137519190614f1f565b9050600086826000015183602001516040516020016137a893929190928352602083019190915260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016604082015260440190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012060608301519091501580159061380a57508160600151613807836040015163ffffffff16613a38565b14155b806138265750613818612eb1565b826040015163ffffffff1610155b1561387057867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018760405161385b9190613cbd565b60405180910390a260009350915061079f9050565b60008181526008602052604090205460ff16156138b757867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88760405161385b9190613cbd565b600197909650945050505050565b60008260000182815481106138dc576138dc6144a7565b9060005260206000200154905092915050565b600081815260018301602052604081205480156139d8576000613913600183614539565b855490915060009061392790600190614539565b905081811461398c576000866000018281548110613947576139476144a7565b906000526020600020015490508087600001848154811061396a5761396a6144a7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061399d5761399d614f94565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612786565b6000915050612786565b5092915050565b6000818152600183016020526040812054613a3057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612786565b506000612786565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115613a6e57613a6e6144ef565b03613b88576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae59190614d85565b90508083101580613b005750610100613afe8483614539565b115b15613b0e5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015613b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eaa9190614d85565b504090565b919050565b50805460008255906000526020600020908101906122209190613c3a565b828054828255906000526020600020908101928215613c2a579160200282015b82811115613c2a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613bd0565b50613c36929150613c3a565b5090565b5b80821115613c365760008155600101613c3b565b60005b83811015613c6a578181015183820152602001613c52565b50506000910152565b60008151808452613c8b816020860160208601613c4f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612eaa6020830184613c73565b73ffffffffffffffffffffffffffffffffffffffff8116811461222057600080fd5b8035613b8d81613cd0565b60008083601f840112613d0f57600080fd5b50813567ffffffffffffffff811115613d2757600080fd5b602083019150836020828501011115613d3f57600080fd5b9250929050565b60008060008060608587031215613d5c57600080fd5b8435613d6781613cd0565b935060208501359250604085013567ffffffffffffffff811115613d8a57600080fd5b613d9687828801613cfd565b95989497509550505050565b600080600060408486031215613db757600080fd5b83359250602084013567ffffffffffffffff811115613dd557600080fd5b613de186828701613cfd565b9497909650939450505050565b60008083601f840112613e0057600080fd5b50813567ffffffffffffffff811115613e1857600080fd5b6020830191508360208260051b8501011115613d3f57600080fd5b60008060008060008060008060e0898b031215613e4f57600080fd5b606089018a811115613e6057600080fd5b8998503567ffffffffffffffff80821115613e7a57600080fd5b613e868c838d01613cfd565b909950975060808b0135915080821115613e9f57600080fd5b613eab8c838d01613dee565b909750955060a08b0135915080821115613ec457600080fd5b50613ed18b828c01613dee565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613f3d57613f3d613eea565b60405290565b60405160c0810167ffffffffffffffff81118282101715613f3d57613f3d613eea565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613fad57613fad613eea565b604052919050565b600067ffffffffffffffff821115613fcf57613fcf613eea565b5060051b60200190565b600082601f830112613fea57600080fd5b81356020613fff613ffa83613fb5565b613f66565b82815260059290921b8401810191818101908684111561401e57600080fd5b8286015b8481101561404257803561403581613cd0565b8352918301918301614022565b509695505050505050565b803560ff81168114613b8d57600080fd5b63ffffffff8116811461222057600080fd5b8035613b8d8161405e565b62ffffff8116811461222057600080fd5b8035613b8d8161407b565b61ffff8116811461222057600080fd5b8035613b8d81614097565b6bffffffffffffffffffffffff8116811461222057600080fd5b8035613b8d816140b2565b60006101e082840312156140ea57600080fd5b6140f2613f19565b90506140fd82614070565b815261410b60208301614070565b602082015261411c60408301614070565b604082015261412d6060830161408c565b606082015261413e608083016140a7565b608082015261414f60a083016140cc565b60a082015261416060c08301614070565b60c082015261417160e08301614070565b60e0820152610100614184818401614070565b90820152610120614196838201614070565b90820152610140828101359082015261016080830135908201526101806141be818401613cf2565b908201526101a08281013567ffffffffffffffff8111156141de57600080fd5b6141ea85828601613fd9565b8284015250506101c06141fe818401613cf2565b9082015292915050565b803567ffffffffffffffff81168114613b8d57600080fd5b600082601f83011261423157600080fd5b813567ffffffffffffffff81111561424b5761424b613eea565b61427c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613f66565b81815284602083860101111561429157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156142c757600080fd5b863567ffffffffffffffff808211156142df57600080fd5b6142eb8a838b01613fd9565b9750602089013591508082111561430157600080fd5b61430d8a838b01613fd9565b965061431b60408a0161404d565b9550606089013591508082111561433157600080fd5b61433d8a838b016140d7565b945061434b60808a01614208565b935060a089013591508082111561436157600080fd5b5061436e89828a01614220565b9150509295509295509295565b60008060008060008060c0878903121561439457600080fd5b863567ffffffffffffffff808211156143ac57600080fd5b6143b88a838b01613fd9565b975060208901359150808211156143ce57600080fd5b6143da8a838b01613fd9565b96506143e860408a0161404d565b955060608901359150808211156143fe57600080fd5b61433d8a838b01614220565b60006020828403121561441c57600080fd5b8135612eaa81613cd0565b60006020828403121561443957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156139e2576139e2614440565b8082018082111561278657612786614440565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff818116838216019081111561278657612786614440565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156139e2576139e2614440565b8181038181111561278657612786614440565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457d5761457d614440565b5060010190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145bc576145bc614440565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826145ff576145ff6145c1565b500490565b6bffffffffffffffffffffffff851681528360208201528260408201526080606082015260006146376080830184613c73565b9695505050505050565b600060ff821660ff84168160ff048111821515161561466257614662614440565b029392505050565b63ffffffff8181168382160190808211156139e2576139e2614440565b600081518084526020808501945080840160005b838110156146cd57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161469b565b509495945050505050565b602081526146ef60208201835163ffffffff169052565b60006020830151614708604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006147818185018363ffffffff169052565b840151905061012061479a8482018363ffffffff169052565b84015190506101406147b38482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147f68185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506101e06101c08181860152614816610200860184614687565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261486c8184018a614687565b905082810360808401526148808189614687565b905060ff871660a084015282810360c084015261489d8187613c73565b905067ffffffffffffffff851660e08401528281036101008401526148c28185613c73565b9c9b505050505050505050505050565b8051613b8d8161405e565b8051613b8d8161407b565b8051613b8d81614097565b8051613b8d816140b2565b8051613b8d81613cd0565b600082601f83011261491a57600080fd5b8151602061492a613ffa83613fb5565b82815260059290921b8401810191818101908684111561494957600080fd5b8286015b8481101561404257805161496081613cd0565b835291830191830161494d565b60006020828403121561497f57600080fd5b815167ffffffffffffffff8082111561499757600080fd5b908301906101e082860312156149ac57600080fd5b6149b4613f19565b6149bd836148d2565b81526149cb602084016148d2565b60208201526149dc604084016148d2565b60408201526149ed606084016148dd565b60608201526149fe608084016148e8565b6080820152614a0f60a084016148f3565b60a0820152614a2060c084016148d2565b60c0820152614a3160e084016148d2565b60e0820152610100614a448185016148d2565b90820152610120614a568482016148d2565b9082015261014083810151908201526101608084015190820152610180614a7e8185016148fe565b908201526101a08381015183811115614a9657600080fd5b614aa288828701614909565b8284015250506101c09150614ab88284016148fe565b91810191909152949350505050565b82815260406020820152600061282f6040830184613c73565b60008060408385031215614af357600080fd5b82518015158114614b0357600080fd5b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614b4a57600080fd5b81356020614b5a613ffa83613fb5565b82815260059290921b84018101918181019086841115614b7957600080fd5b8286015b848110156140425780358352918301918301614b7d565b600082601f830112614ba557600080fd5b81356020614bb5613ffa83613fb5565b82815260059290921b84018101918181019086841115614bd457600080fd5b8286015b8481101561404257803567ffffffffffffffff811115614bf85760008081fd5b614c068986838b0101614220565b845250918301918301614bd8565b600060208284031215614c2657600080fd5b813567ffffffffffffffff80821115614c3e57600080fd5b9083019060c08286031215614c5257600080fd5b614c5a613f43565b8235815260208301356020820152604083013582811115614c7a57600080fd5b614c8687828601614b39565b604083015250606083013582811115614c9e57600080fd5b614caa87828601614b39565b606083015250608083013582811115614cc257600080fd5b614cce87828601614b94565b60808301525060a083013582811115614ce657600080fd5b614cf287828601614b94565b60a08301525095945050505050565b6bffffffffffffffffffffffff8281168282160390808211156139e2576139e2614440565b60006bffffffffffffffffffffffff80841680614d4557614d456145c1565b92169190910492915050565b60006bffffffffffffffffffffffff80831681851681830481118215151615614d7c57614d7c614440565b02949350505050565b600060208284031215614d9757600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614de58285018b614687565b91508382036080850152614df9828a614687565b915060ff881660a085015283820360c0850152614e168288613c73565b90861660e085015283810361010085015290506148c28185613c73565b828482376000838201600081528351614e50818360208801613c4f565b0195945050505050565b600063ffffffff80831681851681830481118215151615614d7c57614d7c614440565b60008060008060008060c08789031215614e9657600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060408284031215614ed957600080fd5b6040516040810181811067ffffffffffffffff82111715614efc57614efc613eea565b6040528251614f0a8161405e565b81526020928301519281019290925250919050565b600060808284031215614f3157600080fd5b6040516080810181811067ffffffffffffffff82111715614f5457614f54613eea565b604052825181526020830151614f698161405e565b60208201526040830151614f7c8161405e565b60408201526060928301519281019290925250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", + Bin: "0x6101406040523480156200001257600080fd5b50604051620054d0380380620054d08339810160408190526200003591620003df565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000406565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003df565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003df565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003df565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003df565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b9816200031b565b505050846002811115620002d157620002d162000429565b60e0816002811115620002e857620002e862000429565b9052506001600160a01b0393841660805291831660a052821660c0528116610100529190911661012052506200043f9050565b336001600160a01b03821603620003755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003dc57600080fd5b50565b600060208284031215620003f257600080fd5b8151620003ff81620003c6565b9392505050565b6000602082840312156200041957600080fd5b815160038110620003ff57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e051610100516101205161502f620004a16000396000818160d6015261016f01526000505060008181612eb701528181613220015281816133b30152613a4901526000505060005050600061043b015261502f6000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e29b753c1161005b578063e29b753c146102e8578063e3d0e712146102fb578063f2fde38b1461030e576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102d5576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601481526020017f4b6565706572526567697374727920322e312e3000000000000000000000000081525081565b6040516101649190613cc8565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610321565b61020e60145460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613d51565b610423565b610275610270366004613dad565b61063f565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102e3366004613e3e565b6107a7565b6101196102f63660046142b9565b6112ea565b610119610309366004614386565b6121e6565b61011961031c366004614415565b61220f565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610492576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104cc576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104da82840184614432565b60008181526004602052604090205490915065010000000000900463ffffffff90811614610534576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461056f9085906c0100000000000000000000000090046bffffffffffffffffffffffff1661447a565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556018546105da90859061449f565b6018556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b60008061064a612223565b6012546e010000000000000000000000000000900460ff1615610699576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f8901859004850281018501909552878552909361079893899089908190840183828082843760009201919091525061225d92505050565b9093509150505b935093915050565b60005a604080516101208101825260125460ff808216835261010080830463ffffffff90811660208601526501000000000084048116958501959095526901000000000000000000830462ffffff1660608501526c01000000000000000000000000830461ffff1660808501526e0100000000000000000000000000008304821615801560a08601526f010000000000000000000000000000008404909216151560c085015270010000000000000000000000000000000083046bffffffffffffffffffffffff1660e08501527c0100000000000000000000000000000000000000000000000000000000909204909316908201529192506108d5576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff1661091e576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a351461095a576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516109679060016144e1565b60ff16861415806109785750858414155b156109af576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109bf8a8a8a8a8a8a8a8a612468565b60006109cb8a8a6126d1565b9050600081604001515167ffffffffffffffff8111156109ed576109ed613ef5565b604051908082528060200260200182016040528015610ab157816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610a0b5790505b5090506000805b836040015151811015610efa576004600085604001518381518110610adf57610adf6144b2565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201528351849083908110610bc457610bc46144b2565b602002602001015160000181905250610bf984604001518281518110610bec57610bec6144b2565b602002602001015161278c565b838281518110610c0b57610c0b6144b2565b6020026020010151608001906001811115610c2857610c286144fa565b90816001811115610c3b57610c3b6144fa565b81525050610caf85848381518110610c5557610c556144b2565b60200260200101516080015186606001518481518110610c7757610c776144b2565b60200260200101518760a001518581518110610c9557610c956144b2565b602002602001015151886000015189602001516001612837565b838281518110610cc157610cc16144b2565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff1681525050610d4d84604001518281518110610d0857610d086144b2565b602002602001015185608001518381518110610d2657610d266144b2565b6020026020010151858481518110610d4057610d406144b2565b6020026020010151612882565b848381518110610d5f57610d5f6144b2565b6020026020010151602001858481518110610d7c57610d7c6144b2565b602002602001015160e0018281525082151515158152505050828181518110610da757610da76144b2565b60200260200101516020015115610dca57610dc3600183614529565b9150610dcf565b610ee8565b610e35838281518110610de457610de46144b2565b6020026020010151600001516060015185606001518381518110610e0a57610e0a6144b2565b60200260200101518660a001518481518110610e2857610e286144b2565b602002602001015161225d565b848381518110610e4757610e476144b2565b6020026020010151606001858481518110610e6457610e646144b2565b602002602001015160a0018281525082151515158152505050828181518110610e8f57610e8f6144b2565b602002602001015160a0015186610ea69190614544565b9550610ee884604001518281518110610ec157610ec16144b2565b6020026020010151848381518110610edb57610edb6144b2565b6020026020010151612a01565b80610ef281614557565b915050610ab8565b508061ffff16600003610f115750505050506112e0565b8351610f1e9060016144e1565b610f2d9060ff1661044c61458f565b616b6c610f3b8d601061458f565b5a610f469089614544565b610f50919061449f565b610f5a919061449f565b610f64919061449f565b9450611b58610f7761ffff8316876145fb565b610f81919061449f565b945060008060008060005b87604001515181101561118257868181518110610fab57610fab6144b2565b60200260200101516020015115611170576110078a888381518110610fd257610fd26144b2565b6020026020010151608001518a60a001518481518110610ff457610ff46144b2565b6020026020010151518c60000151612b13565b878281518110611019576110196144b2565b602002602001015160c00181815250506110758989604001518381518110611043576110436144b2565b602002602001015189848151811061105d5761105d6144b2565b60200260200101518b600001518c602001518b612b33565b9093509150611084828561447a565b9350611090838661447a565b94508681815181106110a4576110a46144b2565b6020026020010151606001511515886040015182815181106110c8576110c86144b2565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866110fd919061447a565b8a858151811061110f5761110f6144b2565b602002602001015160a001518b868151811061112d5761112d6144b2565b602002602001015160c001518d60800151878151811061114f5761114f6144b2565b6020026020010151604051611167949392919061460f565b60405180910390a35b8061117a81614557565b915050610f8c565b5050336000908152600b6020526040902080548492506002906111ba9084906201000090046bffffffffffffffffffffffff1661447a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160108282829054906101000a90046bffffffffffffffffffffffff16611214919061447a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008f600160038110611257576112576144b2565b602002013560001c9050600060088264ffffffffff16901c905087610100015163ffffffff168163ffffffff1611156112d657601280547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff8416021790555b5050505050505050505b5050505050505050565b6112f2612c26565b601f8651111561132e576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff1660000361136b576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451865114158061138a575061138284600361464c565b60ff16865111155b156113c1576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e547001000000000000000000000000000000009091046bffffffffffffffffffffffff169060005b816bffffffffffffffffffffffff1681101561145657611443600e828154811061141a5761141a6144b2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612ca7565b508061144e81614557565b9150506113ee565b5060008060005b836bffffffffffffffffffffffff1681101561155f57600d8181548110611486576114866144b2565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff909216945090829081106114c1576114c16144b2565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591508061155781614557565b91505061145d565b5061156c600d6000613b9d565b611578600e6000613b9d565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c518110156119e157600c60008e83815181106115bd576115bd6144b2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611628576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110611652576116526144b2565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116a7576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f84815181106116d8576116d86144b2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110611780576117806144b2565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117f0576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506118ab576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806119d981614557565b91505061159e565b50508a516119f79150600d9060208d0190613bbb565b508851611a0b90600e9060208c0190613bbb565b506040518061012001604052808960ff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020016012600001600e9054906101000a900460ff16151581526020016012600001600f9054906101000a900460ff1615158152602001856bffffffffffffffffffffffff168152602001600063ffffffff16815250601260008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160096101000a81548162ffffff021916908362ffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548160ff02191690831515021790555060c082015181600001600f6101000a81548160ff02191690831515021790555060e08201518160000160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601360010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601360010160149054906101000a900463ffffffff1663ffffffff168152602001601360010160189054906101000a900463ffffffff1663ffffffff1681526020016013600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601360008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160168190555086610160015160178190555060006013600101601c9054906101000a900463ffffffff169050611fcd612eb1565b601480547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff93841602178082556001926018916120489185917801000000000000000000000000000000000000000000000000900416614675565b92506101000a81548163ffffffff021916908363ffffffff16021790555060008860405160200161207991906146e3565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526014549091506120e290469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612f66565b60115560005b6120f26009613010565b8110156121225761210f61210760098361301a565b600990613026565b508061211a81614557565b9150506120e8565b5060005b896101a0015151811015612179576121668a6101a00151828151811061214e5761214e6144b2565b6020026020010151600961304890919063ffffffff16565b508061217181614557565b915050612126565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601360010160189054906101000a900463ffffffff168f8f8f878f8f6040516121d099989796959493929190614847565b60405180910390a1505050505050505050505050565b612207868686868060200190518101906122009190614978565b86866112ea565b505050505050565b612217612c26565b6122208161306a565b50565b321561225b576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081906f01000000000000000000000000000000900460ff16156122b2576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f010000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061231f908590602401613cc8565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906123f29087908790600401614ad2565b60408051808303816000875af1158015612410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124349190614aeb565b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff16905590969095509350505050565b6000878760405161247a929190614b1e565b604051908190038120612491918b90602001614b2e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612668576001858783602081106124fd576124fd6144b2565b61250a91901a601b6144e1565b8c8c8581811061251c5761251c6144b2565b905060200201358b8b86818110612535576125356144b2565b9050602002013560405160008152602001604052604051612572949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612594573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612642576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061266090614557565b9150506124e0565b50827e010101010101010101010101010101010101010101010101010101010101018416146126c3576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61270a6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061271883850185614c1f565b604081015151606082015151919250908114158061273b57508082608001515114155b8061274b5750808260a001515114155b15612782576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b6000818160045b600f811015612819577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106127d1576127d16144b2565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461280757506000949350505050565b8061281181614557565b915050612793565b5081600f1a600181111561282f5761282f6144fa565b949350505050565b60008061284988878b6000015161315f565b90506000806128648b8a63ffffffff16858a8a60018b6131eb565b9092509050612873818361447a565b9b9a5050505050505050505050565b60008080808460800151600181111561289d5761289d6144fa565b036128c1576128ad868686613644565b6128bc5760009250905061079f565b612938565b6001846080015160018111156128d9576128d96144fa565b036129065760006128eb878787613738565b9250905080612900575060009250905061079f565b50612938565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612940612eb1565b84516040015163ffffffff161161299457857fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636866040516129819190613cc8565b60405180910390a260009250905061079f565b83604001516bffffffffffffffffffffffff16846000015160a001516bffffffffffffffffffffffff1610156129f457857f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02866040516129819190613cc8565b6001969095509350505050565b600081608001516001811115612a1957612a196144fa565b03612a8b57612a26612eb1565b6000838152600460205260409020600101805463ffffffff929092167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555050565b600181608001516001811115612aa357612aa36144fa565b03612b0f5760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b5050565b6000612b2084848461315f565b90508085101561282f5750929392505050565b600080612b4e888760a001518860c0015188888860016131eb565b90925090506000612b5f828461447a565b600089815260046020526040902060010180549192508291600c90612ba39084906c0100000000000000000000000090046bffffffffffffffffffffffff16614d0c565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a815260046020526040812060010180548594509092612bec9185911661447a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161039e565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612ea3576000816060015185612d3f9190614d0c565b90506000612d4d8583614d31565b90508083604001818151612d61919061447a565b6bffffffffffffffffffffffff16905250612d7c8582614d5c565b83606001818151612d8d919061447a565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b6040015190505b9392505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115612ee757612ee76144fa565b03612f6157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5c9190614d90565b905090565b504390565b6000808a8a8a8a8a8a8a8a8a604051602001612f8a99989796959493929190614da9565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000612786825490565b6000612eaa83836138d0565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166138fa565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166139f4565b3373ffffffffffffffffffffffffffffffffffffffff8216036130e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161039e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008080856001811115613175576131756144fa565b03613184575062015f906131a3565b6001856001811115613198576131986144fa565b0361290657506201adb05b6131b463ffffffff8516601461458f565b6131bf8460016144e1565b6131ce9060ff16611d4c61458f565b6131d8908361449f565b6131e2919061449f565b95945050505050565b6000806000896080015161ffff1687613204919061458f565b90508380156132125750803a105b1561321a57503a5b600060027f00000000000000000000000000000000000000000000000000000000000000006002811115613250576132506144fa565b036133af5760408051600081526020810190915285156132ae57600036604051806080016040528060488152602001614fdb6048913960405160200161329893929190614e3e565b6040516020818303038152906040529050613316565b6015546132ca90640100000000900463ffffffff166004614e65565b63ffffffff1667ffffffffffffffff8111156132e8576132e8613ef5565b6040519080825280601f01601f191660200182016040528015613312576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e90613366908490600401613cc8565b602060405180830381865afa158015613383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a79190614d90565b915050613509565b60017f000000000000000000000000000000000000000000000000000000000000000060028111156133e3576133e36144fa565b0361350957841561346557606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561343a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345e9190614d90565b9050613509565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190614e88565b50506015549294506134fa93505050640100000000900463ffffffff168261458f565b61350590601061458f565b9150505b8461352557808b6080015161ffff16613522919061458f565b90505b61353361ffff8716826145fb565b9050600087826135438c8e61449f565b61354d908661458f565b613557919061449f565b61356990670de0b6b3a764000061458f565b61357391906145fb565b905060008c6040015163ffffffff1664e8d4a51000613592919061458f565b898e6020015163ffffffff16858f886135ab919061458f565b6135b5919061449f565b6135c390633b9aca0061458f565b6135cd919061458f565b6135d791906145fb565b6135e1919061449f565b90506b033b2e3c9fd0803ce80000006135fa828461449f565b1115613632576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000808380602001905181019061365b9190614ed2565b835160c00151815191925063ffffffff908116911610156136b857847f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8856040516136a69190613cc8565b60405180910390a26000915050612eaa565b6020810151158015906136df5750602081015181516136dc9063ffffffff16613a43565b14155b806136f857506136ed612eb1565b815163ffffffff1610155b1561372d57847f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301856040516136a69190613cc8565b506001949350505050565b6000806000848060200190518101906137519190614f2a565b90506000868260000151836020015184604001516040516020016137b394939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012060808301519091501580159061381557508160800151613812836060015163ffffffff16613a43565b14155b806138315750613823612eb1565b826060015163ffffffff1610155b1561387b57867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516138669190613cc8565b60405180910390a260009350915061079f9050565b60008181526008602052604090205460ff16156138c257867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516138669190613cc8565b600197909650945050505050565b60008260000182815481106138e7576138e76144b2565b9060005260206000200154905092915050565b600081815260018301602052604081205480156139e357600061391e600183614544565b855490915060009061393290600190614544565b9050818114613997576000866000018281548110613952576139526144b2565b9060005260206000200154905080876000018481548110613975576139756144b2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806139a8576139a8614fab565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612786565b6000915050612786565b5092915050565b6000818152600183016020526040812054613a3b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612786565b506000612786565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115613a7957613a796144fa565b03613b93576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af09190614d90565b90508083101580613b0b5750610100613b098483614544565b115b15613b195750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015613b6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eaa9190614d90565b504090565b919050565b50805460008255906000526020600020908101906122209190613c45565b828054828255906000526020600020908101928215613c35579160200282015b82811115613c3557825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613bdb565b50613c41929150613c45565b5090565b5b80821115613c415760008155600101613c46565b60005b83811015613c75578181015183820152602001613c5d565b50506000910152565b60008151808452613c96816020860160208601613c5a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612eaa6020830184613c7e565b73ffffffffffffffffffffffffffffffffffffffff8116811461222057600080fd5b8035613b9881613cdb565b60008083601f840112613d1a57600080fd5b50813567ffffffffffffffff811115613d3257600080fd5b602083019150836020828501011115613d4a57600080fd5b9250929050565b60008060008060608587031215613d6757600080fd5b8435613d7281613cdb565b935060208501359250604085013567ffffffffffffffff811115613d9557600080fd5b613da187828801613d08565b95989497509550505050565b600080600060408486031215613dc257600080fd5b83359250602084013567ffffffffffffffff811115613de057600080fd5b613dec86828701613d08565b9497909650939450505050565b60008083601f840112613e0b57600080fd5b50813567ffffffffffffffff811115613e2357600080fd5b6020830191508360208260051b8501011115613d4a57600080fd5b60008060008060008060008060e0898b031215613e5a57600080fd5b606089018a811115613e6b57600080fd5b8998503567ffffffffffffffff80821115613e8557600080fd5b613e918c838d01613d08565b909950975060808b0135915080821115613eaa57600080fd5b613eb68c838d01613df9565b909750955060a08b0135915080821115613ecf57600080fd5b50613edc8b828c01613df9565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613f4857613f48613ef5565b60405290565b60405160c0810167ffffffffffffffff81118282101715613f4857613f48613ef5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613fb857613fb8613ef5565b604052919050565b600067ffffffffffffffff821115613fda57613fda613ef5565b5060051b60200190565b600082601f830112613ff557600080fd5b8135602061400a61400583613fc0565b613f71565b82815260059290921b8401810191818101908684111561402957600080fd5b8286015b8481101561404d57803561404081613cdb565b835291830191830161402d565b509695505050505050565b803560ff81168114613b9857600080fd5b63ffffffff8116811461222057600080fd5b8035613b9881614069565b62ffffff8116811461222057600080fd5b8035613b9881614086565b61ffff8116811461222057600080fd5b8035613b98816140a2565b6bffffffffffffffffffffffff8116811461222057600080fd5b8035613b98816140bd565b60006101e082840312156140f557600080fd5b6140fd613f24565b90506141088261407b565b81526141166020830161407b565b60208201526141276040830161407b565b604082015261413860608301614097565b6060820152614149608083016140b2565b608082015261415a60a083016140d7565b60a082015261416b60c0830161407b565b60c082015261417c60e0830161407b565b60e082015261010061418f81840161407b565b908201526101206141a183820161407b565b90820152610140828101359082015261016080830135908201526101806141c9818401613cfd565b908201526101a08281013567ffffffffffffffff8111156141e957600080fd5b6141f585828601613fe4565b8284015250506101c0614209818401613cfd565b9082015292915050565b803567ffffffffffffffff81168114613b9857600080fd5b600082601f83011261423c57600080fd5b813567ffffffffffffffff81111561425657614256613ef5565b61428760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613f71565b81815284602083860101111561429c57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156142d257600080fd5b863567ffffffffffffffff808211156142ea57600080fd5b6142f68a838b01613fe4565b9750602089013591508082111561430c57600080fd5b6143188a838b01613fe4565b965061432660408a01614058565b9550606089013591508082111561433c57600080fd5b6143488a838b016140e2565b945061435660808a01614213565b935060a089013591508082111561436c57600080fd5b5061437989828a0161422b565b9150509295509295509295565b60008060008060008060c0878903121561439f57600080fd5b863567ffffffffffffffff808211156143b757600080fd5b6143c38a838b01613fe4565b975060208901359150808211156143d957600080fd5b6143e58a838b01613fe4565b96506143f360408a01614058565b9550606089013591508082111561440957600080fd5b6143488a838b0161422b565b60006020828403121561442757600080fd5b8135612eaa81613cdb565b60006020828403121561444457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156139ed576139ed61444b565b808201808211156127865761278661444b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff81811683821601908111156127865761278661444b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156139ed576139ed61444b565b818103818111156127865761278661444b565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145885761458861444b565b5060010190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145c7576145c761444b565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261460a5761460a6145cc565b500490565b6bffffffffffffffffffffffff851681528360208201528260408201526080606082015260006146426080830184613c7e565b9695505050505050565b600060ff821660ff84168160ff048111821515161561466d5761466d61444b565b029392505050565b63ffffffff8181168382160190808211156139ed576139ed61444b565b600081518084526020808501945080840160005b838110156146d857815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016146a6565b509495945050505050565b602081526146fa60208201835163ffffffff169052565b60006020830151614713604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e083015161010061478c8185018363ffffffff169052565b84015190506101206147a58482018363ffffffff169052565b84015190506101406147be8482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06148018185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506101e06101c08181860152614821610200860184614692565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526148778184018a614692565b9050828103608084015261488b8189614692565b905060ff871660a084015282810360c08401526148a88187613c7e565b905067ffffffffffffffff851660e08401528281036101008401526148cd8185613c7e565b9c9b505050505050505050505050565b8051613b9881614069565b8051613b9881614086565b8051613b98816140a2565b8051613b98816140bd565b8051613b9881613cdb565b600082601f83011261492557600080fd5b8151602061493561400583613fc0565b82815260059290921b8401810191818101908684111561495457600080fd5b8286015b8481101561404d57805161496b81613cdb565b8352918301918301614958565b60006020828403121561498a57600080fd5b815167ffffffffffffffff808211156149a257600080fd5b908301906101e082860312156149b757600080fd5b6149bf613f24565b6149c8836148dd565b81526149d6602084016148dd565b60208201526149e7604084016148dd565b60408201526149f8606084016148e8565b6060820152614a09608084016148f3565b6080820152614a1a60a084016148fe565b60a0820152614a2b60c084016148dd565b60c0820152614a3c60e084016148dd565b60e0820152610100614a4f8185016148dd565b90820152610120614a618482016148dd565b9082015261014083810151908201526101608084015190820152610180614a89818501614909565b908201526101a08381015183811115614aa157600080fd5b614aad88828701614914565b8284015250506101c09150614ac3828401614909565b91810191909152949350505050565b82815260406020820152600061282f6040830184613c7e565b60008060408385031215614afe57600080fd5b82518015158114614b0e57600080fd5b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614b5557600080fd5b81356020614b6561400583613fc0565b82815260059290921b84018101918181019086841115614b8457600080fd5b8286015b8481101561404d5780358352918301918301614b88565b600082601f830112614bb057600080fd5b81356020614bc061400583613fc0565b82815260059290921b84018101918181019086841115614bdf57600080fd5b8286015b8481101561404d57803567ffffffffffffffff811115614c035760008081fd5b614c118986838b010161422b565b845250918301918301614be3565b600060208284031215614c3157600080fd5b813567ffffffffffffffff80821115614c4957600080fd5b9083019060c08286031215614c5d57600080fd5b614c65613f4e565b8235815260208301356020820152604083013582811115614c8557600080fd5b614c9187828601614b44565b604083015250606083013582811115614ca957600080fd5b614cb587828601614b44565b606083015250608083013582811115614ccd57600080fd5b614cd987828601614b9f565b60808301525060a083013582811115614cf157600080fd5b614cfd87828601614b9f565b60a08301525095945050505050565b6bffffffffffffffffffffffff8281168282160390808211156139ed576139ed61444b565b60006bffffffffffffffffffffffff80841680614d5057614d506145cc565b92169190910492915050565b60006bffffffffffffffffffffffff80831681851681830481118215151615614d8757614d8761444b565b02949350505050565b600060208284031215614da257600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614df08285018b614692565b91508382036080850152614e04828a614692565b915060ff881660a085015283820360c0850152614e218288613c7e565b90861660e085015283810361010085015290506148cd8185613c7e565b828482376000838201600081528351614e5b818360208801613c5a565b0195945050505050565b600063ffffffff80831681851681830481118215151615614d8757614d8761444b565b60008060008060008060c08789031215614ea157600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060408284031215614ee457600080fd5b6040516040810181811067ffffffffffffffff82111715614f0757614f07613ef5565b6040528251614f1581614069565b81526020928301519281019290925250919050565b600060a08284031215614f3c57600080fd5b60405160a0810181811067ffffffffffffffff82111715614f5f57614f5f613ef5565b806040525082518152602083015160208201526040830151614f8081614069565b60408201526060830151614f9381614069565b60608201526080928301519281019290925250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", } var KeeperRegistryABI = KeeperRegistryMetaData.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 90f5219cb7a..97b336b1885 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 @@ -6,7 +6,7 @@ authorized_receiver: ../../contracts/solc/v0.7/AuthorizedReceiver.abi ../../cont automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 -automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1.bin 0b3006a2a1588916d22bf1ae5429bd3bce24a58904588d5ed3fe1026d64616cf +automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1.bin f7e675941621528e03fab1487e38a2d9ecef94694035fb51c1bc16561f3d2cea batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore.bin c5ab26709a01050402615659403f32d5cd1b85f3ad6bb6bfe021692f4233cf19 batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.bin d0a54963260d8c1f1bbd984b758285e6027cfb5a7e42701bcb562ab123219332 batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.bin 7bb76ae241cf1b37b41920830b836cb99f1ad33efd7435ca2398ff6cd2fe5d48 @@ -36,7 +36,7 @@ keeper_registry_wrapper1_1_mock: ../../contracts/solc/v0.7/KeeperRegistry1_1Mock keeper_registry_wrapper1_2: ../../contracts/solc/v0.8.6/KeeperRegistry1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_2.bin c08f903e7ecbdf89bbfea32c6dd334d3bf908ac809ebf63545890798a5f7a4a7 keeper_registry_wrapper1_3: ../../contracts/solc/v0.8.6/KeeperRegistry1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_3.bin 5e1414eacbc1880b7349a4f253b7eca176f7f6300ef3cd834c493ce795a17e25 keeper_registry_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistry2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistry2_0.bin c32dea7d5ef66b7c58ddc84ddf69aa44df1b3ae8601fbc271c95be4ff5853056 -keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin 6406f37de79d3d2efa86fb961e1462b62a5a2fff4aeb408bbdb4bc7272d91638 +keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin 604e4a0cd980c713929b523b999462a3aa0ed06f96ff563a4c8566cf59c8445b keepers_vrf_consumer: ../../contracts/solc/v0.8.6/KeepersVRFConsumer.abi ../../contracts/solc/v0.8.6/KeepersVRFConsumer.bin fa75572e689c9e84705c63e8dbe1b7b8aa1a8fe82d66356c4873d024bb9166e8 log_emitter: ../../contracts/solc/v0.8.19/LogEmitter.abi ../../contracts/solc/v0.8.19/LogEmitter.bin 244ba13730c036de0b02beef4e3d9c9a96946ce353c27f366baecc7f5be5a6fd log_triggered_feed_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup.bin b3c01ce82842c6be4aceba218c78c1e4958803eab3abe5b0cdbe6fb0464c4a5a diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 05c80a63dbc..7131bb1d437 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,7 +19,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.20 + github.com/smartcontractkit/ocr2keepers v0.7.21 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/spf13/cobra v1.6.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 61b13f05a10..641adcd89eb 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.20 h1:1FOeJ0p4mWHqJiX01v/J2S1C1LhU8iqJM1hDcD38aZU= -github.com/smartcontractkit/ocr2keepers v0.7.20/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.21 h1:64CNFoUYVpoJqhQ39WTPIEKVKB5Z/wderX0pIsv/tbA= +github.com/smartcontractkit/ocr2keepers v0.7.21/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go index f7b245ffce0..1ca280c0d2d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go @@ -40,11 +40,12 @@ func TestWorkID(t *testing.T) { BlockNumber: 123, BlockHash: common.HexToHash("0xabcdef"), LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ - Index: 1, - TxHash: common.HexToHash("0x12345"), + Index: 1, + TxHash: common.HexToHash("0x12345"), + BlockHash: common.HexToHash("0xabcdef"), }, }, - expected: "db0e245ff4e7551d6c862d9a0eb5466624e1439ad1db262a7a3d6137d892d0a3", + expected: "aaa208331dfafff7a681e3358d082a2e78633dd05c8fb2817c391888cadb2912", }, { name: "happy path example from an actual tx", @@ -53,11 +54,12 @@ func TestWorkID(t *testing.T) { BlockNumber: 39344455, BlockHash: common.HexToHash("0xb41258d18cd44ebf7a0d70de011f2bc4a67c9b68e8b6dada864045d8543bb020"), LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ - Index: 41, - TxHash: common.HexToHash("0x44079b1b33aff337dbf17b9e12c5724ecab979c50c8201a9814a488ff3e22384"), + Index: 41, + TxHash: common.HexToHash("0x44079b1b33aff337dbf17b9e12c5724ecab979c50c8201a9814a488ff3e22384"), + BlockHash: common.HexToHash("0xb41258d18cd44ebf7a0d70de011f2bc4a67c9b68e8b6dada864045d8543bb020"), }, }, - expected: "cdb4cfd9b4855b28d243d099c41b832da6b2d99dda3e7d09b900899afd09328f", + expected: "ef1b6acac8aa3682a8a08f666a13cfa165f7e811a16ea9fa0817f437fc4d110d", }, { name: "empty upkeepID", @@ -124,7 +126,7 @@ func TestNewUpkeepPayload(t *testing.T) { }, }, check: []byte("check-data-111"), - workID: "d2fc1c0d626b480a4180f30b89142ae727c85e0b4dc0a82645bcef8062ff932a", + workID: "d8e7c8907a0b60b637ce71ff4f757edf076e270d52c51f6e4d46a3b0696e0a39", }, } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go index 9999aefbd25..ea0c4a31f37 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go @@ -41,10 +41,11 @@ func PackTrigger(id *big.Int, trig triggerWrapper) ([]byte, error) { trigger, err = utilsABI.Pack("_conditionalTrigger", &trig) case ocr2keepers.LogTrigger: logTrig := automation_utils_2_1.KeeperRegistryBase21LogTrigger{ - BlockNum: trig.BlockNum, - BlockHash: trig.BlockHash, - LogIndex: trig.LogIndex, - TxHash: trig.TxHash, + BlockNum: trig.BlockNum, + BlockHash: trig.BlockHash, + LogBlockHash: trig.LogBlockHash, + LogIndex: trig.LogIndex, + TxHash: trig.TxHash, } trigger, err = utilsABI.Pack("_logTrigger", &logTrig) default: @@ -98,6 +99,7 @@ func UnpackTrigger(id *big.Int, raw []byte) (triggerWrapper, error) { } copy(triggerW.BlockHash[:], converted.BlockHash[:]) copy(triggerW.TxHash[:], converted.TxHash[:]) + copy(triggerW.LogBlockHash[:], converted.LogBlockHash[:]) return triggerW, nil default: return triggerWrapper{}, fmt.Errorf("unknown trigger type: %d", upkeepType) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go index 5fa5ae5c910..0233e40679d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go @@ -23,13 +23,14 @@ func TestPackUnpackTrigger(t *testing.T) { "happy flow log trigger", append([]byte{1}, common.LeftPadBytes([]byte{1}, 15)...), triggerWrapper{ - BlockNum: 1, - BlockHash: common.HexToHash("0x01111111"), - LogIndex: 1, - TxHash: common.HexToHash("0x01111111"), + BlockNum: 1, + BlockHash: common.HexToHash("0x01111111"), + LogIndex: 1, + TxHash: common.HexToHash("0x01111111"), + LogBlockHash: common.HexToHash("0x01111abc"), }, func() []byte { - b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") return b }(), nil, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go index 62a359a7231..f68289044ec 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go @@ -68,6 +68,7 @@ func (e reportEncoder) Encode(results ...ocr2keepers.CheckResult) ([]byte, error case ocr2keepers.LogTrigger: triggerW.TxHash = result.Trigger.LogTriggerExtension.TxHash triggerW.LogIndex = result.Trigger.LogTriggerExtension.Index + triggerW.LogBlockHash = result.Trigger.LogTriggerExtension.BlockHash default: // no special handling here for conditional triggers } @@ -110,6 +111,7 @@ func (e reportEncoder) Extract(raw []byte) ([]ocr2keepers.ReportedUpkeep, error) trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{} trigger.LogTriggerExtension.TxHash = triggerW.TxHash trigger.LogTriggerExtension.Index = triggerW.LogIndex + trigger.LogTriggerExtension.BlockHash = triggerW.LogBlockHash default: } workID := core.UpkeepWorkID(*id, trigger) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go index a7fe7f536b1..36435a93bab 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go @@ -37,7 +37,7 @@ func TestReportEncoder_EncodeExtract(t *testing.T) { []ocr2keepers.CheckResult{ newResult(1, 1, core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), 1, 1), }, - 704, + 736, 1, 1, nil, @@ -49,7 +49,7 @@ func TestReportEncoder_EncodeExtract(t *testing.T) { newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "20"), 1, 1), newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "30"), 1, 1), }, - 1280, + 1312, 3, 3, nil, @@ -61,7 +61,7 @@ func TestReportEncoder_EncodeExtract(t *testing.T) { newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "20"), 1, 1), newResult(1, 1, core.GenUpkeepID(ocr2keepers.LogTrigger, "10"), 1, 1), }, - 1280, + 1312, 1000, 2000, nil, @@ -110,8 +110,9 @@ func newResult(block int64, checkBlock ocr2keepers.BlockNumber, id ocr2keepers.U if tp == ocr2keepers.LogTrigger { trig.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{ - Index: 1, - TxHash: common.HexToHash("0x1234567890123456789012345678901234567890123456789012345678901234"), + Index: 1, + TxHash: common.HexToHash("0x1234567890123456789012345678901234567890123456789012345678901234"), + BlockHash: common.HexToHash("0xaaaaaaaa90123456789012345678901234567890123456789012345678901234"), } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go index e0c31f2beea..9774ef4d968 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go @@ -30,6 +30,7 @@ const ( UpkeepFailureReasonTxHashNoLongerExists UpkeepFailureReason = 33 UpkeepFailureReasonInvalidRevertDataInput UpkeepFailureReason = 34 UpkeepFailureReasonSimulationFailed UpkeepFailureReason = 35 + UpkeepFailureReasonTxHashReorged UpkeepFailureReason = 36 // pipeline execution error NoPipelineError PipelineExecutionState = 0 diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go index 1835ac69f09..b06a3ca809f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go @@ -99,7 +99,7 @@ func (b fetchedBlock) has(id *big.Int, log logpoller.Log) (bool, int) { continue } upkeepLogs++ - if l.log.BlockNumber == log.BlockNumber && l.log.TxHash == log.TxHash && l.log.LogIndex == log.LogIndex { + if l.log.BlockHash == log.BlockHash && l.log.TxHash == log.TxHash && l.log.LogIndex == log.LogIndex { return true, upkeepLogs } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go index 0f389d0d418..5c8908f9be7 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go @@ -658,10 +658,10 @@ func TestLogEventBuffer_FetchedBlock_Sort(t *testing.T) { }, }, beforeSort: []string{ - "000000000000000000000000000000000000000000000000000000000000000100000000", + "0000000000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000000100000000", }, afterSort: []string{ - "000000000000000000000000000000000000000000000000000000000000000100000000", + "0000000000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000000100000000", }, }, { @@ -742,24 +742,24 @@ func TestLogEventBuffer_FetchedBlock_Sort(t *testing.T) { }, }, beforeSort: []string{ - "00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001", }, afterSort: []string{ - "00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004", - "00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004", + "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005", }, iterations: 10, }, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go index c4e8d7e0da2..363f06ffa5d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go @@ -28,7 +28,7 @@ func (p *logEventsPacker) PackLogData(log logpoller.Log) ([]byte, error) { } b, err := p.abi.Pack("_log", &automation_utils_2_1.Log{ Index: big.NewInt(log.LogIndex), - TxIndex: big.NewInt(0), // TODO: Add this to the logpoller + TxIndex: big.NewInt(0), // Exploratory: Add this to the logpoller and pass correct value TxHash: log.TxHash, BlockNumber: big.NewInt(log.BlockNumber), BlockHash: log.BlockHash, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go index dbed9c591cd..31de875d021 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -185,26 +185,30 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2 if proposal.Trigger.LogTriggerExtension == nil { return nil, errors.New("missing log trigger extension") } - logBlock := int64(proposal.Trigger.LogTriggerExtension.BlockNumber) - if logBlock == 0 { - var number *big.Int - number, _, err = core.GetTxBlock(ctx, r.client, proposal.Trigger.LogTriggerExtension.TxHash) - if err != nil { - return nil, err - } - if number == nil { - return nil, errors.New("failed to get tx block") - } - logBlock = number.Int64() + + // Verify the log is still present on chain, not reorged and is within recoverable range + // Do not trust the logBlockNumber from proposal since it's not included in workID + logBlockHash := common.BytesToHash(proposal.Trigger.LogTriggerExtension.BlockHash[:]) + bn, bh, err := core.GetTxBlock(ctx, r.client, proposal.Trigger.LogTriggerExtension.TxHash) + if err != nil { + return nil, err + } + if bn == nil { + return nil, errors.New("failed to get tx block") + } + if bh.Hex() != logBlockHash.Hex() { + return nil, errors.New("log tx reorged") } + logBlock := bn.Int64() if isRecoverable := logBlock < offsetBlock && logBlock > start; !isRecoverable { return nil, errors.New("log block is not recoverable") } + + // Check if the log was already performed or ineligible upkeepStates, err := r.states.SelectByWorkIDs(ctx, proposal.WorkID) if err != nil { return nil, err } - for _, upkeepState := range upkeepStates { switch upkeepState { case ocr2keepers.Performed, ocr2keepers.Ineligible: diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go index e7729924304..2654f8f3690 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go @@ -351,7 +351,7 @@ func TestLogRecoverer_Recover(t *testing.T) { }, nil, nil, - []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"}, + []string{"c207451fa897f9bb13b09d54d8655edf0644e027c53521b4a92eafbb64ba4d14"}, []int64{200, 0, 450}, }, { @@ -381,7 +381,7 @@ func TestLogRecoverer_Recover(t *testing.T) { }, nil, nil, - []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"}, + []string{"c207451fa897f9bb13b09d54d8655edf0644e027c53521b4a92eafbb64ba4d14"}, []int64{600}, }, { @@ -412,7 +412,7 @@ func TestLogRecoverer_Recover(t *testing.T) { }, nil, nil, - []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"}, + []string{"c207451fa897f9bb13b09d54d8655edf0644e027c53521b4a92eafbb64ba4d14"}, []int64{700}, // should be configUpdateBlock + recoveryLogsBuffer }, } @@ -719,9 +719,48 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { return 100, nil }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(200) + return nil + }, + }, expectErr: true, wantErr: errors.New("log block is not recoverable"), }, + { + name: "if a log block has does not match, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 200, + BlockHash: common.HexToHash("0x2"), + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(200) + receipt.BlockHash = common.HexToHash("0x1") + return nil + }, + }, + expectErr: true, + wantErr: errors.New("log tx reorged"), + }, { name: "if a log block is recoverable, when the upkeep state reader errors, an error is returned", proposal: ocr2keepers.CoordinatedBlockProposal{ @@ -747,6 +786,13 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { return nil, errors.New("upkeep state boom") }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(80) + return nil + }, + }, expectErr: true, wantErr: errors.New("upkeep state boom"), }, @@ -770,6 +816,13 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { return 100, nil }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(80) + return nil + }, + }, stateReader: &mockStateReader{ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { return []ocr2keepers.UpkeepState{ @@ -803,6 +856,13 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { return 100, nil }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(80) + return nil + }, + }, stateReader: &mockStateReader{ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { return []ocr2keepers.UpkeepState{ @@ -831,6 +891,13 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { return nil, errors.New("logs with sigs boom") }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(80) + return nil + }, + }, stateReader: &mockStateReader{ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { return []ocr2keepers.UpkeepState{ @@ -863,6 +930,13 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, nil }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(80) + return nil + }, + }, stateReader: &mockStateReader{ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { return []ocr2keepers.UpkeepState{ @@ -890,7 +964,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { } return t }(), - WorkID: "d91c6f090b8477f434cf775182e4ff12c90618ba4da5b8ec06aa719768b7743a", + WorkID: "7f775793422d178c90e99c3bbdf05181bc6bb6ce13170e87c92ac396bb7ddda0", }, logPoller: &mockLogPoller{ LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { @@ -907,6 +981,14 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, nil }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(80) + receipt.BlockHash = [32]byte{1} + return nil + }, + }, stateReader: &mockStateReader{ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { return []ocr2keepers.UpkeepState{ @@ -933,7 +1015,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { } return t }(), - WorkID: "d91c6f090b8477f434cf775182e4ff12c90618ba4da5b8ec06aa719768b7743a", + WorkID: "7f775793422d178c90e99c3bbdf05181bc6bb6ce13170e87c92ac396bb7ddda0", }, logPoller: &mockLogPoller{ LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { @@ -955,6 +1037,14 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, nil }, }, + client: &mockClient{ + CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error { + receipt.Status = 1 + receipt.BlockNumber = big.NewInt(80) + receipt.BlockHash = [32]byte{1} + return nil + }, + }, stateReader: &mockStateReader{ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { return []ocr2keepers.UpkeepState{ diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go index abe11c00aef..cd77d573f09 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go @@ -134,7 +134,7 @@ func (r *EvmRegistry) verifyLogExists(upkeepId *big.Int, p ocr2keepers.UpkeepPay if logBlockNumber != 0 { h, ok := r.bs.queryBlocksMap(logBlockNumber) if ok && h == logBlockHash.Hex() { - r.lggr.Debugf("tx hash %s exists on chain at block number %d for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), logBlockNumber, upkeepId) + r.lggr.Debugf("tx hash %s exists on chain at block number %d, block hash %s for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), logBlockHash.Hex(), logBlockNumber, upkeepId) return encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false } r.lggr.Debugf("log block %d does not exist in block subscriber for upkeepId %s, querying eth client", logBlockNumber, upkeepId) @@ -142,7 +142,7 @@ func (r *EvmRegistry) verifyLogExists(upkeepId *big.Int, p ocr2keepers.UpkeepPay r.lggr.Debugf("log block not provided, querying eth client for tx hash %s for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId) } // query eth client as a fallback - bn, _, err := core.GetTxBlock(r.ctx, r.client, p.Trigger.LogTriggerExtension.TxHash) + bn, bh, err := core.GetTxBlock(r.ctx, r.client, p.Trigger.LogTriggerExtension.TxHash) if err != nil { // primitive way of checking errors if strings.Contains(err.Error(), "missing required field") || strings.Contains(err.Error(), "not found") { @@ -155,6 +155,10 @@ func (r *EvmRegistry) verifyLogExists(upkeepId *big.Int, p ocr2keepers.UpkeepPay r.lggr.Warnf("tx hash %s does not exist on chain for upkeepId %s.", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId) return encoding.UpkeepFailureReasonTxHashNoLongerExists, encoding.NoPipelineError, false } + if bh.Hex() != logBlockHash.Hex() { + r.lggr.Warnf("tx hash %s reorged from expected blockhash %s to %s for upkeepId %s.", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), logBlockHash.Hex(), bh.Hex(), upkeepId) + return encoding.UpkeepFailureReasonTxHashReorged, encoding.NoPipelineError, false + } r.lggr.Debugf("tx hash %s exists on chain for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId) return encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go index 0cd1a11fcce..ae20ac14df6 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go @@ -280,6 +280,26 @@ func TestRegistry_VerifyLogExists(t *testing.T) { }, receipt: &types.Receipt{Status: 0}, }, + { + name: "eth client returns a matching block but different hash", + upkeepId: big.NewInt(12345), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewLogTrigger(550, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), extension1), + WorkID: "work", + }, + reason: encoding.UpkeepFailureReasonTxHashReorged, + retryable: false, + blocks: map[int64]string{ + 500: "0xa518faeadcc423338c62572da84dda35fe44b34f521ce88f6081b703b250cca4", + }, + makeEthCall: true, + receipt: &types.Receipt{ + Status: 1, + BlockNumber: big.NewInt(550), + BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + }, + }, { name: "eth client returns a matching block", upkeepId: big.NewInt(12345), @@ -297,7 +317,7 @@ func TestRegistry_VerifyLogExists(t *testing.T) { receipt: &types.Receipt{ Status: 1, BlockNumber: big.NewInt(550), - BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + BlockHash: common.HexToHash("0x3df0e926f3e21ec1195ffe007a2899214905eb02e768aa89ce0b94accd7f3d71"), }, }, { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go index 1ea456ed3d5..a8c4ce93ad8 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go @@ -191,6 +191,7 @@ func (c *TransmitEventProvider) processLogs(latestBlock int64, logs ...logpoller trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{} trigger.LogTriggerExtension.TxHash = triggerW.TxHash trigger.LogTriggerExtension.Index = triggerW.LogIndex + trigger.LogTriggerExtension.BlockHash = triggerW.LogBlockHash default: } workID := core.UpkeepWorkID(*upkeepId, trigger) @@ -215,8 +216,9 @@ func (c *TransmitEventProvider) processLogs(latestBlock int64, logs ...logpoller func (c *TransmitEventProvider) logKey(log logpoller.Log) string { logExt := ocr2keepers.LogTriggerExtension{ - TxHash: log.TxHash, - Index: uint32(log.LogIndex), + TxHash: log.TxHash, + Index: uint32(log.LogIndex), + BlockHash: log.BlockHash, } logId := logExt.LogIdentifier() return hex.EncodeToString(logId) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go index aa3480c8c26..72f3b63088d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go @@ -127,7 +127,7 @@ func TestTransmitEventProvider_ProcessLogs(t *testing.T) { Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{ Id: id.BigInt(), Trigger: func() []byte { - b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") return b }(), }, @@ -161,7 +161,7 @@ func TestTransmitEventProvider_ProcessLogs(t *testing.T) { Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{ Id: id.BigInt(), Trigger: func() []byte { - b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") return b }(), }, @@ -174,7 +174,7 @@ func TestTransmitEventProvider_ProcessLogs(t *testing.T) { Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{ Id: id.BigInt(), Trigger: func() []byte { - b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") return b }(), }, diff --git a/go.mod b/go.mod index 56c59625339..19efff0277c 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.20 + github.com/smartcontractkit/ocr2keepers v0.7.21 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e diff --git a/go.sum b/go.sum index 8d127373678..57938ebab7d 100644 --- a/go.sum +++ b/go.sum @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.20 h1:1FOeJ0p4mWHqJiX01v/J2S1C1LhU8iqJM1hDcD38aZU= -github.com/smartcontractkit/ocr2keepers v0.7.20/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.21 h1:64CNFoUYVpoJqhQ39WTPIEKVKB5Z/wderX0pIsv/tbA= +github.com/smartcontractkit/ocr2keepers v0.7.21/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f485252941d..1b1b3940ccf 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -23,7 +23,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.20 + github.com/smartcontractkit/ocr2keepers v0.7.21 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230829114801-14bf715f805e github.com/smartcontractkit/wasp v0.3.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 029573053cf..2e77b16fe09 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2266,8 +2266,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.20 h1:1FOeJ0p4mWHqJiX01v/J2S1C1LhU8iqJM1hDcD38aZU= -github.com/smartcontractkit/ocr2keepers v0.7.20/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.21 h1:64CNFoUYVpoJqhQ39WTPIEKVKB5Z/wderX0pIsv/tbA= +github.com/smartcontractkit/ocr2keepers v0.7.21/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= From 8f6c038ef6ffb5efc5146059c491094e415b1563 Mon Sep 17 00:00:00 2001 From: Margaret Ma Date: Thu, 7 Sep 2023 14:11:12 -0400 Subject: [PATCH 54/88] include forwarder address in ocr2 config (#10532) --- core/web/schema/type/feeds_manager.graphql | 1 + 1 file changed, 1 insertion(+) diff --git a/core/web/schema/type/feeds_manager.graphql b/core/web/schema/type/feeds_manager.graphql index 6a2b019aae3..0d6d5f61788 100644 --- a/core/web/schema/type/feeds_manager.graphql +++ b/core/web/schema/type/feeds_manager.graphql @@ -49,6 +49,7 @@ type OCR2JobConfig { enabled: Boolean! isBootstrap: Boolean! multiaddr: String + forwarderAddress: String p2pPeerID: String keyBundleID: String plugins: Plugins! From 95e5df2075a7cc07a1047c0f56d0b68ad71a0f8f Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Thu, 7 Sep 2023 21:17:55 +0300 Subject: [PATCH 55/88] Performed events scanner: batch calls to log poller (#10546) * batch ids before calling poller for dedup events * merge var blocks --- .../ocr2keeper/evm21/upkeepstate/scanner.go | 21 ++++++-- .../evm21/upkeepstate/scanner_test.go | 52 +++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go index 7879ec45bf9..11a498d63cd 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go @@ -15,6 +15,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) +var ( + _ PerformedLogsScanner = &performedEventsScanner{} + + workIDsBatchSize = 25 +) + type PerformedLogsScanner interface { ScanWorkIDs(ctx context.Context, workIDs ...string) ([]string, error) @@ -66,9 +72,18 @@ func (s *performedEventsScanner) ScanWorkIDs(ctx context.Context, workID ...stri for _, id := range workID { ids = append(ids, common.HexToHash(id)) } - logs, err := s.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), s.registryAddress, 1, ids, int(s.finalityDepth), pg.WithParentCtx(ctx)) - if err != nil { - return nil, fmt.Errorf("error fetching logs: %w", err) + logs := make([]logpoller.Log, 0) + for i := 0; i < len(ids); i += workIDsBatchSize { + end := i + workIDsBatchSize + if end > len(ids) { + end = len(ids) + } + batch := ids[i:end] + batchLogs, err := s.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), s.registryAddress, 1, batch, int(s.finalityDepth), pg.WithParentCtx(ctx)) + if err != nil { + return nil, fmt.Errorf("error fetching logs: %w", err) + } + logs = append(logs, batchLogs...) } return s.logsToWorkIDs(logs), nil diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go index f1962373fe9..9442a5f5d7a 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go @@ -2,6 +2,7 @@ package upkeepstate import ( "fmt" + "sort" "testing" "github.com/ethereum/go-ethereum/common" @@ -110,6 +111,57 @@ func TestPerformedEventsScanner(t *testing.T) { } } +func TestPerformedEventsScanner_Batch(t *testing.T) { + ctx := testutils.Context(t) + registryAddr := common.HexToAddress("0x12345") + lggr := logger.TestLogger(t) + lp := new(mocks.LogPoller) + scanner := NewPerformedEventsScanner(lggr, lp, registryAddr, 100) + + lp.On("IndexedLogs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{ + { + BlockNumber: 1, + Address: registryAddr, + Topics: convertTopics([]common.Hash{ + iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), + common.HexToHash("0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"), + }), + }, + }, nil).Times(1) + lp.On("IndexedLogs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{ + { + BlockNumber: 3, + Address: registryAddr, + Topics: convertTopics([]common.Hash{ + iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), + common.HexToHash("0x331decd9548b62a8d603457658386fc84ba6bc95888008f6362f93160ef3b663"), + }), + }, + }, nil).Times(1) + + origWorkIDsBatchSize := workIDsBatchSize + workIDsBatchSize = 8 + defer func() { + workIDsBatchSize = origWorkIDsBatchSize + }() + + ids, err := scanner.ScanWorkIDs(ctx, + "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", + "1111", "2222", "3333", "4444", "5555", "6666", "7777", "8888", "9999", + "331decd9548b62a8d603457658386fc84ba6bc95888008f6362f93160ef3b663", + ) + + require.NoError(t, err) + require.Equal(t, 2, len(ids)) + sort.Slice(ids, func(i, j int) bool { + return ids[i] < ids[j] + }) + require.Equal(t, "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", ids[0]) + require.Equal(t, "331decd9548b62a8d603457658386fc84ba6bc95888008f6362f93160ef3b663", ids[1]) + + lp.AssertExpectations(t) +} + func convertTopics(topics []common.Hash) [][]byte { var topicsForDB [][]byte for _, t := range topics { From b22efb8bc445fcc908ccce844fe85dff5dae62ee Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Thu, 7 Sep 2023 14:23:57 -0400 Subject: [PATCH 56/88] (test): Add Functions Router foundry tests (#10460) * (test): Add Functions Router foundry tests * Add extra tests from code review --- .../gas-snapshots/functions.gas-snapshot | 54 +- .../v0.8/functions/tests/1_0_0/BaseTest.t.sol | 2 +- .../tests/1_0_0/FunctionsRouter.t.sol | 1413 ++++++++++++++++- .../v0.8/functions/tests/1_0_0/Setup.t.sol | 17 +- 4 files changed, 1451 insertions(+), 35 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 00ebdc48dfd..e0d973ead2a 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -8,10 +8,62 @@ FunctionsOracle_setRegistry:testOnlyOwnerReverts() (gas: 10927) FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35791) FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987) FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905) +FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12073) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 48299) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 38870) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 36239) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35161) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 165) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28037) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 33206) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 102749) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 1770949) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 206000) +FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17842) +FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12883) +FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 31332) +FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13893) +FunctionsRouter_GetContractById:test_GetContractById_SuccessIfRouteExists() (gas: 17417) +FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16382) +FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 23934) +FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 25935) +FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 25509) +FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41004) +FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 22027) FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13315) FunctionsRouter_Pause:test_Pause_Success() (gas: 20254) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14790) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 22683) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengthMismatch() (gas: 14669) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19047) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23348) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118768) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 58984) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57935) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186118) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 48426) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25066) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29162) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34231) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 197905) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65547) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36013) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29904) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 55012) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27532) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35747) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40817) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 204530) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192704) +FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30666) +FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13402) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13294) FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77334) +FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21909) +FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 51123) +FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13315) +FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 38715) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60355) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 60984) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94703) @@ -109,4 +161,4 @@ FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTru FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13525) FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 95208) FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13736) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22082) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22082) \ No newline at end of file diff --git a/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol index 13994f88f71..d01e438a92a 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol @@ -16,6 +16,6 @@ contract BaseTest is Test { if (s_baseTestInitialized) return; s_baseTestInitialized = true; // Set msg.sender to OWNER until stopPrank is called - vm.startPrank(OWNER_ADDRESS); + vm.startPrank(OWNER_ADDRESS, OWNER_ADDRESS); } } diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol index ee75a27e3f4..742a471cb58 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol @@ -3,116 +3,1471 @@ pragma solidity ^0.8.19; import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol"; +import {FunctionsBilling} from "../../dev/1_0_0/FunctionsBilling.sol"; +import {FunctionsRequest} from "../../dev/1_0_0/libraries/FunctionsRequest.sol"; +import {FunctionsResponse} from "../../dev/1_0_0/libraries/FunctionsResponse.sol"; +import {FunctionsCoordinatorTestHelper} from "./testhelpers/FunctionsCoordinatorTestHelper.sol"; +import {FunctionsClientTestHelper} from "./testhelpers/FunctionsClientTestHelper.sol"; -import {FunctionsRouterSetup} from "./Setup.t.sol"; +import {FunctionsRouterSetup, FunctionsRoutesSetup, FunctionsSubscriptionSetup, FunctionsClientRequestSetup} from "./Setup.t.sol"; + +import "forge-std/Vm.sol"; +import "forge-std/console.sol"; // ================================================================ // | Functions Router | // ================================================================ /// @notice #constructor -contract FunctionsRouter_Constructor { - +contract FunctionsRouter_Constructor is FunctionsRouterSetup { + function test_Constructor_Success() public { + assertEq(s_functionsRouter.typeAndVersion(), "Functions Router v1.0.0"); + assertEq(s_functionsRouter.owner(), OWNER_ADDRESS); + } } /// @notice #getConfig -contract FunctionsRouter_GetConfig { +contract FunctionsRouter_GetConfig is FunctionsRouterSetup { + function test_GetConfig_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + FunctionsRouter.Config memory config = s_functionsRouter.getConfig(); + assertEq(config.maxConsumersPerSubscription, getRouterConfig().maxConsumersPerSubscription); + assertEq(config.adminFee, getRouterConfig().adminFee); + assertEq(config.handleOracleFulfillmentSelector, getRouterConfig().handleOracleFulfillmentSelector); + assertEq(config.maxCallbackGasLimits[0], getRouterConfig().maxCallbackGasLimits[0]); + assertEq(config.maxCallbackGasLimits[1], getRouterConfig().maxCallbackGasLimits[1]); + assertEq(config.maxCallbackGasLimits[2], getRouterConfig().maxCallbackGasLimits[2]); + assertEq(config.gasForCallExactCheck, getRouterConfig().gasForCallExactCheck); + } } /// @notice #updateConfig -contract FunctionsRouter_UpdateConfig { +contract FunctionsRouter_UpdateConfig is FunctionsRouterSetup { + FunctionsRouter.Config internal configToSet; + + function setUp() public virtual override { + FunctionsRouterSetup.setUp(); + + uint32[] memory maxCallbackGasLimits = new uint32[](4); + maxCallbackGasLimits[0] = 300_000; + maxCallbackGasLimits[1] = 500_000; + maxCallbackGasLimits[2] = 1_000_000; + maxCallbackGasLimits[3] = 3_000_000; + + configToSet = FunctionsRouter.Config({ + maxConsumersPerSubscription: s_maxConsumersPerSubscription, + adminFee: s_adminFee, + handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector, + maxCallbackGasLimits: maxCallbackGasLimits, + gasForCallExactCheck: 5000 + }); + } + + function test_UpdateConfig_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsRouter.updateConfig(configToSet); + } + + event ConfigUpdated(FunctionsRouter.Config config); + function test_UpdateConfig_Success() public { + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit ConfigUpdated(configToSet); + + s_functionsRouter.updateConfig(configToSet); + + FunctionsRouter.Config memory config = s_functionsRouter.getConfig(); + assertEq(config.maxConsumersPerSubscription, configToSet.maxConsumersPerSubscription); + assertEq(config.adminFee, configToSet.adminFee); + assertEq(config.handleOracleFulfillmentSelector, configToSet.handleOracleFulfillmentSelector); + assertEq(config.maxCallbackGasLimits[0], configToSet.maxCallbackGasLimits[0]); + assertEq(config.maxCallbackGasLimits[1], configToSet.maxCallbackGasLimits[1]); + assertEq(config.maxCallbackGasLimits[2], configToSet.maxCallbackGasLimits[2]); + assertEq(config.maxCallbackGasLimits[3], configToSet.maxCallbackGasLimits[3]); + assertEq(config.gasForCallExactCheck, configToSet.gasForCallExactCheck); + } } /// @notice #isValidCallbackGasLimit -contract FunctionsRouter_IsValidCallbackGasLimit { +contract FunctionsRouter_IsValidCallbackGasLimit is FunctionsSubscriptionSetup { + function test_IsValidCallbackGasLimit_RevertInvalidConfig() public { + // Set an invalid maxCallbackGasLimit flag + bytes32 flagsToSet = 0x5a00000000000000000000000000000000000000000000000000000000000000; + s_functionsRouter.setFlags(s_subscriptionId, flagsToSet); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.InvalidGasFlagValue.selector, 90)); + s_functionsRouter.isValidCallbackGasLimit(s_subscriptionId, 0); + } + + function test_IsValidCallbackGasLimit_RevertGasLimitTooBig() public { + uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0; + bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId); + uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); + + FunctionsRouter.Config memory config = s_functionsRouter.getConfig(); + uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits; + uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector]; + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.GasLimitTooBig.selector, maxCallbackGasLimit)); + s_functionsRouter.isValidCallbackGasLimit(s_subscriptionId, maxCallbackGasLimit + 1); + } + + function test_IsValidCallbackGasLimit_Success() public view { + uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0; + bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId); + uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); + FunctionsRouter.Config memory config = s_functionsRouter.getConfig(); + uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits; + uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector]; + + s_functionsRouter.isValidCallbackGasLimit(s_subscriptionId, maxCallbackGasLimit); + } } /// @notice #getAdminFee -contract FunctionsRouter_GetAdminFee { +contract FunctionsRouter_GetAdminFee is FunctionsRouterSetup { + function test_GetAdminFee_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + uint72 adminFee = s_functionsRouter.getAdminFee(); + assertEq(adminFee, getRouterConfig().adminFee); + } } /// @notice #getAllowListId -contract FunctionsRouter_GetAllowListId { +contract FunctionsRouter_GetAllowListId is FunctionsRouterSetup { + function test_GetAllowListId_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 defaultAllowListId = bytes32(0); + bytes32 allowListId = s_functionsRouter.getAllowListId(); + assertEq(allowListId, defaultAllowListId); + } } /// @notice #setAllowListId -contract FunctionsRouter_SetAllowListId { +contract FunctionsRouter_SetAllowListId is FunctionsRouterSetup { + function test_UpdateConfig_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 routeIdToSet = bytes32("allowList"); + vm.expectRevert("Only callable by owner"); + s_functionsRouter.setAllowListId(routeIdToSet); + } + + function test_SetAllowListId_Success() public { + bytes32 routeIdToSet = bytes32("allowList"); + s_functionsRouter.setAllowListId(routeIdToSet); + bytes32 allowListId = s_functionsRouter.getAllowListId(); + assertEq(allowListId, routeIdToSet); + } } /// @notice #_getMaxConsumers -contract FunctionsRouter__GetMaxConsumers { - +contract FunctionsRouter__GetMaxConsumers is FunctionsRouterSetup { + // TODO: make contract internal function helper } /// @notice #sendRequest -contract FunctionsRouter_SendRequest { +contract FunctionsRouter_SendRequest is FunctionsSubscriptionSetup { + function setUp() public virtual override { + FunctionsSubscriptionSetup.setUp(); + + // Add sending wallet as a subscription consumer + s_functionsRouter.addConsumer(s_subscriptionId, OWNER_ADDRESS); + } + + function test_SendRequest_RevertIfInvalidDonId() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + bytes32 invalidDonId = bytes32("this does not exist"); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidDonId)); + s_functionsRouter.sendRequest( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5_000, + invalidDonId + ); + } + + function test_SendRequest_RevertIfIncorrectDonId() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + bytes32 incorrectDonId = s_functionsRouter.getAllowListId(); + + // Low level revert from incorrect call + vm.expectRevert(); + s_functionsRouter.sendRequest( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5_000, + incorrectDonId + ); + } + + function test_SendRequest_RevertIfPaused() public { + s_functionsRouter.pause(); + + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.sendRequest(s_subscriptionId, requestData, FunctionsRequest.REQUEST_DATA_VERSION, 5000, s_donId); + } + + function test_SendRequest_RevertIfNoSubscription() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint64 invalidSubscriptionId = 123456789; + + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + s_functionsRouter.sendRequest( + invalidSubscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5000, + s_donId + ); + } + + function test_SendRequest_RevertIfConsumerNotAllowed() public { + // Remove sending wallet as a subscription consumer + s_functionsRouter.removeConsumer(s_subscriptionId, OWNER_ADDRESS); + + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + vm.expectRevert(FunctionsSubscriptions.InvalidConsumer.selector); + s_functionsRouter.sendRequest(s_subscriptionId, requestData, FunctionsRequest.REQUEST_DATA_VERSION, 5000, s_donId); + } + + function test_SendRequest_RevertIfInvalidCallbackGasLimit() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0; + bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId); + uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); + + FunctionsRouter.Config memory config = s_functionsRouter.getConfig(); + uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits; + uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector]; + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.GasLimitTooBig.selector, maxCallbackGasLimit)); + s_functionsRouter.sendRequest( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 500_000, + s_donId + ); + } + function test_SendRequest_RevertIfEmptyData() public { + // Build invalid request data + bytes memory emptyRequestData = new bytes(0); + + vm.expectRevert(FunctionsRouter.EmptyRequestData.selector); + s_functionsRouter.sendRequest( + s_subscriptionId, + emptyRequestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5_000, + s_donId + ); + } + + function test_SendRequest_RevertIfInsufficientSubscriptionBalance() public { + // Create new subscription that does not have any funding + uint64 subscriptionId = s_functionsRouter.createSubscription(); + s_functionsRouter.addConsumer(subscriptionId, address(OWNER_ADDRESS)); + + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint32 callbackGasLimit = 5000; + vm.expectRevert(FunctionsBilling.InsufficientBalance.selector); + + s_functionsRouter.sendRequest( + subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + s_donId + ); + } + + event RequestStart( + bytes32 indexed requestId, + bytes32 indexed donId, + uint64 indexed subscriptionId, + address subscriptionOwner, + address requestingContract, + address requestInitiator, + bytes data, + uint16 dataVersion, + uint32 callbackGasLimit, + uint96 estimatedTotalCostJuels + ); + + function test_SendRequest_Success() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint32 callbackGasLimit = 5000; + + bytes32 expectedRequestId = keccak256( + abi.encode(address(s_functionsCoordinator), OWNER_ADDRESS, s_subscriptionId, 1) + ); + + uint96 costEstimate = s_functionsCoordinator.estimateCost( + s_subscriptionId, + requestData, + callbackGasLimit, + tx.gasprice + ); + + vm.recordLogs(); + + // topic0 (function signature, always checked), topic1 (true), topic2 (true), topic3 (true), and data (true). + bool checkTopic1 = true; + bool checkTopic2 = true; + bool checkTopic3 = true; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestStart({ + requestId: expectedRequestId, + donId: s_donId, + subscriptionId: s_subscriptionId, + subscriptionOwner: OWNER_ADDRESS, + requestingContract: OWNER_ADDRESS, + requestInitiator: OWNER_ADDRESS, + data: requestData, + dataVersion: FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit: callbackGasLimit, + estimatedTotalCostJuels: costEstimate + }); + + bytes32 requestIdFromReturn = s_functionsRouter.sendRequest( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + s_donId + ); + + // Get requestId from RequestStart event log topic 1 + Vm.Log[] memory entries = vm.getRecordedLogs(); + bytes32 requestIdFromEvent = entries[2].topics[1]; + + assertEq(requestIdFromReturn, requestIdFromEvent); + } } /// @notice #sendRequestToProposed -contract FunctionsRouter_SendRequestToProposed { +contract FunctionsRouter_SendRequestToProposed is FunctionsSubscriptionSetup { + FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper + + function setUp() public virtual override { + FunctionsSubscriptionSetup.setUp(); + + // Add sending wallet as a subscription consumer + s_functionsRouter.addConsumer(s_subscriptionId, OWNER_ADDRESS); + + // Deploy new Coordinator contract + s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( + address(s_functionsRouter), + getCoordinatorConfig(), + address(s_linkEthFeed) + ); + + // Propose new Coordinator contract + bytes32[] memory proposedContractSetIds = new bytes32[](1); + proposedContractSetIds[0] = s_donId; + address[] memory proposedContractSetAddresses = new address[](1); + proposedContractSetAddresses[0] = address(s_functionsCoordinator2); + + s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses); + } + + function test_SendRequestToProposed_RevertIfInvalidDonId() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + bytes32 invalidDonId = bytes32("this does not exist"); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidDonId)); + s_functionsRouter.sendRequestToProposed( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5_000, + invalidDonId + ); + } + + function test_SendRequestToProposed_RevertIfIncorrectDonId() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + bytes32 incorrectDonId = s_functionsRouter.getAllowListId(); + + // Low level revert from incorrect call + vm.expectRevert(); + s_functionsRouter.sendRequestToProposed( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5_000, + incorrectDonId + ); + } + + function test_SendRequestToProposed_RevertIfPaused() public { + s_functionsRouter.pause(); + + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.sendRequestToProposed( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5000, + s_donId + ); + } + + function test_SendRequestToProposed_RevertIfNoSubscription() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + uint64 invalidSubscriptionId = 123456789; + + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + s_functionsRouter.sendRequestToProposed( + invalidSubscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5000, + s_donId + ); + } + + function test_SendRequestToProposed_RevertIfConsumerNotAllowed() public { + // Remove sending wallet as a subscription consumer + s_functionsRouter.removeConsumer(s_subscriptionId, OWNER_ADDRESS); + + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + vm.expectRevert(FunctionsSubscriptions.InvalidConsumer.selector); + s_functionsRouter.sendRequestToProposed( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5000, + s_donId + ); + } + + function test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0; + bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId); + uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); + + FunctionsRouter.Config memory config = s_functionsRouter.getConfig(); + uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits; + uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector]; + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.GasLimitTooBig.selector, maxCallbackGasLimit)); + s_functionsRouter.sendRequestToProposed( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 500_000, + s_donId + ); + } + + function test_SendRequestToProposed_RevertIfEmptyData() public { + // Build invalid request data + bytes memory emptyRequestData = new bytes(0); + + vm.expectRevert(FunctionsRouter.EmptyRequestData.selector); + s_functionsRouter.sendRequestToProposed( + s_subscriptionId, + emptyRequestData, + FunctionsRequest.REQUEST_DATA_VERSION, + 5_000, + s_donId + ); + } + + function test_SendRequest_RevertIfInsufficientSubscriptionBalance() public { + // Create new subscription that does not have any funding + uint64 subscriptionId = s_functionsRouter.createSubscription(); + s_functionsRouter.addConsumer(subscriptionId, address(OWNER_ADDRESS)); + + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint32 callbackGasLimit = 5000; + vm.expectRevert(FunctionsBilling.InsufficientBalance.selector); + + s_functionsRouter.sendRequestToProposed( + subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + s_donId + ); + } + + event RequestStart( + bytes32 indexed requestId, + bytes32 indexed donId, + uint64 indexed subscriptionId, + address subscriptionOwner, + address requestingContract, + address requestInitiator, + bytes data, + uint16 dataVersion, + uint32 callbackGasLimit, + uint96 estimatedTotalCostJuels + ); + + function test_SendRequestToProposed_Success() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint32 callbackGasLimit = 5000; + + bytes32 expectedRequestId = keccak256( + abi.encode(address(s_functionsCoordinator2), OWNER_ADDRESS, s_subscriptionId, 1) + ); + + uint96 costEstimate = s_functionsCoordinator2.estimateCost( + s_subscriptionId, + requestData, + callbackGasLimit, + tx.gasprice + ); + + vm.recordLogs(); + + // topic0 (function signature, always checked), topic1 (true), topic2 (true), topic3 (true), and data (true). + bool checkTopic1 = true; + bool checkTopic2 = true; + bool checkTopic3 = true; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestStart({ + requestId: expectedRequestId, + donId: s_donId, + subscriptionId: s_subscriptionId, + subscriptionOwner: OWNER_ADDRESS, + requestingContract: OWNER_ADDRESS, + requestInitiator: OWNER_ADDRESS, + data: requestData, + dataVersion: FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit: callbackGasLimit, + estimatedTotalCostJuels: costEstimate + }); + + bytes32 requestIdFromReturn = s_functionsRouter.sendRequestToProposed( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + s_donId + ); + + // Get requestId from RequestStart event log topic 1 + Vm.Log[] memory entries = vm.getRecordedLogs(); + bytes32 requestIdFromEvent = entries[2].topics[1]; + + assertEq(requestIdFromReturn, requestIdFromEvent); + } } /// @notice #_sendRequest -contract FunctionsRouter__SendRequest { - +contract FunctionsRouter__SendRequest is FunctionsRouterSetup { + // TODO: make contract internal function helper } /// @notice #fulfill -contract FunctionsRouter_Fulfill { +contract FunctionsRouter_Fulfill is FunctionsClientRequestSetup { + function test_Fulfill_RevertIfPaused() public { + s_functionsRouter.pause(); + + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.fulfill(response, err, juelsPerGas, costWithoutCallback, transmitter, commitment); + } + + function test_Fulfill_RevertIfNotCommittedCoordinator() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + + vm.expectRevert(FunctionsRouter.OnlyCallableFromCoordinator.selector); + s_functionsRouter.fulfill(response, err, juelsPerGas, costWithoutCallback, transmitter, commitment); + } + + event RequestNotProcessed( + bytes32 indexed requestId, + address coordinator, + address transmitter, + FunctionsResponse.FulfillResult resultCode + ); + + function test_Fulfill_RequestNotProcessedInvalidRequestId() public { + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + // Modify request commitment to have a invalid requestId + bytes32 invalidRequestId = bytes32("this does not exist"); + commitment.requestId = invalidRequestId; + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestNotProcessed({ + requestId: s_requestCommitment.requestId, + coordinator: address(s_functionsCoordinator), + transmitter: NOP_TRANSMITTER_ADDRESS_1, + resultCode: FunctionsResponse.FulfillResult.INVALID_REQUEST_ID + }); + + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + response, + err, + juelsPerGas, + costWithoutCallback, + transmitter, + commitment + ); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.INVALID_REQUEST_ID)); + assertEq(callbackGasCostJuels, 0); + } + + function test_Fulfill_RequestNotProcessedInvalidCommitment() public { + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + // Modify request commitment to have charge more than quoted + commitment.estimatedTotalCostJuels = 10 * JUELS_PER_LINK; // 10 LINK + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestNotProcessed({ + requestId: s_requestCommitment.requestId, + coordinator: address(s_functionsCoordinator), + transmitter: NOP_TRANSMITTER_ADDRESS_1, + resultCode: FunctionsResponse.FulfillResult.INVALID_COMMITMENT + }); + + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + response, + err, + juelsPerGas, + costWithoutCallback, + transmitter, + commitment + ); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.INVALID_COMMITMENT)); + assertEq(callbackGasCostJuels, 0); + } + + function test_Fulfill_RequestNotProcessedInsufficientGas() public { + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + + vm.txGasPrice(1); + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestNotProcessed({ + requestId: s_requestCommitment.requestId, + coordinator: address(s_functionsCoordinator), + transmitter: NOP_TRANSMITTER_ADDRESS_1, + resultCode: FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED + }); + + // Coordinator sends enough gas that would get through callback and payment, but fail after + uint32 callbackGasLimit = 5000; + uint256 gasToUse = getCoordinatorConfig().gasOverheadBeforeCallback + callbackGasLimit; + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill{ + gas: gasToUse + }(response, err, juelsPerGas, costWithoutCallback, transmitter, s_requestCommitment); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED)); + assertEq(callbackGasCostJuels, 0); + } + + function test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() public { + // // Send as committed Coordinator + // vm.stopPrank(); + // vm.startPrank(address(s_functionsCoordinator)); + // bytes memory response = bytes("hello world!"); + // bytes memory err = new bytes(0); + // uint96 juelsPerGas = 0; + // uint96 costWithoutCallback = 0; + // address transmitter = NOP_TRANSMITTER_ADDRESS_1; + // FunctionsResponse.Commitment memory commitment = s_requestCommitment; + // TODO: use contract helper to change subscription balance + // // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + // bool checkTopic1 = false; + // bool checkTopic2 = false; + // bool checkTopic3 = false; + // bool checkData = true; + // vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + // emit RequestNotProcessed({ + // requestId: s_requestCommitment.requestId, + // coordinator: address(s_functionsCoordinator), + // transmitter: NOP_TRANSMITTER_ADDRESS_1, + // resultCode: FunctionsResponse.FulfillResult.SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION + // }); + // (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + // response, + // err, + // juelsPerGas, + // costWithoutCallback, + // transmitter, + // commitment + // ); + // assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION)); + // assertEq(callbackGasCostJuels, 0); + } + + function test_Fulfill_RequestNotProcessedCostExceedsCommitment() public { + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + // Use higher juelsPerGas than request time + uint96 juelsPerGas = 100000; + uint96 costWithoutCallback = 1; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestNotProcessed({ + requestId: s_requestCommitment.requestId, + coordinator: address(s_functionsCoordinator), + transmitter: NOP_TRANSMITTER_ADDRESS_1, + resultCode: FunctionsResponse.FulfillResult.COST_EXCEEDS_COMMITMENT + }); + + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + response, + err, + juelsPerGas, + costWithoutCallback, + transmitter, + commitment + ); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.COST_EXCEEDS_COMMITMENT)); + assertEq(callbackGasCostJuels, 0); + } + + event RequestProcessed( + bytes32 indexed requestId, + uint64 indexed subscriptionId, + uint96 totalCostJuels, + address transmitter, + FunctionsResponse.FulfillResult resultCode, + bytes response, + bytes err, + bytes callbackReturnData + ); + + FunctionsClientTestHelper internal s_clientWithFailingCallback; + + function test_Fulfill_SuccessUserCallbackReverts() public { + // Deploy Client with failing callback + s_clientWithFailingCallback = new FunctionsClientTestHelper(address(s_functionsRouter)); + s_clientWithFailingCallback.setRevertFulfillRequest(true); + + // Add Client as a subscription consumer + s_functionsRouter.addConsumer(s_subscriptionId, address(s_clientWithFailingCallback)); + // Send a minimal request + string memory sourceCode = "return 'hello world';"; + + vm.recordLogs(); + bytes32 requestId = s_clientWithFailingCallback.sendSimpleRequestWithJavaScript( + sourceCode, + s_subscriptionId, + s_donId, + 5000 + ); + + // Get commitment data from OracleRequest event log + Vm.Log[] memory entries = vm.getRecordedLogs(); + (, , , , , , , FunctionsResponse.Commitment memory _commitment) = abi.decode( + entries[0].data, + (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment) + ); + s_requestCommitment = _commitment; + + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestProcessed({ + requestId: requestId, + subscriptionId: s_subscriptionId, + totalCostJuels: s_adminFee + costWithoutCallback, + transmitter: transmitter, + resultCode: FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR, + response: response, + err: err, + callbackReturnData: vm.parseBytes( + "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000f61736b656420746f207265766572740000000000000000000000000000000000" + ) // TODO: build this + }); + + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + response, + err, + juelsPerGas, + costWithoutCallback, + transmitter, + commitment + ); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR)); + assertEq(callbackGasCostJuels, 0); + } + + function test_Fulfill_SuccessUserCallbackRunsOutOfGas() public { + string memory sourceCode = "return 'hello world';"; + bytes memory secrets; + string[] memory args = new string[](0); + bytes[] memory bytesArgs = new bytes[](0); + uint32 callbackGasLimit = 0; + + vm.recordLogs(); + // Send a request with no gas for the callback + bytes32 requestId = s_functionsClient.sendRequest( + s_donId, + sourceCode, + secrets, + args, + bytesArgs, + s_subscriptionId, + callbackGasLimit + ); + + // Get commitment data from OracleRequest event log + Vm.Log[] memory entries = vm.getRecordedLogs(); + (, , , , , , , FunctionsResponse.Commitment memory commitment) = abi.decode( + entries[0].data, + (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment) + ); + + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + vm.expectEmit(false, false, false, true); + emit RequestProcessed({ + requestId: requestId, + subscriptionId: s_subscriptionId, + totalCostJuels: s_adminFee + costWithoutCallback, // NOTE: tx.gasprice is at 0, so no callback gas used + transmitter: transmitter, + resultCode: FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR, + response: response, + err: err, + callbackReturnData: new bytes(0) + }); + + vm.recordLogs(); + + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + response, + err, + juelsPerGas, + costWithoutCallback, + transmitter, + commitment + ); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR)); + assertEq(callbackGasCostJuels, 0); + } + + function test_Fulfill_SuccessFulfilled() public { + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit RequestProcessed({ + requestId: s_requestId, + subscriptionId: s_subscriptionId, + totalCostJuels: s_adminFee + costWithoutCallback, // NOTE: tx.gasprice is at 0, so no callback gas used + transmitter: transmitter, + resultCode: FunctionsResponse.FulfillResult.FULFILLED, + response: response, + err: err, + callbackReturnData: new bytes(0) + }); + + vm.recordLogs(); + + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + response, + err, + juelsPerGas, + costWithoutCallback, + transmitter, + commitment + ); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.FULFILLED)); + assertEq(callbackGasCostJuels, 0); + } } /// @notice #_callback -contract FunctionsRouter__Callback { - +contract FunctionsRouter__Callback is FunctionsRouterSetup { + // TODO: make contract internal function helper } /// @notice #getContractById -contract FunctionsRouter_GetContractById { +contract FunctionsRouter_GetContractById is FunctionsRoutesSetup { + function test_GetContractById_RevertIfRouteDoesNotExist() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 invalidRouteId = bytes32("this does not exist"); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidRouteId)); + s_functionsRouter.getContractById(invalidRouteId); + } + + function test_GetContractById_SuccessIfRouteExists() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + address routeDestination = s_functionsRouter.getContractById(s_donId); + assertEq(routeDestination, address(s_functionsCoordinator)); + } } /// @notice #getProposedContractById -contract FunctionsRouter_GetProposedContractById { +contract FunctionsRouter_GetProposedContractById is FunctionsRoutesSetup { + FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper + + function setUp() public virtual override { + FunctionsRoutesSetup.setUp(); + + // Deploy new Coordinator contract + s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( + address(s_functionsRouter), + getCoordinatorConfig(), + address(s_linkEthFeed) + ); + + // Propose new Coordinator contract + bytes32[] memory proposedContractSetIds = new bytes32[](1); + proposedContractSetIds[0] = s_donId; + address[] memory proposedContractSetAddresses = new address[](1); + proposedContractSetAddresses[0] = address(s_functionsCoordinator2); + + s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses); + } + + function test_GetProposedContractById_RevertIfRouteDoesNotExist() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + bytes32 invalidRouteId = bytes32("this does not exist"); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidRouteId)); + s_functionsRouter.getProposedContractById(invalidRouteId); + } + + function test_GetProposedContractById_SuccessIfRouteExists() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + address routeDestination = s_functionsRouter.getProposedContractById(s_donId); + assertEq(routeDestination, address(s_functionsCoordinator2)); + } } /// @notice #getProposedContractSet -contract FunctionsRouter_GetProposedContractSet { +contract FunctionsRouter_GetProposedContractSet is FunctionsRoutesSetup { + FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper + bytes32[] s_proposedContractSetIds; + address[] s_proposedContractSetAddresses; + + function setUp() public virtual override { + FunctionsRoutesSetup.setUp(); + + // Deploy new Coordinator contract + s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( + address(s_functionsRouter), + getCoordinatorConfig(), + address(s_linkEthFeed) + ); + + // Propose new Coordinator contract + s_proposedContractSetIds = new bytes32[](1); + s_proposedContractSetIds[0] = s_donId; + s_proposedContractSetAddresses = new address[](1); + s_proposedContractSetAddresses[0] = address(s_functionsCoordinator2); + + s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses); + } + + function test_GetProposedContractSet_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + (bytes32[] memory proposedContractSetIds, address[] memory proposedContractSetAddresses) = s_functionsRouter + .getProposedContractSet(); + assertEq(proposedContractSetIds.length, 1); + assertEq(proposedContractSetIds[0], s_donId); + assertEq(proposedContractSetIds.length, 1); + assertEq(proposedContractSetAddresses[0], address(s_functionsCoordinator2)); + } } /// @notice #proposeContractsUpdate -contract FunctionsRouter_ProposeContractsUpdate { +contract FunctionsRouter_ProposeContractsUpdate is FunctionsRoutesSetup { + FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper + bytes32[] s_proposedContractSetIds; + address[] s_proposedContractSetAddresses; + + function setUp() public virtual override { + FunctionsRoutesSetup.setUp(); + + // Deploy new Coordinator contract + s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( + address(s_functionsRouter), + getCoordinatorConfig(), + address(s_linkEthFeed) + ); + + // Propose new Coordinator contract + s_proposedContractSetIds = new bytes32[](1); + s_proposedContractSetIds[0] = s_donId; + s_proposedContractSetAddresses = new address[](1); + s_proposedContractSetAddresses[0] = address(s_functionsCoordinator2); + } + + function test_ProposeContractsUpdate_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + vm.expectRevert("Only callable by owner"); + s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses); + } + + function test_ProposeContractsUpdate_RevertIfLengthMismatch() public { + bytes32[] memory proposedContractSetIds = new bytes32[](1); + proposedContractSetIds[0] = s_donId; + address[] memory proposedContractSetAddresses = new address[](1); + + vm.expectRevert(FunctionsRouter.InvalidProposal.selector); + s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses); + } + + function test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() public { + uint8 MAX_PROPOSAL_SET_LENGTH = 8; + uint8 INVALID_PROPOSAL_SET_LENGTH = MAX_PROPOSAL_SET_LENGTH + 1; + + // Generate some mock data + bytes32[] memory proposedContractSetIds = new bytes32[](INVALID_PROPOSAL_SET_LENGTH); + for (uint8 i = 0; i < INVALID_PROPOSAL_SET_LENGTH; ++i) { + proposedContractSetIds[i] = bytes32(uint256(i + 111)); + } + address[] memory proposedContractSetAddresses = new address[](INVALID_PROPOSAL_SET_LENGTH); + for (uint8 i = 0; i < INVALID_PROPOSAL_SET_LENGTH; ++i) { + proposedContractSetAddresses[i] = address(uint160(uint(keccak256(abi.encodePacked(i + 111))))); + } + + vm.expectRevert(FunctionsRouter.InvalidProposal.selector); + s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses); + } + + function test_ProposeContractsUpdate_RevertIfEmptyAddress() public { + bytes32[] memory proposedContractSetIds = new bytes32[](1); + proposedContractSetIds[0] = s_donId; + address[] memory proposedContractSetAddresses = new address[](1); + proposedContractSetAddresses[0] = address(0); + + vm.expectRevert(FunctionsRouter.InvalidProposal.selector); + s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses); + } + + function test_ProposeContractsUpdate_RevertIfNotNewContract() public { + bytes32[] memory proposedContractSetIds = new bytes32[](1); + proposedContractSetIds[0] = s_donId; + address[] memory proposedContractSetAddresses = new address[](1); + proposedContractSetAddresses[0] = address(s_functionsCoordinator); + + vm.expectRevert(FunctionsRouter.InvalidProposal.selector); + s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses); + } + + event ContractProposed( + bytes32 proposedContractSetId, + address proposedContractSetFromAddress, + address proposedContractSetToAddress + ); + + function test_ProposeContractsUpdate_Success() public { + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit ContractProposed({ + proposedContractSetId: s_proposedContractSetIds[0], + proposedContractSetFromAddress: address(s_functionsCoordinator), + proposedContractSetToAddress: s_proposedContractSetAddresses[0] + }); + + s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses); + } } /// @notice #updateContracts -contract FunctionsRouter_UpdateContracts { +contract FunctionsRouter_UpdateContracts is FunctionsRoutesSetup { + FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper + bytes32[] s_proposedContractSetIds; + address[] s_proposedContractSetAddresses; + + function setUp() public virtual override { + FunctionsRoutesSetup.setUp(); + + // Deploy new Coordinator contract + s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( + address(s_functionsRouter), + getCoordinatorConfig(), + address(s_linkEthFeed) + ); + + // Propose new Coordinator contract + s_proposedContractSetIds = new bytes32[](1); + s_proposedContractSetIds[0] = s_donId; + s_proposedContractSetAddresses = new address[](1); + s_proposedContractSetAddresses[0] = address(s_functionsCoordinator2); + + s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses); + } + + function test_UpdateContracts_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsRouter.updateContracts(); + } + + event ContractUpdated(bytes32 id, address from, address to); + + function test_UpdateContracts_Success() public { + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit ContractUpdated({ + id: s_proposedContractSetIds[0], + from: address(s_functionsCoordinator), + to: s_proposedContractSetAddresses[0] + }); + + s_functionsRouter.updateContracts(); + (bytes32[] memory proposedContractSetIds, address[] memory proposedContractSetAddresses) = s_functionsRouter + .getProposedContractSet(); + + assertEq(proposedContractSetIds.length, 0); + assertEq(proposedContractSetAddresses.length, 0); + } } /// @notice #_whenNotPaused -contract FunctionsRouter__WhenNotPaused { - +contract FunctionsRouter__WhenNotPaused is FunctionsRouterSetup { + // TODO: make contract internal function helper } /// @notice #_onlyRouterOwner -contract FunctionsRouter__OnlyRouterOwner { - +contract FunctionsRouter__OnlyRouterOwner is FunctionsRouterSetup { + // TODO: make contract internal function helper } /// @notice #_onlySenderThatAcceptedToS -contract FunctionsRouter__OnlySenderThatAcceptedToS { - +contract FunctionsRouter__OnlySenderThatAcceptedToS is FunctionsRouterSetup { + // TODO: make contract internal function helper } /// @notice #pause diff --git a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol index 4d49cb64054..361f9b2420a 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol @@ -11,7 +11,6 @@ import {TermsOfServiceAllowList} from "../../dev/1_0_0/accessControl/TermsOfServ import {FunctionsClientUpgradeHelper} from "./testhelpers/FunctionsClientUpgradeHelper.sol"; import {MockLinkToken} from "../../../mocks/MockLinkToken.sol"; -import "forge-std/console.sol"; import "forge-std/Vm.sol"; contract FunctionsRouterSetup is BaseTest { @@ -23,6 +22,7 @@ contract FunctionsRouterSetup is BaseTest { uint16 internal s_maxConsumersPerSubscription = 3; uint72 internal s_adminFee = 100; + uint72 internal s_donFee = 100; bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175; int256 internal LINK_ETH_RATE = 6000000000000000; @@ -59,7 +59,7 @@ contract FunctionsRouterSetup is BaseTest { }); } - function getCoordinatorConfig() public pure returns (FunctionsBilling.Config memory) { + function getCoordinatorConfig() public view returns (FunctionsBilling.Config memory) { return FunctionsBilling.Config({ maxCallbackGasLimit: 0, // NOTE: unused , TODO: remove @@ -67,7 +67,7 @@ contract FunctionsRouterSetup is BaseTest { gasOverheadAfterCallback: 44_615, // TODO: update gasOverheadBeforeCallback: 44_615, // TODO: update requestTimeoutSeconds: 60 * 5, // 5 minutes - donFee: 100, + donFee: s_donFee, maxSupportedRequestDataVersion: 1, fulfillmentGasPriceOverEstimationBP: 5000, fallbackNativePerUnitLink: 5000000000000000 @@ -196,9 +196,18 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { bytes memory secrets; string[] memory args = new string[](0); bytes[] memory bytesArgs = new bytes[](0); + uint32 callbackGasLimit = 5000; vm.recordLogs(); - s_requestId = s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000); + s_requestId = s_functionsClient.sendRequest( + s_donId, + sourceCode, + secrets, + args, + bytesArgs, + s_subscriptionId, + callbackGasLimit + ); // Get commitment data from OracleRequest event log Vm.Log[] memory entries = vm.getRecordedLogs(); From d9cddb8292539821cc0c5b0537a94d9e5a2d72cb Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Thu, 7 Sep 2023 21:15:23 +0100 Subject: [PATCH 57/88] Remove check block too new check (#10545) * Remove check block too new check * fix test * remove error type --- .../ocr2keeper/evm21/encoding/interface.go | 1 - .../evm21/registry_check_pipeline.go | 7 ------- .../evm21/registry_check_pipeline_test.go | 21 ++++--------------- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go index 9774ef4d968..58e82134bdf 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go @@ -42,7 +42,6 @@ const ( MercuryUnmarshalError PipelineExecutionState = 6 InvalidMercuryRequest PipelineExecutionState = 7 InvalidMercuryResponse PipelineExecutionState = 8 // this will only happen if Mercury server sends bad responses - CheckBlockTooNew PipelineExecutionState = 9 ) type UpkeepInfo = iregistry21.KeeperRegistryBase21UpkeepInfo diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go index cd77d573f09..7a8991193c4 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go @@ -99,13 +99,6 @@ func (r *EvmRegistry) getBlockHash(blockNumber *big.Int) (common.Hash, error) { // verifyCheckBlock checks that the check block and hash are valid, returns the pipeline execution state and retryable func (r *EvmRegistry) verifyCheckBlock(ctx context.Context, checkBlock, upkeepId *big.Int, checkHash common.Hash) (state encoding.PipelineExecutionState, retryable bool) { - // verify check block number is not in future (can happen when this node is lagging the other members in DON) - latestBlock := r.bs.latestBlock.Load() - if checkBlock.Int64() > int64(latestBlock.Number) { - r.lggr.Warnf("latest block is %d, check block number %s is in future for upkeepId %s", r.bs.latestBlock.Load(), checkBlock, upkeepId) - return encoding.CheckBlockTooNew, true // retryable since the block can be found in future - } - var h string var ok bool // verify check block number and hash are valid diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go index ae20ac14df6..152c912f70f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go @@ -85,20 +85,6 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { retryable bool makeEthCall bool }{ - { - name: "check block number too new", - checkBlock: big.NewInt(500), - latestBlock: ocr2keepers.BlockKey{Number: 400}, - upkeepId: big.NewInt(12345), - checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), - payload: ocr2keepers.UpkeepPayload{ - UpkeepID: upkeepId, - Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")), - WorkID: "work", - }, - state: encoding.CheckBlockTooNew, - retryable: true, - }, { name: "for an invalid check block number, if hash does not match the check hash, return CheckBlockInvalid", checkBlock: big.NewInt(500), @@ -389,7 +375,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { BlockNumber: 550, } - trigger0 := ocr2keepers.NewTrigger(590, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0")) + trigger0 := ocr2keepers.NewTrigger(575, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0")) trigger1 := ocr2keepers.NewLogTrigger(560, common.HexToHash("0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857"), extension1) trigger2 := ocr2keepers.NewLogTrigger(570, common.HexToHash("0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc"), extension2) @@ -429,12 +415,13 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { 550: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857", 560: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857", 570: "0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc", + 575: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857", }, latestBlock: ocr2keepers.BlockKey{Number: 580}, results: []ocr2keepers.CheckResult{ { - PipelineExecutionState: uint8(encoding.CheckBlockTooNew), - Retryable: true, + PipelineExecutionState: uint8(encoding.CheckBlockInvalid), + Retryable: false, Eligible: false, IneligibilityReason: 0, UpkeepID: uid0, From 247918e5259ab3df882d22804154230d47a44046 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Thu, 7 Sep 2023 15:39:46 -0500 Subject: [PATCH 58/88] core/services/vrf/v2: fix nolint comment (#10552) --- core/services/vrf/v2/integration_v2_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 3b85a524bac..a06920ece45 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -2140,10 +2140,10 @@ VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit sql = `INSERT INTO eth_tx_attempts (eth_tx_id, gas_price, signed_raw_tx, hash, state, created_at, chain_specific_gas_limit) VALUES (:eth_tx_id, :gas_price, :signed_raw_tx, :hash, :state, :created_at, :chain_specific_gas_limit)` for _, attempt := range txAttempts { - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt) //nolint:gosec - just copying fields + dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt) //nolint:gosec // just copying fields _, err = db.NamedExec(sql, &dbAttempt) require.NoError(t, err) - txmgr.DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt) //nolint:gosec - just copying fields + txmgr.DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt) //nolint:gosec // just copying fields } // add eth_receipts From a8c921b2c3f653a0f4928c739f3aa653636151b6 Mon Sep 17 00:00:00 2001 From: Ryan Hall Date: Thu, 7 Sep 2023 18:40:02 -0400 Subject: [PATCH 59/88] avoid logging if context is done (#10553) Co-authored-by: amirylm --- .../ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go index 6b89dfd0e72..50e7e85e3b6 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go @@ -143,6 +143,10 @@ func (p *logEventProvider) Start(context.Context) error { lggr.Warnw("readQ is full, dropping ids", "ids", ids) } }) + // if the context was canceled, we don't need to log the error + if ctx.Err() != nil { + return + } if err != nil { lggr.Warnw("stopped scheduling read jobs with error", "err", err) } From 81d1984de641a3ef61c88df6f4072d1223441111 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Thu, 7 Sep 2023 20:42:20 -0400 Subject: [PATCH 60/88] [Functions] Various housecleaning (#10509) * FunctionsBilling.sol remove unused maxCallbackGasLimit * FunctionsClient.sol handleOracleFulfillment emits RequestFulfilled * FunctionsRequest.sol remove unused requestSignature * (fix): FunctionsBilling.sol gas price is in wei, change variable name to reflect this * FunctionsRouter.sol prevent duplicate requestIds from Coordinator * Regenerate geth wrappers * (test): Remove test helper .addSignature * Changes from review * (test): Add unit tests for FunctionsBilling_EstimateCost and test_SendRequest_RevertIfDuplicateRequestId * (test): Fix test setup for extra fulfill event * Gethwrappers & test change from review * Update gas snapshot * (test): Remove MaxCallbackGasLimit from v1 integration test --- .../gas-snapshots/functions.gas-snapshot | 59 ++++++++--------- .../functions/dev/1_0_0/FunctionsBilling.sol | 23 ++++--- .../functions/dev/1_0_0/FunctionsClient.sol | 1 + .../functions/dev/1_0_0/FunctionsRouter.sol | 6 ++ .../1_0_0/interfaces/IFunctionsBilling.sol | 4 +- .../dev/1_0_0/libraries/FunctionsRequest.sol | 6 -- .../tests/1_0_0/FunctionsCoordinator.t.sol | 63 ++++++++++++++++++- .../tests/1_0_0/FunctionsRouter.t.sol | 57 ++++++++++++++++- .../v0.8/functions/tests/1_0_0/Setup.t.sol | 5 +- .../1_0_0/testhelpers/FunctionsTestHelper.sol | 7 --- .../test/v0.8/functions/v1/Functions.test.ts | 26 -------- contracts/test/v0.8/functions/v1/utils.ts | 2 - .../functions_client_example.go | 2 +- .../functions_coordinator.go | 23 ++++--- .../functions_load_test_client.go | 2 +- .../functions_router/functions_router.go | 4 +- ...rapper-dependency-versions-do-not-edit.txt | 8 +-- .../v1/internal/testutils.go | 1 - 18 files changed, 188 insertions(+), 111 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index e0d973ead2a..ad4b158a7ff 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,3 +1,5 @@ +FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32391) +FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 52979) FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13452) FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974) FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255) @@ -10,15 +12,15 @@ FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987) FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12073) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 48299) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 38870) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 38830) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 36239) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35161) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 165) FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28037) FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 33206) -FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 102749) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 1770949) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 206000) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 103393) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 1762917) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 205990) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17842) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12883) FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 31332) @@ -38,24 +40,25 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengt FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19047) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23348) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118768) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 58984) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57935) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186118) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 48426) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25066) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29162) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34231) -FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 197905) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65547) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 58977) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 192424) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29382) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57929) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186036) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 48353) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25038) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29088) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34224) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 197881) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65518) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36013) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29904) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 55012) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27532) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35747) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40817) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 204530) -FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192704) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29876) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 54984) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27504) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35718) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40788) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 204484) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192600) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30666) FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13402) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13294) @@ -79,7 +82,7 @@ FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubs FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57863) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89296) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20103) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193421) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193411) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_Success() (gas: 67209) FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7609) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28659) @@ -106,7 +109,7 @@ FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Reve FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 52817) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 47539) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 48847) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 162051) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 162049) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17946) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 165) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15577) @@ -114,7 +117,7 @@ FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54598) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37975) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14980) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175611) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175601) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27632) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57751) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15022) @@ -129,7 +132,7 @@ FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57778) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87210) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18004) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190641) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190639) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 41585) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12847) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15640) @@ -137,16 +140,16 @@ FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35571) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25881) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25210) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28164) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57781) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57759) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26368) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15714) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152510) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25855) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44366) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23615) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1469094) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1458273) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26021) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1549182) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1538361) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 94702) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 50442) diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol index 8e8607078e5..5ae302da86f 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol @@ -20,7 +20,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { using FunctionsResponse for FunctionsResponse.Commitment; using FunctionsResponse for FunctionsResponse.FulfillResult; - uint32 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000; + uint256 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000_000_000_000; // 1 million gwei // ================================================================ // | Request Commitment state | // ================================================================ @@ -34,15 +34,14 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // ================================================================ struct Config { - uint32 maxCallbackGasLimit; // ══════════════════╗ Maximum amount of gas that can be given to a request's client callback + uint32 fulfillmentGasPriceOverEstimationBP; // ══╗ Percentage of gas price overestimation to account for changes in gas price between request and response. Held as basis points (one hundredth of 1 percentage point) 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. uint32 requestTimeoutSeconds; // ║ How many seconds it takes before we consider a request to be timed out 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. uint16 maxSupportedRequestDataVersion; // ═══════╝ The highest support request data version supported by the node. All lower versions should also be supported. - uint32 fulfillmentGasPriceOverEstimationBP; // ══╗ Percentage of gas price overestimation to account for changes in gas price between request and response. Held as basis points (one hundredth of 1 percentage point) - uint224 fallbackNativePerUnitLink; // ═══════════╝ fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale + uint224 fallbackNativePerUnitLink; // ═══════════╸ fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale } Config private s_config; @@ -126,10 +125,10 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return uint256(weiPerUnitLink); } - function _getJuelsPerGas(uint256 gasPriceGwei) private view returns (uint96) { + function _getJuelsPerGas(uint256 gasPriceWei) private view returns (uint96) { // (1e18 juels/link) * (wei/gas) / (wei/link) = juels per gas // There are only 1e9*1e18 = 1e27 juels in existence, should not exceed uint96 (2^96 ~ 7e28) - return SafeCast.toUint96((1e18 * gasPriceGwei) / getWeiPerUnitLink()); + return SafeCast.toUint96((1e18 * gasPriceWei) / getWeiPerUnitLink()); } // ================================================================ @@ -141,16 +140,16 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint64 subscriptionId, bytes calldata data, uint32 callbackGasLimit, - uint256 gasPriceGwei + uint256 gasPriceWei ) external view override returns (uint96) { _getRouter().isValidCallbackGasLimit(subscriptionId, callbackGasLimit); // Reasonable ceilings to prevent integer overflows - if (gasPriceGwei > REASONABLE_GAS_PRICE_CEILING) { + if (gasPriceWei > REASONABLE_GAS_PRICE_CEILING) { revert InvalidCalldata(); } uint72 adminFee = getAdminFee(); uint72 donFee = getDONFee(data); - return _calculateCostEstimate(callbackGasLimit, gasPriceGwei, donFee, adminFee); + return _calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee); } // @notice Estimate the cost in Juels of LINK @@ -158,14 +157,14 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // Gas Price can be overestimated to account for flucuations between request and response time function _calculateCostEstimate( uint32 callbackGasLimit, - uint256 gasPriceGwei, + uint256 gasPriceWei, uint72 donFee, uint72 adminFee ) internal view returns (uint96) { uint256 executionGas = s_config.gasOverheadBeforeCallback + s_config.gasOverheadAfterCallback + callbackGasLimit; - uint256 gasPriceWithOverestimation = gasPriceGwei + - ((gasPriceGwei * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000); + uint256 gasPriceWithOverestimation = gasPriceWei + + ((gasPriceWei * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000); // @NOTE: Basis Points are 1/100th of 1%, divide by 10_000 to bring back to original units uint96 juelsPerGas = _getJuelsPerGas(gasPriceWithOverestimation); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol index b7f676c2327..41db3e98b29 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol @@ -57,5 +57,6 @@ abstract contract FunctionsClient is IFunctionsClient { revert OnlyRouterCanFulfill(); } fulfillRequest(requestId, response, err); + emit RequestFulfilled(requestId); } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol index 46f6929fabc..4ec25985802 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol @@ -62,6 +62,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, error SenderMustAcceptTermsOfService(address sender); error InvalidGasFlagValue(uint8 value); error GasLimitTooBig(uint32 limit); + error DuplicateRequestId(bytes32 requestId); struct CallbackResult { bool success; // ══════╸ Whether the callback succeeded or not @@ -244,6 +245,11 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, }) ); + // Do not allow setting a comittment for a requestId that already exists + if (s_requestCommitments[commitment.requestId] != bytes32(0)) { + revert DuplicateRequestId(commitment.requestId); + } + // Store a commitment about the request s_requestCommitments[commitment.requestId] = keccak256( abi.encode( diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol index 00ff17ee14d..44f4c62da81 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol @@ -20,13 +20,13 @@ interface IFunctionsBilling { // @param - subscriptionId An identifier of the billing account // @param - data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request // @param - callbackGasLimit Gas limit for the fulfillment callback - // @param - gasPriceGwei The blockchain's gas price to estimate with + // @param - gasPriceWei The blockchain's gas price to estimate with // @return - billedCost Cost in Juels (1e18) of LINK function estimateCost( uint64 subscriptionId, bytes calldata data, uint32 callbackGasLimit, - uint256 gasPriceGwei + uint256 gasPriceWei ) external view returns (uint96); // @notice Remove a request commitment that the Router has determined to be stale diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol index 0a669588ed0..76b83a998bd 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol @@ -27,7 +27,6 @@ library FunctionsRequest { CodeLanguage language; // ════════════╸ The coding language that the source code is written in string source; // ════════════════════╸ Raw source code for Request.codeLocation of Location.Inline, URL for Request.codeLocation of Location.Remote, or slot decimal number for Request.codeLocation of Location.DONHosted bytes encryptedSecretsReference; // ══╸ Encrypted URLs for Request.secretsLocation of Location.Remote (use addSecretsReference()), or CBOR encoded slotid+version for Request.secretsLocation of Location.DONHosted (use addDONHostedSecrets()) - bytes requestSignature; // ═══════════╸ Signature generated by the subscription owner's EOA string[] args; // ════════════════════╸ String arguments that will be passed into the source code bytes[] bytesArgs; // ════════════════╸ Bytes arguments that will be passed into the source code } @@ -52,11 +51,6 @@ library FunctionsRequest { buffer.writeString("source"); buffer.writeString(self.source); - if (self.requestSignature.length > 0) { - buffer.writeString("requestSignature"); - buffer.writeBytes(self.requestSignature); - } - if (self.args.length > 0) { buffer.writeString("args"); buffer.startArray(); diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol index c6d560fffc6..8ab936e5033 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol @@ -1,6 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {FunctionsCoordinator} from "../../dev/1_0_0/FunctionsCoordinator.sol"; +import {FunctionsBilling} from "../../dev/1_0_0/FunctionsBilling.sol"; +import {FunctionsRequest} from "../../dev/1_0_0/libraries/FunctionsRequest.sol"; + +import {FunctionsSubscriptionSetup} from "./Setup.t.sol"; + // ================================================================ // | Functions Coordinator | // ================================================================ @@ -115,8 +121,61 @@ contract FunctionsBilling__GetJuelsPerGas { } /// @notice #estimateCost -contract FunctionsBilling_EstimateCost { - +contract FunctionsBilling_EstimateCost is FunctionsSubscriptionSetup { + function setUp() public virtual override { + FunctionsSubscriptionSetup.setUp(); + + // Get cost estimate as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + } + + uint256 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000_000_000_000; // 1 million gwei + + function test_EstimateCost_RevertsIfGasPriceAboveCeiling() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint32 callbackGasLimit = 5_500; + uint256 gasPriceWei = REASONABLE_GAS_PRICE_CEILING + 1; + + vm.expectRevert(FunctionsBilling.InvalidCalldata.selector); + + s_functionsCoordinator.estimateCost(s_subscriptionId, requestData, callbackGasLimit, gasPriceWei); + } + + function test_EstimateCost_Success() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + uint32 callbackGasLimit = 5_500; + uint256 gasPriceWei = 1; + + uint96 costEstimate = s_functionsCoordinator.estimateCost( + s_subscriptionId, + requestData, + callbackGasLimit, + gasPriceWei + ); + uint96 expectedCostEstimate = 15725380; + assertEq(costEstimate, expectedCostEstimate); + } } /// @notice #_calculateCostEstimate diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol index 742a471cb58..c6295943df1 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.19; import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol"; +import {FunctionsCoordinator} from "../../dev/1_0_0/FunctionsCoordinator.sol"; import {FunctionsBilling} from "../../dev/1_0_0/FunctionsBilling.sol"; import {FunctionsRequest} from "../../dev/1_0_0/libraries/FunctionsRequest.sol"; import {FunctionsResponse} from "../../dev/1_0_0/libraries/FunctionsResponse.sol"; @@ -380,6 +381,59 @@ contract FunctionsRouter_SendRequest is FunctionsSubscriptionSetup { ); } + function test_SendRequest_RevertIfDuplicateRequestId() public { + // Build minimal valid request data + string memory sourceCode = "return 'hello world';"; + FunctionsRequest.Request memory request; + FunctionsRequest.initializeRequest( + request, + FunctionsRequest.Location.Inline, + FunctionsRequest.CodeLanguage.JavaScript, + sourceCode + ); + uint32 callbackGasLimit = 5_000; + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + + // Send a first request that will remain pending + bytes32 requestId = s_functionsRouter.sendRequest( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + s_donId + ); + + // Mock the Coordinator to always give back the first requestId + FunctionsResponse.Commitment memory mockCommitment = FunctionsResponse.Commitment({ + adminFee: s_adminFee, + coordinator: address(s_functionsCoordinator), + client: OWNER_ADDRESS, + subscriptionId: s_subscriptionId, + callbackGasLimit: callbackGasLimit, + estimatedTotalCostJuels: 0, + timeoutTimestamp: uint32(block.timestamp + getCoordinatorConfig().requestTimeoutSeconds), + requestId: requestId, + donFee: s_donFee, + gasOverheadBeforeCallback: getCoordinatorConfig().gasOverheadBeforeCallback, + gasOverheadAfterCallback: getCoordinatorConfig().gasOverheadAfterCallback + }); + + vm.mockCall( + address(s_functionsCoordinator), + abi.encodeWithSelector(FunctionsCoordinator.startRequest.selector), + abi.encode(mockCommitment) + ); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.DuplicateRequestId.selector, requestId)); + s_functionsRouter.sendRequest( + s_subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + s_donId + ); + } + event RequestStart( bytes32 indexed requestId, bytes32 indexed donId, @@ -1147,7 +1201,6 @@ contract FunctionsRouter_Fulfill is FunctionsClientRequestSetup { uint96 juelsPerGas = 0; uint96 costWithoutCallback = 0; address transmitter = NOP_TRANSMITTER_ADDRESS_1; - FunctionsResponse.Commitment memory commitment = s_requestCommitment; // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). bool checkTopic1 = false; @@ -1174,7 +1227,7 @@ contract FunctionsRouter_Fulfill is FunctionsClientRequestSetup { juelsPerGas, costWithoutCallback, transmitter, - commitment + s_requestCommitment ); assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.FULFILLED)); diff --git a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol index 361f9b2420a..638e369b90b 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol @@ -62,7 +62,6 @@ contract FunctionsRouterSetup is BaseTest { function getCoordinatorConfig() public view returns (FunctionsBilling.Config memory) { return FunctionsBilling.Config({ - maxCallbackGasLimit: 0, // NOTE: unused , TODO: remove feedStalenessSeconds: 24 * 60 * 60, // 1 day gasOverheadAfterCallback: 44_615, // TODO: update gasOverheadBeforeCallback: 44_615, // TODO: update @@ -196,7 +195,7 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { bytes memory secrets; string[] memory args = new string[](0); bytes[] memory bytesArgs = new bytes[](0); - uint32 callbackGasLimit = 5000; + uint32 callbackGasLimit = 5500; vm.recordLogs(); s_requestId = s_functionsClient.sendRequest( @@ -254,7 +253,7 @@ contract FunctionsFulfillmentSetup is FunctionsClientRequestSetup { // Get actual cost from RequestProcessed event log Vm.Log[] memory entries = vm.getRecordedLogs(); (uint96 totalCostJuels, , , , , ) = abi.decode( - entries[1].data, + entries[2].data, (uint96, address, FunctionsResponse.FulfillResult, bytes, bytes, bytes) ); // totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol index 57ae6e0bbad..73f10071dbc 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol @@ -41,12 +41,6 @@ contract FunctionsTestHelper { storeRequest(r); } - function addSignature(bytes memory signature) public { - FunctionsRequest.Request memory r = s_req; - r.requestSignature = signature; - storeRequest(r); - } - function storeRequest(FunctionsRequest.Request memory r) private { s_req.codeLocation = r.codeLocation; s_req.language = r.language; @@ -54,6 +48,5 @@ contract FunctionsTestHelper { s_req.args = r.args; s_req.secretsLocation = r.secretsLocation; s_req.encryptedSecretsReference = r.encryptedSecretsReference; - s_req.requestSignature = r.requestSignature; } } diff --git a/contracts/test/v0.8/functions/v1/Functions.test.ts b/contracts/test/v0.8/functions/v1/Functions.test.ts index b0128b90204..981b3227073 100644 --- a/contracts/test/v0.8/functions/v1/Functions.test.ts +++ b/contracts/test/v0.8/functions/v1/Functions.test.ts @@ -41,7 +41,6 @@ describe('FunctionsTestHelper', () => { 'addSecretsReference', 'addTwoArgs', 'addEmptyArgs', - 'addSignature', ]), ).to.equal(true) }) @@ -170,29 +169,4 @@ describe('FunctionsTestHelper', () => { await expect(ctr.addEmptyArgs()).to.be.revertedWith('EmptyArgs()') }) }) - - describe('#addSignature', () => { - it('emits CBOR encoded request with js source and signature', async () => { - const signatureHex = 'aabbccddeeff' - const js = 'function run(args, responses) {}' - await ctr.initializeRequestForInlineJavaScript(js) - await ctr.addSignature('0x' + signatureHex) - const tx = await ctr.closeEvent() - const [payload] = await parseRequestDataEvent(tx) - const decoded = await decodeDietCBOR(payload) - assert.deepEqual( - { - ...decoded, - language: decoded.language.toNumber(), - codeLocation: decoded.codeLocation.toNumber(), - }, - { - language: 0, - codeLocation: 0, - source: js, - requestSignature: Buffer.from(signatureHex, 'hex'), - }, - ) - }) - }) }) diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts index a7a89871f32..1107858e6b8 100644 --- a/contracts/test/v0.8/functions/v1/utils.ts +++ b/contracts/test/v0.8/functions/v1/utils.ts @@ -86,7 +86,6 @@ export const functionsRouterConfig: FunctionsRouterConfig = { gasForCallExactCheck: 5000, } export type CoordinatorConfig = { - maxCallbackGasLimit: number feedStalenessSeconds: number gasOverheadBeforeCallback: number gasOverheadAfterCallback: number @@ -98,7 +97,6 @@ export type CoordinatorConfig = { } const fallbackNativePerUnitLink = 5000000000000000 export const coordinatorConfig: CoordinatorConfig = { - maxCallbackGasLimit: 1_000_000, feedStalenessSeconds: 86_400, gasOverheadBeforeCallback: 44_615, gasOverheadAfterCallback: 44_615, diff --git a/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go b/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go index 6dc02520146..6ae90b45edb 100644 --- a/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go +++ b/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go @@ -32,7 +32,7 @@ var ( var FunctionsClientExampleMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedRequestID\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001a7638038062001a76833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b6080516118a1620001d5600039600081816101c60152610a2a01526118a16000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112ed565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e16101433660046113c0565b61022d565b6101176201117081565b6100e1610347565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e16101993660046114a4565b610449565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61022883838361045d565b505050565b61023561052b565b61027e6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6102c089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105ae9050565b85156103085761030887878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105bf9050565b83156103225761032261031b85876114da565b8290610609565b61033961032e8261064c565b846201117085610a25565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61045161052b565b61045a81610b04565b50565b826002541461049b576040517fd068bf5b000000000000000000000000000000000000000000000000000000008152600481018490526024016103c4565b6104a482610bf9565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104e681610bf9565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c4565b565b6105bb8260008084610c7b565b5050565b80516000036105fa576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610644576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b6060600061065b610100610d12565b90506106a56040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610d3390919063ffffffff16565b82516106c39060028111156106bc576106bc611572565b8290610d4c565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610702908290610d33565b60408301516107199080156106bc576106bc611572565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610758908290610d33565b6060830151610768908290610d33565b60a083015151156107c25760408051808201909152601081527f726571756573745369676e61747572650000000000000000000000000000000060208201526107b2908290610d33565b60a08301516107c2908290610d81565b60c0830151511561086f5760408051808201909152600481527f6172677300000000000000000000000000000000000000000000000000000000602082015261080c908290610d33565b61081581610d8e565b60005b8360c0015151811015610865576108558460c00151828151811061083e5761083e6115a1565b602002602001015183610d3390919063ffffffff16565b61085e816115ff565b9050610818565b5061086f81610db2565b608083015151156109705760008360200151600281111561089257610892611572565b036108c9576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610908908290610d33565b610921836020015160028111156106bc576106bc611572565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610960908290610d33565b6080830151610970908290610d81565b60e08301515115610a1d5760408051808201909152600981527f627974657341726773000000000000000000000000000000000000000000000060208201526109ba908290610d33565b6109c381610d8e565b60005b8360e0015151811015610a1357610a038460e0015182815181106109ec576109ec6115a1565b602002602001015183610d8190919063ffffffff16565b610a0c816115ff565b90506109c6565b50610a1d81610db2565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a8a959493929190611637565b6020604051808303816000875af1158015610aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acd91906116d7565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610c0e575081515b60005b81811015610c7457610c248160086116f0565b848281518110610c3657610c366115a1565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c6d816115ff565b9050610c11565b5050919050565b8051600003610cb6576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610cc957610cc9611572565b90816002811115610cdc57610cdc611572565b90525060408401828015610cf257610cf2611572565b90818015610d0257610d02611572565b9052506060909301929092525050565b610d1a6111a4565b8051610d269083610dd0565b5060006020820152919050565b610d408260038351610e4a565b81516102289082610f71565b8151610d599060c2610f99565b506105bb8282604051602001610d7191815260200190565b6040516020818303038152906040525b610d408260028351610e4a565b610d99816004611002565b600181602001818151610dac9190611707565b90525050565b610dbd816007611002565b600181602001818151610dac919061171a565b604080518082019091526060815260006020820152610df060208361172d565b15610e1857610e0060208361172d565b610e0b90602061171a565b610e159083611707565b91505b602080840183905260405180855260008152908184010181811015610e3c57600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e77578251610e719060e0600585901b168317610f99565b50505050565b60ff8167ffffffffffffffff1611610eb9578251610ea0906018611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166001611019565b61ffff8167ffffffffffffffff1611610efc578251610ee3906019611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166002611019565b63ffffffff8167ffffffffffffffff1611610f41578251610f2890601a611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166004611019565b8251610f5890601b611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166008611019565b604080518082019091526060815260006020820152610f928383845161109e565b9392505050565b6040805180820190915260608152600060208201528251516000610fbe826001611707565b905084602001518210610fdf57610fdf85610fda8360026116f0565b61118d565b8451602083820101858153508051821115610ff8578181525b5093949350505050565b815161022890601f611fe0600585901b1617610f99565b604080518082019091526060815260006020820152835151600061103d8285611707565b9050856020015181111561105a5761105a86610fda8360026116f0565b6000600161106a86610100611888565b611074919061171a565b90508651828101878319825116178152508051831115611092578281525b50959695505050505050565b60408051808201909152606081526000602082015282518211156110c157600080fd5b83515160006110d08483611707565b905085602001518111156110ed576110ed86610fda8360026116f0565b855180518382016020019160009180851115611107578482525b505050602086015b602086106111475780518252611126602083611707565b9150611133602082611707565b905061114060208761171a565b955061110f565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516111998383610dd0565b50610e718382610f71565b60405180604001604052806111cc604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561124f5761124f6111d9565b604052919050565b600067ffffffffffffffff831115611271576112716111d9565b6112a260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611208565b90508281528383830111156112b657600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112de57600080fd5b610f9283833560208501611257565b60008060006060848603121561130257600080fd5b83359250602084013567ffffffffffffffff8082111561132157600080fd5b61132d878388016112cd565b9350604086013591508082111561134357600080fd5b50611350868287016112cd565b9150509250925092565b60008083601f84011261136c57600080fd5b50813567ffffffffffffffff81111561138457600080fd5b60208301915083602082850101111561139c57600080fd5b9250929050565b803567ffffffffffffffff811681146113bb57600080fd5b919050565b60008060008060008060008060a0898b0312156113dc57600080fd5b883567ffffffffffffffff808211156113f457600080fd5b6114008c838d0161135a565b909a50985060208b013591508082111561141957600080fd5b6114258c838d0161135a565b909850965060408b013591508082111561143e57600080fd5b818b0191508b601f83011261145257600080fd5b81358181111561146157600080fd5b8c60208260051b850101111561147657600080fd5b60208301965080955050505061148e60608a016113a3565b9150608089013590509295985092959890939650565b6000602082840312156114b657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f9257600080fd5b600067ffffffffffffffff808411156114f5576114f56111d9565b8360051b6020611506818301611208565b86815291850191818101903684111561151e57600080fd5b865b84811015611566578035868111156115385760008081fd5b880136601f82011261154a5760008081fd5b611558368235878401611257565b845250918301918301611520565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611630576116306115d0565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156116755788810183015185820160c001528201611659565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050506116be604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116e957600080fd5b5051919050565b8082028115828204841417610e4457610e446115d0565b80820180821115610e4457610e446115d0565b81810381811115610e4457610e446115d0565b600082611763577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b808511156117c157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156117a7576117a76115d0565b808516156117b457918102915b93841c939080029061176d565b509250929050565b6000826117d857506001610e44565b816117e557506000610e44565b81600181146117fb576002811461180557611821565b6001915050610e44565b60ff841115611816576118166115d0565b50506001821b610e44565b5060208310610133831016604e8410600b8410161715611844575081810a610e44565b61184e8383611768565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611880576118806115d0565b029392505050565b6000610f9283836117c956fea164736f6c6343000813000a", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001a4838038062001a48833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051611873620001d5600039600081816101c601526109f301526118736000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112bf565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e1610143366004611392565b610258565b6101176201117081565b6100e161036a565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e1610199366004611476565b61046c565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610228838383610480565b60405183907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a2505050565b61026061054e565b6102a16040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6102e389898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105d19050565b851561032b5761032b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105e29050565b83156103455761034561033e85876114ac565b829061062c565b61035c6103518261066f565b8462011170856109ee565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61047461054e565b61047d81610acd565b50565b82600254146104be576040517fd068bf5b000000000000000000000000000000000000000000000000000000008152600481018490526024016103e7565b6104c782610bc2565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90921691909117905561050981610bc2565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103e7565b565b6105de8260008084610c44565b5050565b805160000361061d576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610667576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b6060600061067e610100610cdb565b90506106c86040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610cfc90919063ffffffff16565b82516106e69060028111156106df576106df611544565b8290610d1a565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610725908290610cfc565b604083015161073c9080156106df576106df611544565b60408051808201909152600681527f736f757263650000000000000000000000000000000000000000000000000000602082015261077b908290610cfc565b606083015161078b908290610cfc565b60a083015151156108385760408051808201909152600481527f617267730000000000000000000000000000000000000000000000000000000060208201526107d5908290610cfc565b6107de81610d53565b60005b8360a001515181101561082e5761081e8460a00151828151811061080757610807611573565b602002602001015183610cfc90919063ffffffff16565b610827816115d1565b90506107e1565b5061083881610d77565b608083015151156109395760008360200151600281111561085b5761085b611544565b03610892576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e000000000000000000000000000000000060208201526108d1908290610cfc565b6108ea836020015160028111156106df576106df611544565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610929908290610cfc565b6080830151610939908290610d95565b60c083015151156109e65760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610983908290610cfc565b61098c81610d53565b60005b8360c00151518110156109dc576109cc8460c0015182815181106109b5576109b5611573565b602002602001015183610d9590919063ffffffff16565b6109d5816115d1565b905061098f565b506109e681610d77565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a53959493929190611609565b6020604051808303816000875af1158015610a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9691906116a9565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103e7565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610bd7575081515b60005b81811015610c3d57610bed8160086116c2565b848281518110610bff57610bff611573565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c36816115d1565b9050610bda565b5050919050565b8051600003610c7f576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610c9257610c92611544565b90816002811115610ca557610ca5611544565b90525060408401828015610cbb57610cbb611544565b90818015610ccb57610ccb611544565b9052506060909301929092525050565b610ce3611176565b8051610cef9083610da2565b5060006020820152919050565b610d098260038351610e1c565b8151610d159082610f43565b505050565b8151610d279060c2610f6b565b506105de8282604051602001610d3f91815260200190565b604051602081830303815290604052610d95565b610d5e816004610fd4565b600181602001818151610d7191906116d9565b90525050565b610d82816007610fd4565b600181602001818151610d7191906116ec565b610d098260028351610e1c565b604080518082019091526060815260006020820152610dc26020836116ff565b15610dea57610dd26020836116ff565b610ddd9060206116ec565b610de790836116d9565b91505b602080840183905260405180855260008152908184010181811015610e0e57600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e49578251610e439060e0600585901b168317610f6b565b50505050565b60ff8167ffffffffffffffff1611610e8b578251610e72906018611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166001610feb565b61ffff8167ffffffffffffffff1611610ece578251610eb5906019611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166002610feb565b63ffffffff8167ffffffffffffffff1611610f13578251610efa90601a611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166004610feb565b8251610f2a90601b611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166008610feb565b604080518082019091526060815260006020820152610f6483838451611070565b9392505050565b6040805180820190915260608152600060208201528251516000610f908260016116d9565b905084602001518210610fb157610fb185610fac8360026116c2565b61115f565b8451602083820101858153508051821115610fca578181525b5093949350505050565b8151610d1590601f611fe0600585901b1617610f6b565b604080518082019091526060815260006020820152835151600061100f82856116d9565b9050856020015181111561102c5761102c86610fac8360026116c2565b6000600161103c8661010061185a565b61104691906116ec565b90508651828101878319825116178152508051831115611064578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561109357600080fd5b83515160006110a284836116d9565b905085602001518111156110bf576110bf86610fac8360026116c2565b8551805183820160200191600091808511156110d9578482525b505050602086015b6020861061111957805182526110f86020836116d9565b91506111056020826116d9565b90506111126020876116ec565b95506110e1565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b815161116b8383610da2565b50610e438382610f43565b604051806040016040528061119e604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611221576112216111ab565b604052919050565b600067ffffffffffffffff831115611243576112436111ab565b61127460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116016111da565b905082815283838301111561128857600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112b057600080fd5b610f6483833560208501611229565b6000806000606084860312156112d457600080fd5b83359250602084013567ffffffffffffffff808211156112f357600080fd5b6112ff8783880161129f565b9350604086013591508082111561131557600080fd5b506113228682870161129f565b9150509250925092565b60008083601f84011261133e57600080fd5b50813567ffffffffffffffff81111561135657600080fd5b60208301915083602082850101111561136e57600080fd5b9250929050565b803567ffffffffffffffff8116811461138d57600080fd5b919050565b60008060008060008060008060a0898b0312156113ae57600080fd5b883567ffffffffffffffff808211156113c657600080fd5b6113d28c838d0161132c565b909a50985060208b01359150808211156113eb57600080fd5b6113f78c838d0161132c565b909850965060408b013591508082111561141057600080fd5b818b0191508b601f83011261142457600080fd5b81358181111561143357600080fd5b8c60208260051b850101111561144857600080fd5b60208301965080955050505061146060608a01611375565b9150608089013590509295985092959890939650565b60006020828403121561148857600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f6457600080fd5b600067ffffffffffffffff808411156114c7576114c76111ab565b8360051b60206114d88183016111da565b8681529185019181810190368411156114f057600080fd5b865b848110156115385780358681111561150a5760008081fd5b880136601f82011261151c5760008081fd5b61152a368235878401611229565b8452509183019183016114f2565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611602576116026115a2565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156116475788810183015185820160c00152820161162b565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050611690604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116bb57600080fd5b5051919050565b8082028115828204841417610e1657610e166115a2565b80820180821115610e1657610e166115a2565b81810381811115610e1657610e166115a2565b600082611735577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b8085111561179357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611779576117796115a2565b8085161561178657918102915b93841c939080029061173f565b509250929050565b6000826117aa57506001610e16565b816117b757506000610e16565b81600181146117cd57600281146117d7576117f3565b6001915050610e16565b60ff8411156117e8576117e86115a2565b50506001821b610e16565b5060208310610133831016604e8410600b8410161715611816575081810a610e16565b611820838361173a565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611852576118526115a2565b029392505050565b6000610f64838361179b56fea164736f6c6343000813000a", } var FunctionsClientExampleABI = FunctionsClientExampleMetaData.ABI diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index e1f6b2f7c15..a66c6bc3685 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -31,14 +31,13 @@ var ( ) type FunctionsBillingConfig struct { - MaxCallbackGasLimit uint32 + FulfillmentGasPriceOverEstimationBP uint32 FeedStalenessSeconds uint32 GasOverheadBeforeCallback uint32 GasOverheadAfterCallback uint32 RequestTimeoutSeconds uint32 DonFee *big.Int MaxSupportedRequestDataVersion uint16 - FulfillmentGasPriceOverEstimationBP uint32 FallbackNativePerUnitLink *big.Int } @@ -71,8 +70,8 @@ type FunctionsResponseRequestMeta struct { } var FunctionsCoordinatorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":[],\"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\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"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\":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\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"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\":\"gasPriceGwei\",\"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\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b50604051620051b4380380620051b483398101604081905262000034916200044f565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b50505050505062000600565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033a565b80516008805460208401516040808601516060870151608088015160a089015160c08a015163ffffffff998a166001600160401b031990981697909717640100000000968a16870217600160401b600160801b03191668010000000000000000948a169490940263ffffffff60601b1916939093176c010000000000000000000000009289169290920291909117600160801b600160e81b031916600160801b91881691909102600160a01b600160e81b03191617600160a01b6001600160481b03909216919091021761ffff60e81b1916600160e81b61ffff909416939093029290921790925560e084015161010085015193166001600160e01b0390931690910291909117600955517f5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c906200032f90839062000558565b60405180910390a150565b6200034462000346565b565b6000546001600160a01b03163314620003445760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003ba57600080fd5b919050565b60405161012081016001600160401b0381118282101715620003f157634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff81168114620003ba57600080fd5b80516001600160481b0381168114620003ba57600080fd5b805161ffff81168114620003ba57600080fd5b80516001600160e01b0381168114620003ba57600080fd5b60008060008385036101608112156200046757600080fd5b6200047285620003a2565b935061012080601f19830112156200048957600080fd5b62000493620003bf565b9150620004a360208701620003f7565b8252620004b360408701620003f7565b6020830152620004c660608701620003f7565b6040830152620004d960808701620003f7565b6060830152620004ec60a08701620003f7565b6080830152620004ff60c087016200040c565b60a08301526200051260e0870162000424565b60c083015261010062000527818801620003f7565b60e08401526200053982880162000437565b908301525091506200054f6101408501620003a2565b90509250925092565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a0830151620005b760a08401826001600160481b03169052565b5060c0830151620005ce60c084018261ffff169052565b5060e0830151620005e760e084018263ffffffff169052565b50610100928301516001600160e01b0316919092015290565b60805160a051614b6462000650600039600081816108060152818161099401528181610c7d01528181610f130152818161104a01528181611834015261329b015260006112720152614b646000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806381ff7048116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e7121461054e578063e4ddcea614610561578063f2fde38b1461057757600080fd5b8063c3f909d4146103c4578063d227d24514610516578063d328a91e1461054657600080fd5b8063a631571e116100bd578063a631571e14610371578063afcb95d714610391578063b1dc65a4146103b157600080fd5b806381ff7048146102b957806385b214cf146103265780638da5cb5b1461034957600080fd5b806366316d8d116101455780637f15e1661161011f5780637f15e16614610289578063814118341461029c57806381f1b938146102b157600080fd5b806366316d8d1461026657806379ba5097146102795780637d4807871461028157600080fd5b80631bdf7f1b116101765780631bdf7f1b146101f95780632a905ccc1461020c57806359b5b7ac1461022e57600080fd5b8063083a546614610192578063181f5a77146101a7575b600080fd5b6101a56101a036600461358e565b61058a565b005b6101e36040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f09190613634565b60405180910390f35b6101a5610207366004613797565b6105df565b610214610802565b60405168ffffffffffffffffff90911681526020016101f0565b61021461023c3660046138db565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101a561027436600461396a565b610898565b6101a5610a51565b6101a5610b53565b6101a561029736600461358e565b610d69565b6102a4610db9565b6040516101f091906139f4565b6101e3610e28565b61030360015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f0565b610339610334366004613a07565b610ef9565b60405190151581526020016101f0565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61038461037f366004613a20565b610fd9565b6040516101f09190613b75565b6040805160018152600060208201819052918101919091526060016101f0565b6101a56103bf366004613bc9565b611179565b6105096040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216948401949094526c0100000000000000000000000082048116606084015270010000000000000000000000000000000082048116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08401527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c083015260095490811660e0830152919091047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661010082015290565b6040516101f09190613c80565b610529610524366004613d63565b611830565b6040516bffffffffffffffffffffffff90911681526020016101f0565b6101e361198f565b6101a561055c366004613e7c565b6119e6565b610569612412565b6040519081526020016101f0565b6101a5610585366004613f49565b612643565b610592612657565b60008190036105cd576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105da828483613fff565b505050565b6105e76126da565b80516008805460208401516040808601516060870151608088015160a089015160c08a015163ffffffff998a167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090981697909717640100000000968a168702177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1668010000000000000000948a16949094027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16939093176c0100000000000000000000000092891692909202919091177fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000918816919091027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff16177401000000000000000000000000000000000000000068ffffffffffffffffff90921691909102177fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d01000000000000000000000000000000000000000000000000000000000061ffff909416939093029290921790925560e084015161010085015193167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90931690910291909117600955517f5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c906107f7908390613c80565b60405180910390a150565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108939190614125565b905090565b6108a06126e2565b806bffffffffffffffffffffffff166000036108da5750336000908152600a60205260409020546bffffffffffffffffffffffff16610934565b336000908152600a60205260409020546bffffffffffffffffffffffff80831691161015610934576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906109619084906bffffffffffffffffffffffff16614171565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506109b67f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610a3557600080fd5b505af1158015610a49573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ad7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b5b6126da565b610b636126e2565b6000610b6d610db9565b905060005b8151811015610d65576000600a6000848481518110610b9357610b93614196565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff1690506000600a6000858581518110610c0857610c08614196565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610c9f7f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610ccc57610ccc614196565b6020026020010151836040518363ffffffff1660e01b8152600401610d2192919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d3b57600080fd5b505af1158015610d4f573d6000803e3d6000fd5b505050505080610d5e906141c5565b9050610b72565b5050565b610d71612657565b6000819003610dac576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105da828483613fff565b60606006805480602002602001604051908101604052809291908181526020018280548015610e1e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610df3575b5050505050905090565b6060600d8054610e3790613f66565b9050600003610e72576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610e7f90613f66565b80601f0160208091040260200160405190810160405280929190818152602001828054610eab90613f66565b8015610e1e5780601f10610ecd57610100808354040283529160200191610e1e565b820191906000526020600020905b815481529060010190602001808311610edb57509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f6a576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260076020526040902054610f8557506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610fc89084815260200190565b60405180910390a15060015b919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146110a1576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110b26110ad836141fd565b61288d565b90506110c46060830160408401613f49565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261111260c0870160a088016142ea565b61112461016088016101408901613f49565b61112e8880614307565b6111406101208b016101008c0161436c565b60208b01356111566101008d0160e08e01614387565b8b60405161116c999897969594939291906143a4565b60405180910390a3919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610ace565b61126e8b8b8b8b8b8b612c9d565b60007f0000000000000000000000000000000000000000000000000000000000000000156112cb576002826020015183604001516112ac919061444c565b6112b69190614494565b6112c190600161444c565b60ff1690506112e1565b60208201516112db90600161444c565b60ff1690505b88811461134a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610ace565b8887146113b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610ace565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113f6576113f66144b6565b6002811115611407576114076144b6565b9052509050600281602001516002811115611424576114246144b6565b14801561146b57506006816000015160ff168154811061144657611446614196565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6114d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610ace565b50505050506114de613526565b6000808a8a6040516114f19291906144e5565b604051908190038120611508918e906020016144f5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b8981101561181257600060018489846020811061157157611571614196565b61157e91901a601b61444c565b8e8e8681811061159057611590614196565b905060200201358d8d878181106115a9576115a9614196565b90506020020135604051600081526020016040526040516115e6949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611608573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff80821685529296509294508401916101009004166002811115611688576116886144b6565b6002811115611699576116996144b6565b90525092506001836020015160028111156116b6576116b66144b6565b1461171d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610ace565b8251600090879060ff16601f811061173757611737614196565b602002015173ffffffffffffffffffffffffffffffffffffffff16146117b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610ace565b8086846000015160ff16601f81106117d3576117d3614196565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526117fe60018661444c565b9450508061180b906141c5565b9050611552565b505050611823833383858e8e612d54565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b1580156118d057600080fd5b505afa1580156118e4573d6000803e3d6000fd5b505050620f42408311159050611926576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611930610802565b9050600061197387878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061023c92505050565b905061198185858385612f22565b925050505b95945050505050565b6060600c805461199e90613f66565b90506000036119d9576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610e7f90613f66565b855185518560ff16601f831115611a59576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610ace565b80600003611ac3576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610ace565b818314611b51576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610ace565b611b5c816003614509565b8311611bc4576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610ace565b611bcc612657565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611c13908861300c565b60055415611dc857600554600090611c2d90600190614520565b9050600060058281548110611c4457611c44614196565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611c7e57611c7e614196565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611cfe57611cfe614533565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611d6757611d67614533565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611c13915050565b60005b81515181101561222f5760006004600084600001518481518110611df157611df1614196565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611e3b57611e3b6144b6565b14611ea2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610ace565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611ed357611ed3614196565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115611f7457611f746144b6565b021790555060009150611f849050565b6004600084602001518481518110611f9e57611f9e614196565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611fe857611fe86144b6565b1461204f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610ace565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061208257612082614196565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612123576121236144b6565b02179055505082518051600592508390811061214157612141614196565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106121bd576121bd614196565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905580612227816141c5565b915050611dcb565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff43811682029290921780855592048116929182916014916122e791849174010000000000000000000000000000000000000000900416614562565b92506101000a81548163ffffffff021916908363ffffffff1602179055506123464630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613025565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986123fd988b9891977401000000000000000000000000000000000000000090920463ffffffff1696909591949193919261457f565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216848601526c010000000000000000000000008084048316606086015270010000000000000000000000000000000084048316608086015274010000000000000000000000000000000000000000840468ffffffffffffffffff1660a0808701919091527d01000000000000000000000000000000000000000000000000000000000090940461ffff1660c086015260095492831660e086015291047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610100840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa158015612577573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259b919061462f565b5093505092505080426125ae9190614520565b836020015163ffffffff161080156125d057506000836020015163ffffffff16115b156125ff57505061010001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b6000821361263c576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610ace565b5092915050565b61264b612657565b612654816130d0565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146126d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610ace565b565b6126d8612657565b600b546bffffffffffffffffffffffff166000036126fc57565b6000612706610db9565b90508051600003612743576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b54600091612762916bffffffffffffffffffffffff1661467f565b905060005b825181101561282e5781600a600085848151811061278757612787614196565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166127ef91906146aa565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080612827906141c5565b9050612767565b50815161283b90826146cf565b600b805460009061285b9084906bffffffffffffffffffffffff16614171565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216948401949094526c0100000000000000000000000082048116606084015270010000000000000000000000000000000082048116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08401527d01000000000000000000000000000000000000000000000000000000000090910461ffff90811660c0840181905260095492831660e0850152939091047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661010080840191909152850151919291161115612a22576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff1690506000612a638560e001513a848860800151612f22565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612abf576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b423087604001518860a001518960c001516001612ae091906146f7565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff1642612c349190614718565b63ffffffff16815250945084604051602001612c509190613b75565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b6000612caa826020614509565b612cb5856020614509565b612cc188610144614718565b612ccb9190614718565b612cd59190614718565b612ce0906000614718565b9050368114612d4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610ace565b50505050505050565b606080808080612d6686880188614806565b8451949950929750909550935091501580612d8357508351855114155b80612d9057508251855114155b80612d9d57508151855114155b80612daa57508051855114155b15612de1576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612f14576000612e79878381518110612e0457612e04614196565b6020026020010151878481518110612e1e57612e1e614196565b6020026020010151878581518110612e3857612e38614196565b6020026020010151878681518110612e5257612e52614196565b6020026020010151878781518110612e6c57612e6c614196565b60200260200101516131c5565b90506000816006811115612e8f57612e8f6144b6565b1480612eac57506001816006811115612eaa57612eaa6144b6565b145b15612f0357868281518110612ec357612ec3614196565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612f0d816141c5565b9050612de4565b505050505050505050505050565b60085460009081908690612f5a9063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614562565b612f649190614562565b60095463ffffffff918216925060009161271091612f83911688614509565b612f8d91906148d8565b612f979087614718565b90506000612fa482613455565b90506000612fc0846bffffffffffffffffffffffff8416614509565b90506000612fdc68ffffffffffffffffff808916908a166146aa565b9050612ffe612ff96bffffffffffffffffffffffff831684614718565b613484565b9a9950505050505050505050565b6000613016610db9565b511115610d6557610d656126e2565b6000808a8a8a8a8a8a8a8a8a604051602001613049999897969594939291906148ec565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361314f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610ace565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906131dc91906149c2565b9050806040516020016131ef9190613b75565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a8152600790935291205414613241576006915050611986565b60008781526007602052604090205461325e576002915050611986565b60006132693a613455565b905060008261012001518361010001516132839190614a8a565b6132949064ffffffffff16836146cf565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff16886132f391906146aa565b338b6040518763ffffffff1660e01b815260040161331696959493929190614aa8565b60408051808303816000875af1158015613334573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133589190614b24565b90925090506000826006811115613371576133716144b6565b148061338e5750600182600681111561338c5761338c6144b6565b145b156134475760008b8152600760205260408120556133ac81846146aa565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff90921693909291613418918591166146aa565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b600061347e613462612412565b61347484670de0b6b3a7640000614509565b612ff991906148d8565b92915050565b60006bffffffffffffffffffffffff821115613522576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610ace565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f84011261355757600080fd5b50813567ffffffffffffffff81111561356f57600080fd5b60208301915083602082850101111561358757600080fd5b9250929050565b600080602083850312156135a157600080fd5b823567ffffffffffffffff8111156135b857600080fd5b6135c485828601613545565b90969095509350505050565b6000815180845260005b818110156135f6576020818501810151868301820152016135da565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061364760208301846135d0565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156136a1576136a161364e565b60405290565b604051610160810167ffffffffffffffff811182821017156136a1576136a161364e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156137125761371261364e565b604052919050565b63ffffffff8116811461265457600080fd5b8035610fd48161371a565b68ffffffffffffffffff8116811461265457600080fd5b8035610fd481613737565b803561ffff81168114610fd457600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114610fd457600080fd5b600061012082840312156137aa57600080fd5b6137b261367d565b6137bb8361372c565b81526137c96020840161372c565b60208201526137da6040840161372c565b60408201526137eb6060840161372c565b60608201526137fc6080840161372c565b608082015261380d60a0840161374e565b60a082015261381e60c08401613759565b60c082015261382f60e0840161372c565b60e082015261010061384281850161376b565b908201529392505050565b600082601f83011261385e57600080fd5b813567ffffffffffffffff8111156138785761387861364e565b6138a960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016136cb565b8181528460208386010111156138be57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156138ed57600080fd5b813567ffffffffffffffff81111561390457600080fd5b6139108482850161384d565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461265457600080fd5b8035610fd481613918565b6bffffffffffffffffffffffff8116811461265457600080fd5b8035610fd481613945565b6000806040838503121561397d57600080fd5b823561398881613918565b9150602083013561399881613945565b809150509250929050565b600081518084526020808501945080840160005b838110156139e957815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016139b7565b509495945050505050565b60208152600061364760208301846139a3565b600060208284031215613a1957600080fd5b5035919050565b600060208284031215613a3257600080fd5b813567ffffffffffffffff811115613a4957600080fd5b8201610160818503121561364757600080fd5b805182526020810151613a87602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613aa760408401826bffffffffffffffffffffffff169052565b506060810151613acf606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613aeb608084018267ffffffffffffffff169052565b5060a0810151613b0360a084018263ffffffff169052565b5060c0810151613b2060c084018268ffffffffffffffffff169052565b5060e0810151613b3d60e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161347e8284613a5c565b60008083601f840112613b9657600080fd5b50813567ffffffffffffffff811115613bae57600080fd5b6020830191508360208260051b850101111561358757600080fd5b60008060008060008060008060e0898b031215613be557600080fd5b606089018a811115613bf657600080fd5b8998503567ffffffffffffffff80821115613c1057600080fd5b613c1c8c838d01613545565b909950975060808b0135915080821115613c3557600080fd5b613c418c838d01613b84565b909750955060a08b0135915080821115613c5a57600080fd5b50613c678b828c01613b84565b999c989b50969995989497949560c00135949350505050565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a0830151613ce060a084018268ffffffffffffffffff169052565b5060c0830151613cf660c084018261ffff169052565b5060e0830151613d0e60e084018263ffffffff169052565b50610100838101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116848301525b505092915050565b67ffffffffffffffff8116811461265457600080fd5b8035610fd481613d42565b600080600080600060808688031215613d7b57600080fd5b8535613d8681613d42565b9450602086013567ffffffffffffffff811115613da257600080fd5b613dae88828901613545565b9095509350506040860135613dc28161371a565b949793965091946060013592915050565b600067ffffffffffffffff821115613ded57613ded61364e565b5060051b60200190565b600082601f830112613e0857600080fd5b81356020613e1d613e1883613dd3565b6136cb565b82815260059290921b84018101918181019086841115613e3c57600080fd5b8286015b84811015613e60578035613e5381613918565b8352918301918301613e40565b509695505050505050565b803560ff81168114610fd457600080fd5b60008060008060008060c08789031215613e9557600080fd5b863567ffffffffffffffff80821115613ead57600080fd5b613eb98a838b01613df7565b97506020890135915080821115613ecf57600080fd5b613edb8a838b01613df7565b9650613ee960408a01613e6b565b95506060890135915080821115613eff57600080fd5b613f0b8a838b0161384d565b9450613f1960808a01613d58565b935060a0890135915080821115613f2f57600080fd5b50613f3c89828a0161384d565b9150509295509295509295565b600060208284031215613f5b57600080fd5b813561364781613918565b600181811c90821680613f7a57607f821691505b602082108103613fb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105da57600081815260208120601f850160051c81016020861015613fe05750805b601f850160051c820191505b81811015610a4957828155600101613fec565b67ffffffffffffffff8311156140175761401761364e565b61402b836140258354613f66565b83613fb9565b6000601f84116001811461407d57600085156140475750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614113565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140cc57868501358255602094850194600190920191016140ac565b5086821015614107577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8051610fd481613737565b60006020828403121561413757600080fd5b815161364781613737565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff82811682821603908082111561263c5761263c614142565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141f6576141f6614142565b5060010190565b6000610160823603121561421057600080fd5b6142186136a7565b823567ffffffffffffffff81111561422f57600080fd5b61423b3682860161384d565b825250602083013560208201526142546040840161393a565b60408201526142656060840161395f565b60608201526142766080840161374e565b608082015261428760a08401613d58565b60a082015261429860c08401613d58565b60c08201526142a960e0840161372c565b60e08201526101006142bc818501613759565b908201526101206142ce848201613d58565b908201526101406142e084820161393a565b9082015292915050565b6000602082840312156142fc57600080fd5b813561364781613d42565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261433c57600080fd5b83018035915067ffffffffffffffff82111561435757600080fd5b60200191503681900382131561358757600080fd5b60006020828403121561437e57600080fd5b61364782613759565b60006020828403121561439957600080fd5b81356136478161371a565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301019050612ffe60e0830184613a5c565b60ff818116838216019081111561347e5761347e614142565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806144a7576144a7614465565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761347e5761347e614142565b8181038181111561347e5761347e614142565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff81811683821601908082111561263c5761263c614142565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526145af8184018a6139a3565b905082810360808401526145c381896139a3565b905060ff871660a084015282810360c08401526145e081876135d0565b905067ffffffffffffffff851660e084015282810361010084015261460581856135d0565b9c9b505050505050505050505050565b805169ffffffffffffffffffff81168114610fd457600080fd5b600080600080600060a0868803121561464757600080fd5b61465086614615565b945060208601519350604086015192506060860151915061467360808701614615565b90509295509295909350565b60006bffffffffffffffffffffffff8084168061469e5761469e614465565b92169190910492915050565b6bffffffffffffffffffffffff81811683821601908082111561263c5761263c614142565b6bffffffffffffffffffffffff818116838216028082169190828114613d3a57613d3a614142565b67ffffffffffffffff81811683821601908082111561263c5761263c614142565b8082018082111561347e5761347e614142565b600082601f83011261473c57600080fd5b8135602061474c613e1883613dd3565b82815260059290921b8401810191818101908684111561476b57600080fd5b8286015b84811015613e60578035835291830191830161476f565b600082601f83011261479757600080fd5b813560206147a7613e1883613dd3565b82815260059290921b840181019181810190868411156147c657600080fd5b8286015b84811015613e6057803567ffffffffffffffff8111156147ea5760008081fd5b6147f88986838b010161384d565b8452509183019183016147ca565b600080600080600060a0868803121561481e57600080fd5b853567ffffffffffffffff8082111561483657600080fd5b61484289838a0161472b565b9650602088013591508082111561485857600080fd5b61486489838a01614786565b9550604088013591508082111561487a57600080fd5b61488689838a01614786565b9450606088013591508082111561489c57600080fd5b6148a889838a01614786565b935060808801359150808211156148be57600080fd5b506148cb88828901614786565b9150509295509295909350565b6000826148e7576148e7614465565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526149338285018b6139a3565b91508382036080850152614947828a6139a3565b915060ff881660a085015283820360c085015261496482886135d0565b90861660e0850152838103610100850152905061460581856135d0565b8051610fd481613918565b8051610fd481613945565b8051610fd481613d42565b8051610fd48161371a565b805164ffffffffff81168114610fd457600080fd5b600061016082840312156149d557600080fd5b6149dd6136a7565b825181526149ed60208401614981565b60208201526149fe6040840161498c565b6040820152614a0f60608401614981565b6060820152614a2060808401614997565b6080820152614a3160a084016149a2565b60a0820152614a4260c0840161411a565b60c0820152614a5360e0840161411a565b60e0820152610100614a668185016149ad565b90820152610120614a788482016149ad565b908201526101406138428482016149a2565b64ffffffffff81811683821601908082111561263c5761263c614142565b6000610200808352614abc8184018a6135d0565b90508281036020840152614ad081896135d0565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614b19905060a0830184613a5c565b979650505050505050565b60008060408385031215614b3757600080fd5b825160078110614b4657600080fd5b60208401519092506139988161394556fea164736f6c6343000813000a", + 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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":[],\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"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\":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\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b506040516200514638038062005146833981016040819052620000349162000418565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b505050505050620005c6565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033b565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160e81b0261ffff60e81b196001600160481b03909216600160a01b02600160a01b600160e81b031963ffffffff948516600160801b0216600160801b600160e81b03199585166c010000000000000000000000000263ffffffff60601b19978616680100000000000000000297909716600160401b600160801b0319998616640100000000026001600160401b0319909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980546001600160e01b039092166001600160e01b0319909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a906200033090839062000536565b60405180910390a150565b6200034562000347565b565b6000546001600160a01b03163314620003455760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003bb57600080fd5b919050565b805163ffffffff81168114620003bb57600080fd5b80516001600160481b0381168114620003bb57600080fd5b805161ffff81168114620003bb57600080fd5b80516001600160e01b0381168114620003bb57600080fd5b60008060008385036101408112156200043057600080fd5b6200043b85620003a3565b935061010080601f19830112156200045257600080fd5b60405191508082016001600160401b03811183821017156200048457634e487b7160e01b600052604160045260246000fd5b6040526200049560208701620003c0565b8252620004a560408701620003c0565b6020830152620004b860608701620003c0565b6040830152620004cb60808701620003c0565b6060830152620004de60a08701620003c0565b6080830152620004f160c08701620003d5565b60a08301526200050460e08701620003ed565b60c08301526200051681870162000400565b60e08301525091506200052d6101208501620003a3565b90509250925092565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525060018060481b0360a08401511660a083015260c0830151620005a360c084018261ffff169052565b5060e0830151620005bf60e08401826001600160e01b03169052565b5092915050565b60805160a051614b3062000616600039600081816105ce0152818161075c01528181610a4501528181610cdb0152818161104e015281816118380152613287015260006112760152614b306000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806385b214cf116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610539578063e4ddcea61461054c578063f2fde38b1461056257600080fd5b8063c3f909d4146103c4578063d227d24514610501578063d328a91e1461053157600080fd5b8063a631571e116100bd578063a631571e14610371578063afcb95d714610391578063b1dc65a4146103b157600080fd5b806385b214cf146103135780638da5cb5b146103365780639314176d1461035e57600080fd5b806379ba509711610145578063814118341161011f578063814118341461028957806381f1b9381461029e57806381ff7048146102a657600080fd5b806379ba5097146102665780637d4807871461026e5780637f15e1661461027657600080fd5b80632a905ccc116101765780632a905ccc146101f957806359b5b7ac1461021b57806366316d8d1461025357600080fd5b8063083a546614610192578063181f5a77146101a7575b600080fd5b6101a56101a036600461357a565b610575565b005b6101e36040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f09190613620565b60405180910390f35b6102016105ca565b60405168ffffffffffffffffff90911681526020016101f0565b610201610229366004613770565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101a56102613660046137ff565b610660565b6101a5610819565b6101a561091b565b6101a561028436600461357a565b610b31565b610291610b81565b6040516101f09190613889565b6101e3610bf0565b6102f060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f0565b61032661032136600461389c565b610cc1565b60405190151581526020016101f0565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6101a561036c366004613932565b610da1565b61038461037f3660046139fc565b610fdd565b6040516101f09190613b51565b6040805160018152600060208201819052918101919091526060016101f0565b6101a56103bf366004613ba5565b61117d565b6104f46040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915250604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08201527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e082015290565b6040516101f09190613c5c565b61051461050f366004613d1c565b611834565b6040516bffffffffffffffffffffffff90911681526020016101f0565b6101e3611996565b6101a5610547366004613e35565b6119ed565b610554612419565b6040519081526020016101f0565b6101a5610570366004613f02565b61263e565b61057d612652565b60008190036105b8576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105c5828483613fb8565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065b91906140de565b905090565b6106686126d5565b806bffffffffffffffffffffffff166000036106a25750336000908152600a60205260409020546bffffffffffffffffffffffff166106fc565b336000908152600a60205260409020546bffffffffffffffffffffffff808316911610156106fc576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906107299084906bffffffffffffffffffffffff1661412a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061077e7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b1580156107fd57600080fd5b505af1158015610811573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461089f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610923612880565b61092b6126d5565b6000610935610b81565b905060005b8151811015610b2d576000600a600084848151811061095b5761095b61414f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff1690506000600a60008585815181106109d0576109d061414f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610a677f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610a9457610a9461414f565b6020026020010151836040518363ffffffff1660e01b8152600401610ae992919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610b0357600080fd5b505af1158015610b17573d6000803e3d6000fd5b505050505080610b269061417e565b905061093a565b5050565b610b39612652565b6000819003610b74576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105c5828483613fb8565b60606006805480602002602001604051908101604052809291908181526020018280548015610be657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610bbb575b5050505050905090565b6060600d8054610bff90613f1f565b9050600003610c3a576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610c4790613f1f565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7390613f1f565b8015610be65780601f10610c9557610100808354040283529160200191610be6565b820191906000526020600020905b815481529060010190602001808311610ca357509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d32576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260076020526040902054610d4d57506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610d909084815260200190565b60405180910390a15060015b919050565b610da9612880565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167d010000000000000000000000000000000000000000000000000000000000027fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90921674010000000000000000000000000000000000000000027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff63ffffffff94851670010000000000000000000000000000000002167fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff9585166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9786166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a90610fd2908390613c5c565b60405180910390a150565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146110a5576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110b66110b1836141b6565b612888565b90506110c86060830160408401613f02565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261111660c0870160a088016142a3565b61112861016088016101408901613f02565b61113288806142c0565b6111446101208b016101008c01614325565b60208b013561115a6101008d0160e08e01614340565b8b6040516111709998979695949392919061435d565b60405180910390a3919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610896565b6112728b8b8b8b8b8b612c89565b60007f0000000000000000000000000000000000000000000000000000000000000000156112cf576002826020015183604001516112b09190614405565b6112ba919061444d565b6112c5906001614405565b60ff1690506112e5565b60208201516112df906001614405565b60ff1690505b88811461134e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610896565b8887146113b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610896565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113fa576113fa61446f565b600281111561140b5761140b61446f565b90525090506002816020015160028111156114285761142861446f565b14801561146f57506006816000015160ff168154811061144a5761144a61414f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6114d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610896565b50505050506114e2613512565b6000808a8a6040516114f592919061449e565b60405190819003812061150c918e906020016144ae565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156118165760006001848984602081106115755761157561414f565b61158291901a601b614405565b8e8e868181106115945761159461414f565b905060200201358d8d878181106115ad576115ad61414f565b90506020020135604051600081526020016040526040516115ea949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561160c573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561168c5761168c61446f565b600281111561169d5761169d61446f565b90525092506001836020015160028111156116ba576116ba61446f565b14611721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610896565b8251600090879060ff16601f811061173b5761173b61414f565b602002015173ffffffffffffffffffffffffffffffffffffffff16146117bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610896565b8086846000015160ff16601f81106117d7576117d761414f565b73ffffffffffffffffffffffffffffffffffffffff9092166020929092020152611802600186614405565b9450508061180f9061417e565b9050611556565b505050611827833383858e8e612d40565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b1580156118d457600080fd5b505afa1580156118e8573d6000803e3d6000fd5b5050505066038d7ea4c6800082111561192d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006119376105ca565b9050600061197a87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061022992505050565b905061198885858385612f0e565b925050505b95945050505050565b6060600c80546119a590613f1f565b90506000036119e0576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610c4790613f1f565b855185518560ff16601f831115611a60576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610896565b80600003611aca576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610896565b818314611b58576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610896565b611b638160036144c2565b8311611bcb576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610896565b611bd3612652565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611c1a9088612ff8565b60055415611dcf57600554600090611c34906001906144d9565b9050600060058281548110611c4b57611c4b61414f565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611c8557611c8561414f565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611d0557611d056144ec565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611d6e57611d6e6144ec565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611c1a915050565b60005b8151518110156122365760006004600084600001518481518110611df857611df861414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611e4257611e4261446f565b14611ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610896565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611eda57611eda61414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115611f7b57611f7b61446f565b021790555060009150611f8b9050565b6004600084602001518481518110611fa557611fa561414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611fef57611fef61446f565b14612056576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610896565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106120895761208961414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561212a5761212a61446f565b0217905550508251805160059250839081106121485761214861414f565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106121c4576121c461414f565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061222e8161417e565b915050611dd2565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff43811682029290921780855592048116929182916014916122ee9184917401000000000000000000000000000000000000000090041661451b565b92506101000a81548163ffffffff021916908363ffffffff16021790555061234d4630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613011565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612404988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614538565b60405180910390a15050505050505050505050565b604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c01000000000000000000000000808304821660608501527001000000000000000000000000000000008304909116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a0808501919091527d01000000000000000000000000000000000000000000000000000000000090920461ffff1660c08401526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa158015612573573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259791906145e8565b5093505092505080426125aa91906144d9565b836020015163ffffffff161080156125cc57506000836020015163ffffffff16115b156125fa57505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b60008213612637576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610896565b5092915050565b612646612652565b61264f816130bc565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146126d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610896565b565b600b546bffffffffffffffffffffffff166000036126ef57565b60006126f9610b81565b90508051600003612736576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b54600091612755916bffffffffffffffffffffffff16614638565b905060005b82518110156128215781600a600085848151811061277a5761277a61414f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166127e29190614663565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508061281a9061417e565b905061275a565b50815161282e9082614688565b600b805460009061284e9084906bffffffffffffffffffffffff1661412a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6126d3612652565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260408051610100808201835260085463ffffffff80821684526401000000008204811660208501526801000000000000000082048116948401949094526c010000000000000000000000008104841660608401527001000000000000000000000000000000008104909316608083015274010000000000000000000000000000000000000000830468ffffffffffffffffff1660a08301527d01000000000000000000000000000000000000000000000000000000000090920461ffff90811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e084015292850151919291161115612a0e576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff1690506000612a4f8560e001513a848860800151612f0e565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612aab576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b2e3087604001518860a001518960c001516001612acc91906146b8565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff1642612c2091906146d9565b63ffffffff16815250945084604051602001612c3c9190613b51565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b6000612c968260206144c2565b612ca18560206144c2565b612cad886101446146d9565b612cb791906146d9565b612cc191906146d9565b612ccc9060006146d9565b9050368114612d37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610896565b50505050505050565b606080808080612d52868801886147c7565b8451949950929750909550935091501580612d6f57508351855114155b80612d7c57508251855114155b80612d8957508151855114155b80612d9657508051855114155b15612dcd576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612f00576000612e65878381518110612df057612df061414f565b6020026020010151878481518110612e0a57612e0a61414f565b6020026020010151878581518110612e2457612e2461414f565b6020026020010151878681518110612e3e57612e3e61414f565b6020026020010151878781518110612e5857612e5861414f565b60200260200101516131b1565b90506000816006811115612e7b57612e7b61446f565b1480612e9857506001816006811115612e9657612e9661446f565b145b15612eef57868281518110612eaf57612eaf61414f565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612ef98161417e565b9050612dd0565b505050505050505050505050565b60085460009081908690612f469063ffffffff6c0100000000000000000000000082048116916801000000000000000090041661451b565b612f50919061451b565b60085463ffffffff918216925060009161271091612f6f9116886144c2565b612f799190614899565b612f8390876146d9565b90506000612f9082613441565b90506000612fac846bffffffffffffffffffffffff84166144c2565b90506000612fc868ffffffffffffffffff808916908a16614663565b9050612fea612fe56bffffffffffffffffffffffff8316846146d9565b613470565b9a9950505050505050505050565b6000613002610b81565b511115610b2d57610b2d6126d5565b6000808a8a8a8a8a8a8a8a8a604051602001613035999897969594939291906148ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361313b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610896565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906131c89190614983565b9050806040516020016131db9190613b51565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a815260079093529120541461322d57600691505061198d565b60008781526007602052604090205461324a57600291505061198d565b60006132553a613441565b9050600082610120015183610100015161326f9190614a56565b6132809064ffffffffff1683614688565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff16886132df9190614663565b338b6040518763ffffffff1660e01b815260040161330296959493929190614a74565b60408051808303816000875af1158015613320573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133449190614af0565b9092509050600082600681111561335d5761335d61446f565b148061337a575060018260068111156133785761337861446f565b145b156134335760008b8152600760205260408120556133988184614663565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff9092169390929161340491859116614663565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b600061346a61344e612419565b61346084670de0b6b3a76400006144c2565b612fe59190614899565b92915050565b60006bffffffffffffffffffffffff82111561350e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610896565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f84011261354357600080fd5b50813567ffffffffffffffff81111561355b57600080fd5b60208301915083602082850101111561357357600080fd5b9250929050565b6000806020838503121561358d57600080fd5b823567ffffffffffffffff8111156135a457600080fd5b6135b085828601613531565b90969095509350505050565b6000815180845260005b818110156135e2576020818501810151868301820152016135c6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061363360208301846135bc565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff8111828210171561368d5761368d61363a565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136da576136da61363a565b604052919050565b600082601f8301126136f357600080fd5b813567ffffffffffffffff81111561370d5761370d61363a565b61373e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613693565b81815284602083860101111561375357600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561378257600080fd5b813567ffffffffffffffff81111561379957600080fd5b6137a5848285016136e2565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461264f57600080fd5b8035610d9c816137ad565b6bffffffffffffffffffffffff8116811461264f57600080fd5b8035610d9c816137da565b6000806040838503121561381257600080fd5b823561381d816137ad565b9150602083013561382d816137da565b809150509250929050565b600081518084526020808501945080840160005b8381101561387e57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161384c565b509495945050505050565b6020815260006136336020830184613838565b6000602082840312156138ae57600080fd5b5035919050565b63ffffffff8116811461264f57600080fd5b8035610d9c816138b5565b68ffffffffffffffffff8116811461264f57600080fd5b8035610d9c816138d2565b803561ffff81168114610d9c57600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114610d9c57600080fd5b600061010080838503121561394657600080fd5b6040519081019067ffffffffffffffff821181831017156139695761396961363a565b816040528335915061397a826138b5565b818152613989602085016138c7565b602082015261399a604085016138c7565b60408201526139ab606085016138c7565b60608201526139bc608085016138c7565b60808201526139cd60a085016138e9565b60a08201526139de60c085016138f4565b60c08201526139ef60e08501613906565b60e0820152949350505050565b600060208284031215613a0e57600080fd5b813567ffffffffffffffff811115613a2557600080fd5b8201610160818503121561363357600080fd5b805182526020810151613a63602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613a8360408401826bffffffffffffffffffffffff169052565b506060810151613aab606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613ac7608084018267ffffffffffffffff169052565b5060a0810151613adf60a084018263ffffffff169052565b5060c0810151613afc60c084018268ffffffffffffffffff169052565b5060e0810151613b1960e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161346a8284613a38565b60008083601f840112613b7257600080fd5b50813567ffffffffffffffff811115613b8a57600080fd5b6020830191508360208260051b850101111561357357600080fd5b60008060008060008060008060e0898b031215613bc157600080fd5b606089018a811115613bd257600080fd5b8998503567ffffffffffffffff80821115613bec57600080fd5b613bf88c838d01613531565b909950975060808b0135915080821115613c1157600080fd5b613c1d8c838d01613b60565b909750955060a08b0135915080821115613c3657600080fd5b50613c438b828c01613b60565b999c989b50969995989497949560c00135949350505050565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525068ffffffffffffffffff60a08401511660a083015260c0830151613ccb60c084018261ffff169052565b5060e083015161263760e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b67ffffffffffffffff8116811461264f57600080fd5b8035610d9c81613cfb565b600080600080600060808688031215613d3457600080fd5b8535613d3f81613cfb565b9450602086013567ffffffffffffffff811115613d5b57600080fd5b613d6788828901613531565b9095509350506040860135613d7b816138b5565b949793965091946060013592915050565b600067ffffffffffffffff821115613da657613da661363a565b5060051b60200190565b600082601f830112613dc157600080fd5b81356020613dd6613dd183613d8c565b613693565b82815260059290921b84018101918181019086841115613df557600080fd5b8286015b84811015613e19578035613e0c816137ad565b8352918301918301613df9565b509695505050505050565b803560ff81168114610d9c57600080fd5b60008060008060008060c08789031215613e4e57600080fd5b863567ffffffffffffffff80821115613e6657600080fd5b613e728a838b01613db0565b97506020890135915080821115613e8857600080fd5b613e948a838b01613db0565b9650613ea260408a01613e24565b95506060890135915080821115613eb857600080fd5b613ec48a838b016136e2565b9450613ed260808a01613d11565b935060a0890135915080821115613ee857600080fd5b50613ef589828a016136e2565b9150509295509295509295565b600060208284031215613f1457600080fd5b8135613633816137ad565b600181811c90821680613f3357607f821691505b602082108103613f6c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105c557600081815260208120601f850160051c81016020861015613f995750805b601f850160051c820191505b8181101561081157828155600101613fa5565b67ffffffffffffffff831115613fd057613fd061363a565b613fe483613fde8354613f1f565b83613f72565b6000601f84116001811461403657600085156140005750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556140cc565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140855786850135825560209485019460019092019101614065565b50868210156140c0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8051610d9c816138d2565b6000602082840312156140f057600080fd5b8151613633816138d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff828116828216039080821115612637576126376140fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141af576141af6140fb565b5060010190565b600061016082360312156141c957600080fd5b6141d1613669565b823567ffffffffffffffff8111156141e857600080fd5b6141f4368286016136e2565b8252506020830135602082015261420d604084016137cf565b604082015261421e606084016137f4565b606082015261422f608084016138e9565b608082015261424060a08401613d11565b60a082015261425160c08401613d11565b60c082015261426260e084016138c7565b60e08201526101006142758185016138f4565b90820152610120614287848201613d11565b908201526101406142998482016137cf565b9082015292915050565b6000602082840312156142b557600080fd5b813561363381613cfb565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142f557600080fd5b83018035915067ffffffffffffffff82111561431057600080fd5b60200191503681900382131561357357600080fd5b60006020828403121561433757600080fd5b613633826138f4565b60006020828403121561435257600080fd5b8135613633816138b5565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301019050612fea60e0830184613a38565b60ff818116838216019081111561346a5761346a6140fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806144605761446061441e565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761346a5761346a6140fb565b8181038181111561346a5761346a6140fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff818116838216019080821115612637576126376140fb565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526145688184018a613838565b9050828103608084015261457c8189613838565b905060ff871660a084015282810360c084015261459981876135bc565b905067ffffffffffffffff851660e08401528281036101008401526145be81856135bc565b9c9b505050505050505050505050565b805169ffffffffffffffffffff81168114610d9c57600080fd5b600080600080600060a0868803121561460057600080fd5b614609866145ce565b945060208601519350604086015192506060860151915061462c608087016145ce565b90509295509295909350565b60006bffffffffffffffffffffffff808416806146575761465761441e565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115612637576126376140fb565b6bffffffffffffffffffffffff8181168382160280821691908281146146b0576146b06140fb565b505092915050565b67ffffffffffffffff818116838216019080821115612637576126376140fb565b8082018082111561346a5761346a6140fb565b600082601f8301126146fd57600080fd5b8135602061470d613dd183613d8c565b82815260059290921b8401810191818101908684111561472c57600080fd5b8286015b84811015613e195780358352918301918301614730565b600082601f83011261475857600080fd5b81356020614768613dd183613d8c565b82815260059290921b8401810191818101908684111561478757600080fd5b8286015b84811015613e1957803567ffffffffffffffff8111156147ab5760008081fd5b6147b98986838b01016136e2565b84525091830191830161478b565b600080600080600060a086880312156147df57600080fd5b853567ffffffffffffffff808211156147f757600080fd5b61480389838a016146ec565b9650602088013591508082111561481957600080fd5b61482589838a01614747565b9550604088013591508082111561483b57600080fd5b61484789838a01614747565b9450606088013591508082111561485d57600080fd5b61486989838a01614747565b9350608088013591508082111561487f57600080fd5b5061488c88828901614747565b9150509295509295909350565b6000826148a8576148a861441e565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526148f48285018b613838565b91508382036080850152614908828a613838565b915060ff881660a085015283820360c085015261492582886135bc565b90861660e085015283810361010085015290506145be81856135bc565b8051610d9c816137ad565b8051610d9c816137da565b8051610d9c81613cfb565b8051610d9c816138b5565b805164ffffffffff81168114610d9c57600080fd5b6000610160828403121561499657600080fd5b61499e613669565b825181526149ae60208401614942565b60208201526149bf6040840161494d565b60408201526149d060608401614942565b60608201526149e160808401614958565b60808201526149f260a08401614963565b60a0820152614a0360c084016140d3565b60c0820152614a1460e084016140d3565b60e0820152610100614a2781850161496e565b90820152610120614a3984820161496e565b90820152610140614a4b848201614963565b908201529392505050565b64ffffffffff818116838216019080821115612637576126376140fb565b6000610200808352614a888184018a6135bc565b90508281036020840152614a9c81896135bc565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614ae5905060a0830184613a38565b979650505050505050565b60008060408385031215614b0357600080fd5b825160078110614b1257600080fd5b602084015190925061382d816137da56fea164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI @@ -211,9 +210,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorRaw) Transact(opts *b return _FunctionsCoordinator.Contract.contract.Transact(opts, method, params...) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPriceGwei) + err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPriceWei) if err != nil { return *new(*big.Int), err @@ -225,12 +224,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) { + return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceWei) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) { + return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceWei) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) { @@ -1690,7 +1689,7 @@ func (FunctionsCoordinatorConfigSet) Topic() common.Hash { } func (FunctionsCoordinatorConfigUpdated) Topic() common.Hash { - return common.HexToHash("0x5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c") + return common.HexToHash("0x8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a") } func (FunctionsCoordinatorOracleRequest) Topic() common.Hash { @@ -1718,7 +1717,7 @@ func (_FunctionsCoordinator *FunctionsCoordinator) Address() common.Address { } type FunctionsCoordinatorInterface interface { - EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) + EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) diff --git a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go index 1f399700b1c..37a895fe8cd 100644 --- a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go +++ b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go @@ -32,7 +32,7 @@ var ( var FunctionsLoadTestClientMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStats\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastError\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponse\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resetStats\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"cborEncodedRequest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendEncodedRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"slotId\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"slotVersion\",\"type\":\"uint64\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestWithDONHostedSecrets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalEmptyResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalFailedResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSucceededResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200243938038062002439833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051612264620001d5600039600081816102ac0152610fde01526122646000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c806379ba5097116100b2578063954491c111610081578063c59d484711610066578063c59d484714610246578063c9429e2a14610261578063f2fde38b1461028157600080fd5b8063954491c114610220578063b2518e0e1461023357600080fd5b806379ba5097146101cd578063887efe94146101d55780638aea61dc146101e85780638da5cb5b146101f857600080fd5b80635c1d92e9116100ee5780635c1d92e91461019b57806362747e42146101b35780636d9809a0146101bb578063724ec8a2146101c557600080fd5b80630ca761751461012057806329f0de3f146101355780632ab424da1461015357806347c0318614610184575b600080fd5b61013361012e3660046118ee565b610294565b005b61013d610313565b60405161014a91906119bf565b60405180910390f35b60055461016f9068010000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161014a565b61018d60025481565b60405190815260200161014a565b60055461016f90640100000000900463ffffffff1681565b61013d6103a1565b61016f6203d09081565b6101336103ae565b610133610420565b6101336101e3366004611a91565b610522565b60055461016f9063ffffffff1681565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014a565b61013361022e366004611b55565b61069c565b610133610241366004611c1b565b6107ba565b61024e610839565b60405161014a9796959493929190611c81565b60055461016f906c01000000000000000000000000900463ffffffff1681565b61013361028f366004611cde565b6109c1565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610303576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030e8383836109d5565b505050565b6004805461032090611d14565b80601f016020809104026020016040519081016040528092919081815260200182805461034c90611d14565b80156103995780601f1061036e57610100808354040283529160200191610399565b820191906000526020600020905b81548152906001019060200180831161037c57829003601f168201915b505050505081565b6003805461032090611d14565b6103b6610adf565b6000600281905560408051602081019091529081526003906103d89082611db5565b506040805160208101909152600081526004906103f59082611db5565b50600580547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61052a610adf565b6105736040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6105b589898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b629050565b85156105fd576105fd87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b739050565b8315610617576106176106108587611ecf565b8290610bbd565b60005b8a63ffffffff1681101561068f5761063f61063483610c00565b856203d09086610fd9565b600255600580546001919060009061065e90849063ffffffff16611f96565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061068790611fba565b91505061061a565b5050505050505050505050565b6106a4610adf565b6106ed6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b61072f89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b629050565b61073a8188886110b8565b831561074d5761074d6106108587611ecf565b60005b8a63ffffffff1681101561068f5761076a61063483610c00565b600255600580546001919060009061078990849063ffffffff16611f96565b92506101000a81548163ffffffff021916908363ffffffff16021790555080806107b290611fba565b915050610750565b6107c2610adf565b60005b8463ffffffff16811015610832576107e284846203d09085610fd9565b600255600580546001919060009061080190849063ffffffff16611f96565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061082a90611fba565b9150506107c5565b5050505050565b600060608060008060008061084c610adf565b60025460055460038054909160049163ffffffff808316926801000000000000000081048216926c01000000000000000000000000820483169264010000000090920490911690869061089e90611d14565b80601f01602080910402602001604051908101604052809291908181526020018280546108ca90611d14565b80156109175780601f106108ec57610100808354040283529160200191610917565b820191906000526020600020905b8154815290600101906020018083116108fa57829003601f168201915b5050505050955084805461092a90611d14565b80601f016020809104026020016040519081016040528092919081815260200182805461095690611d14565b80156109a35780601f10610978576101008083540402835291602001916109a3565b820191906000526020600020905b81548152906001019060200180831161098657829003601f168201915b50505050509450965096509650965096509650965090919293949596565b6109c9610adf565b6109d28161117b565b50565b600283905560036109e68382611db5565b5060046109f38282611db5565b508151600003610a3e576001600560048282829054906101000a900463ffffffff16610a1f9190611f96565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b805115610a865760016005600c8282829054906101000a900463ffffffff16610a679190611f96565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b815115801590610a9557508051155b1561030e576001600560088282829054906101000a900463ffffffff16610abc9190611f96565b92506101000a81548163ffffffff021916908363ffffffff160217905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161049d565b565b610b6f8260008084611270565b5050565b8051600003610bae576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610bf8576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b60606000610c0f610100611307565b9050610c596040518060400160405280600c81526020017f636f64654c6f636174696f6e00000000000000000000000000000000000000008152508261132890919063ffffffff16565b8251610c77906002811115610c7057610c70611ff2565b8290611341565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610cb6908290611328565b6040830151610ccd908015610c7057610c70611ff2565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610d0c908290611328565b6060830151610d1c908290611328565b60a08301515115610d765760408051808201909152601081527f726571756573745369676e6174757265000000000000000000000000000000006020820152610d66908290611328565b60a0830151610d76908290611376565b60c08301515115610e235760408051808201909152600481527f61726773000000000000000000000000000000000000000000000000000000006020820152610dc0908290611328565b610dc981611383565b60005b8360c0015151811015610e1957610e098460c001518281518110610df257610df2612021565b60200260200101518361132890919063ffffffff16565b610e1281611fba565b9050610dcc565b50610e23816113a7565b60808301515115610f2457600083602001516002811115610e4657610e46611ff2565b03610e7d576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610ebc908290611328565b610ed583602001516002811115610c7057610c70611ff2565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610f14908290611328565b6080830151610f24908290611376565b60e08301515115610fd15760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610f6e908290611328565b610f7781611383565b60005b8360e0015151811015610fc757610fb78460e001518281518110610fa057610fa0612021565b60200260200101518361137690919063ffffffff16565b610fc081611fba565b9050610f7a565b50610fd1816113a7565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b815260040161103e959493929190612050565b6020604051808303816000875af115801561105d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611081919061209a565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b60006110c5610100611307565b905061110f6040518060400160405280600681526020017f736c6f74494400000000000000000000000000000000000000000000000000008152508261132890919063ffffffff16565b61111c8160ff85166113c5565b60408051808201909152600781527f76657273696f6e00000000000000000000000000000000000000000000000000602082015261115b908290611328565b61116581836113c5565b6002602085015251516080909301929092525050565b3373ffffffffffffffffffffffffffffffffffffffff8216036111fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161049d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516000036112ab576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838360028111156112be576112be611ff2565b908160028111156112d1576112d1611ff2565b905250604084018280156112e7576112e7611ff2565b908180156112f7576112f7611ff2565b9052506060909301929092525050565b61130f6117a5565b805161131b90836113d1565b5060006020820152919050565b611335826003835161144b565b815161030e9082611572565b815161134e9060c261159a565b50610b6f828260405160200161136691815260200190565b6040516020818303038152906040525b611335826002835161144b565b61138e816004611603565b6001816020018181516113a191906120b3565b90525050565b6113b2816007611603565b6001816020018181516113a191906120c6565b610b6f8260008361144b565b6040805180820190915260608152600060208201526113f16020836120d9565b15611419576114016020836120d9565b61140c9060206120c6565b61141690836120b3565b91505b60208084018390526040518085526000815290818401018181101561143d57600080fd5b604052508290505b92915050565b60178167ffffffffffffffff16116114785782516114729060e0600585901b16831761159a565b50505050565b60ff8167ffffffffffffffff16116114ba5782516114a1906018611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600161161a565b61ffff8167ffffffffffffffff16116114fd5782516114e4906019611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600261161a565b63ffffffff8167ffffffffffffffff161161154257825161152990601a611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600461161a565b825161155990601b611fe0600586901b161761159a565b5082516114729067ffffffffffffffff8316600861161a565b6040805180820190915260608152600060208201526115938383845161169f565b9392505050565b60408051808201909152606081526000602082015282515160006115bf8260016120b3565b9050846020015182106115e0576115e0856115db836002612114565b61178e565b84516020838201018581535080518211156115f9578181525b5093949350505050565b815161030e90601f611fe0600585901b161761159a565b604080518082019091526060815260006020820152835151600061163e82856120b3565b9050856020015181111561165b5761165b866115db836002612114565b6000600161166b8661010061224b565b61167591906120c6565b90508651828101878319825116178152508051831115611693578281525b50959695505050505050565b60408051808201909152606081526000602082015282518211156116c257600080fd5b83515160006116d184836120b3565b905085602001518111156116ee576116ee866115db836002612114565b855180518382016020019160009180851115611708578482525b505050602086015b6020861061174857805182526117276020836120b3565b91506117346020826120b3565b90506117416020876120c6565b9550611710565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b815161179a83836113d1565b506114728382611572565b60405180604001604052806117cd604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611850576118506117da565b604052919050565b600067ffffffffffffffff831115611872576118726117da565b6118a360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611809565b90508281528383830111156118b757600080fd5b828260208301376000602084830101529392505050565b600082601f8301126118df57600080fd5b61159383833560208501611858565b60008060006060848603121561190357600080fd5b83359250602084013567ffffffffffffffff8082111561192257600080fd5b61192e878388016118ce565b9350604086013591508082111561194457600080fd5b50611951868287016118ce565b9150509250925092565b6000815180845260005b8181101561198157602081850181015186830182015201611965565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611593602083018461195b565b803563ffffffff811681146119e657600080fd5b919050565b60008083601f8401126119fd57600080fd5b50813567ffffffffffffffff811115611a1557600080fd5b602083019150836020828501011115611a2d57600080fd5b9250929050565b60008083601f840112611a4657600080fd5b50813567ffffffffffffffff811115611a5e57600080fd5b6020830191508360208260051b8501011115611a2d57600080fd5b803567ffffffffffffffff811681146119e657600080fd5b600080600080600080600080600060c08a8c031215611aaf57600080fd5b611ab88a6119d2565b985060208a013567ffffffffffffffff80821115611ad557600080fd5b611ae18d838e016119eb565b909a50985060408c0135915080821115611afa57600080fd5b611b068d838e016119eb565b909850965060608c0135915080821115611b1f57600080fd5b50611b2c8c828d01611a34565b9095509350611b3f905060808b01611a79565b915060a08a013590509295985092959850929598565b600080600080600080600080600060e08a8c031215611b7357600080fd5b611b7c8a6119d2565b985060208a013567ffffffffffffffff80821115611b9957600080fd5b611ba58d838e016119eb565b909a50985060408c0135915060ff82168214611bc057600080fd5b819750611bcf60608d01611a79565b965060808c0135915080821115611be557600080fd5b50611bf28c828d01611a34565b9095509350611c05905060a08b01611a79565b915060c08a013590509295985092959850929598565b60008060008060808587031215611c3157600080fd5b611c3a856119d2565b9350602085013567ffffffffffffffff811115611c5657600080fd5b611c62878288016118ce565b935050611c7160408601611a79565b9396929550929360600135925050565b87815260e060208201526000611c9a60e083018961195b565b8281036040840152611cac818961195b565b63ffffffff97881660608501529587166080840152505091841660a083015290921660c0909201919091529392505050565b600060208284031215611cf057600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461159357600080fd5b600181811c90821680611d2857607f821691505b602082108103611d61577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561030e57600081815260208120601f850160051c81016020861015611d8e5750805b601f850160051c820191505b81811015611dad57828155600101611d9a565b505050505050565b815167ffffffffffffffff811115611dcf57611dcf6117da565b611de381611ddd8454611d14565b84611d67565b602080601f831160018114611e365760008415611e005750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611dad565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611e8357888601518255948401946001909101908401611e64565b5085821015611ebf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600067ffffffffffffffff80841115611eea57611eea6117da565b8360051b6020611efb818301611809565b868152918501918181019036841115611f1357600080fd5b865b84811015611f5b57803586811115611f2d5760008081fd5b880136601f820112611f3f5760008081fd5b611f4d368235878401611858565b845250918301918301611f15565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff818116838216019080821115611fb357611fb3611f67565b5092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611feb57611feb611f67565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8616815260a06020820152600061207360a083018761195b565b61ffff9590951660408301525063ffffffff92909216606083015260809091015292915050565b6000602082840312156120ac57600080fd5b5051919050565b8082018082111561144557611445611f67565b8181038181111561144557611445611f67565b60008261210f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b808202811582820484141761144557611445611f67565b600181815b8085111561218457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561216a5761216a611f67565b8085161561217757918102915b93841c9390800290612130565b509250929050565b60008261219b57506001611445565b816121a857506000611445565b81600181146121be57600281146121c8576121e4565b6001915050611445565b60ff8411156121d9576121d9611f67565b50506001821b611445565b5060208310610133831016604e8410600b8410161715612207575081810a611445565b612211838361212b565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561224357612243611f67565b029392505050565b6000611593838361218c56fea164736f6c6343000813000a", + Bin: "0x60a06040523480156200001157600080fd5b50604051620023ff380380620023ff833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b60805161222a620001d5600039600081816102ac0152610fa0015261222a6000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c806379ba5097116100b2578063954491c111610081578063c59d484711610066578063c59d484714610246578063c9429e2a14610261578063f2fde38b1461028157600080fd5b8063954491c114610220578063b2518e0e1461023357600080fd5b806379ba5097146101cd578063887efe94146101d55780638aea61dc146101e85780638da5cb5b146101f857600080fd5b80635c1d92e9116100ee5780635c1d92e91461019b57806362747e42146101b35780636d9809a0146101bb578063724ec8a2146101c557600080fd5b80630ca761751461012057806329f0de3f146101355780632ab424da1461015357806347c0318614610184575b600080fd5b61013361012e3660046118b4565b610294565b005b61013d61033e565b60405161014a9190611985565b60405180910390f35b60055461016f9068010000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161014a565b61018d60025481565b60405190815260200161014a565b60055461016f90640100000000900463ffffffff1681565b61013d6103cc565b61016f6203d09081565b6101336103d9565b61013361044b565b6101336101e3366004611a57565b61054d565b60055461016f9063ffffffff1681565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014a565b61013361022e366004611b1b565b6106bf565b610133610241366004611be1565b6107d5565b61024e610854565b60405161014a9796959493929190611c47565b60055461016f906c01000000000000000000000000900463ffffffff1681565b61013361028f366004611ca4565b6109dc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610303576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030e8383836109f0565b60405183907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a2505050565b6004805461034b90611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461037790611cda565b80156103c45780601f10610399576101008083540402835291602001916103c4565b820191906000526020600020905b8154815290600101906020018083116103a757829003601f168201915b505050505081565b6003805461034b90611cda565b6103e1610afb565b6000600281905560408051602081019091529081526003906104039082611d7b565b506040805160208101909152600081526004906104209082611d7b565b50600580547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610555610afb565b6105966040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6105d889898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b7e9050565b85156106205761062087878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b8f9050565b831561063a5761063a6106338587611e95565b8290610bd9565b60005b8a63ffffffff168110156106b25761066261065783610c1c565b856203d09086610f9b565b600255600580546001919060009061068190849063ffffffff16611f5c565b92506101000a81548163ffffffff021916908363ffffffff16021790555080806106aa90611f80565b91505061063d565b5050505050505050505050565b6106c7610afb565b6107086040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b61074a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b7e9050565b61075581888861107a565b8315610768576107686106338587611e95565b60005b8a63ffffffff168110156106b25761078561065783610c1c565b60025560058054600191906000906107a490849063ffffffff16611f5c565b92506101000a81548163ffffffff021916908363ffffffff16021790555080806107cd90611f80565b91505061076b565b6107dd610afb565b60005b8463ffffffff1681101561084d576107fd84846203d09085610f9b565b600255600580546001919060009061081c90849063ffffffff16611f5c565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061084590611f80565b9150506107e0565b5050505050565b6000606080600080600080610867610afb565b60025460055460038054909160049163ffffffff808316926801000000000000000081048216926c0100000000000000000000000082048316926401000000009092049091169086906108b990611cda565b80601f01602080910402602001604051908101604052809291908181526020018280546108e590611cda565b80156109325780601f1061090757610100808354040283529160200191610932565b820191906000526020600020905b81548152906001019060200180831161091557829003601f168201915b5050505050955084805461094590611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461097190611cda565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509450965096509650965096509650965090919293949596565b6109e4610afb565b6109ed8161113d565b50565b60028390556003610a018382611d7b565b506004610a0e8282611d7b565b508151600003610a59576001600560048282829054906101000a900463ffffffff16610a3a9190611f5c565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b805115610aa15760016005600c8282829054906101000a900463ffffffff16610a829190611f5c565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b815115801590610ab057508051155b15610af6576001600560088282829054906101000a900463ffffffff16610ad79190611f5c565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104c8565b565b610b8b8260008084611232565b5050565b8051600003610bca576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610c14576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b60606000610c2b6101006112c9565b9050610c756040518060400160405280600c81526020017f636f64654c6f636174696f6e0000000000000000000000000000000000000000815250826112ea90919063ffffffff16565b8251610c93906002811115610c8c57610c8c611fb8565b8290611303565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610cd29082906112ea565b6040830151610ce9908015610c8c57610c8c611fb8565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610d289082906112ea565b6060830151610d389082906112ea565b60a08301515115610de55760408051808201909152600481527f61726773000000000000000000000000000000000000000000000000000000006020820152610d829082906112ea565b610d8b8161133c565b60005b8360a0015151811015610ddb57610dcb8460a001518281518110610db457610db4611fe7565b6020026020010151836112ea90919063ffffffff16565b610dd481611f80565b9050610d8e565b50610de581611360565b60808301515115610ee657600083602001516002811115610e0857610e08611fb8565b03610e3f576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610e7e9082906112ea565b610e9783602001516002811115610c8c57610c8c611fb8565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610ed69082906112ea565b6080830151610ee690829061137e565b60c08301515115610f935760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610f309082906112ea565b610f398161133c565b60005b8360c0015151811015610f8957610f798460c001518281518110610f6257610f62611fe7565b60200260200101518361137e90919063ffffffff16565b610f8281611f80565b9050610f3c565b50610f9381611360565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401611000959493929190612016565b6020604051808303816000875af115801561101f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110439190612060565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b60006110876101006112c9565b90506110d16040518060400160405280600681526020017f736c6f7449440000000000000000000000000000000000000000000000000000815250826112ea90919063ffffffff16565b6110de8160ff851661138b565b60408051808201909152600781527f76657273696f6e00000000000000000000000000000000000000000000000000602082015261111d9082906112ea565b611127818361138b565b6002602085015251516080909301929092525050565b3373ffffffffffffffffffffffffffffffffffffffff8216036111bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104c8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b805160000361126d576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383600281111561128057611280611fb8565b9081600281111561129357611293611fb8565b905250604084018280156112a9576112a9611fb8565b908180156112b9576112b9611fb8565b9052506060909301929092525050565b6112d161176b565b80516112dd9083611397565b5060006020820152919050565b6112f78260038351611411565b8151610af69082611538565b81516113109060c2611560565b50610b8b828260405160200161132891815260200190565b60405160208183030381529060405261137e565b6113478160046115c9565b60018160200181815161135a9190612079565b90525050565b61136b8160076115c9565b60018160200181815161135a919061208c565b6112f78260028351611411565b610b8b82600083611411565b6040805180820190915260608152600060208201526113b760208361209f565b156113df576113c760208361209f565b6113d290602061208c565b6113dc9083612079565b91505b60208084018390526040518085526000815290818401018181101561140357600080fd5b604052508290505b92915050565b60178167ffffffffffffffff161161143e5782516114389060e0600585901b168317611560565b50505050565b60ff8167ffffffffffffffff1611611480578251611467906018611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660016115e0565b61ffff8167ffffffffffffffff16116114c35782516114aa906019611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660026115e0565b63ffffffff8167ffffffffffffffff16116115085782516114ef90601a611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660046115e0565b825161151f90601b611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660086115e0565b60408051808201909152606081526000602082015261155983838451611665565b9392505050565b6040805180820190915260608152600060208201528251516000611585826001612079565b9050846020015182106115a6576115a6856115a18360026120da565b611754565b84516020838201018581535080518211156115bf578181525b5093949350505050565b8151610af690601f611fe0600585901b1617611560565b60408051808201909152606081526000602082015283515160006116048285612079565b9050856020015181111561162157611621866115a18360026120da565b6000600161163186610100612211565b61163b919061208c565b90508651828101878319825116178152508051831115611659578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561168857600080fd5b83515160006116978483612079565b905085602001518111156116b4576116b4866115a18360026120da565b8551805183820160200191600091808511156116ce578482525b505050602086015b6020861061170e57805182526116ed602083612079565b91506116fa602082612079565b905061170760208761208c565b95506116d6565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516117608383611397565b506114388382611538565b6040518060400160405280611793604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611816576118166117a0565b604052919050565b600067ffffffffffffffff831115611838576118386117a0565b61186960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116016117cf565b905082815283838301111561187d57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126118a557600080fd5b6115598383356020850161181e565b6000806000606084860312156118c957600080fd5b83359250602084013567ffffffffffffffff808211156118e857600080fd5b6118f487838801611894565b9350604086013591508082111561190a57600080fd5b5061191786828701611894565b9150509250925092565b6000815180845260005b818110156119475760208185018101518683018201520161192b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006115596020830184611921565b803563ffffffff811681146119ac57600080fd5b919050565b60008083601f8401126119c357600080fd5b50813567ffffffffffffffff8111156119db57600080fd5b6020830191508360208285010111156119f357600080fd5b9250929050565b60008083601f840112611a0c57600080fd5b50813567ffffffffffffffff811115611a2457600080fd5b6020830191508360208260051b85010111156119f357600080fd5b803567ffffffffffffffff811681146119ac57600080fd5b600080600080600080600080600060c08a8c031215611a7557600080fd5b611a7e8a611998565b985060208a013567ffffffffffffffff80821115611a9b57600080fd5b611aa78d838e016119b1565b909a50985060408c0135915080821115611ac057600080fd5b611acc8d838e016119b1565b909850965060608c0135915080821115611ae557600080fd5b50611af28c828d016119fa565b9095509350611b05905060808b01611a3f565b915060a08a013590509295985092959850929598565b600080600080600080600080600060e08a8c031215611b3957600080fd5b611b428a611998565b985060208a013567ffffffffffffffff80821115611b5f57600080fd5b611b6b8d838e016119b1565b909a50985060408c0135915060ff82168214611b8657600080fd5b819750611b9560608d01611a3f565b965060808c0135915080821115611bab57600080fd5b50611bb88c828d016119fa565b9095509350611bcb905060a08b01611a3f565b915060c08a013590509295985092959850929598565b60008060008060808587031215611bf757600080fd5b611c0085611998565b9350602085013567ffffffffffffffff811115611c1c57600080fd5b611c2887828801611894565b935050611c3760408601611a3f565b9396929550929360600135925050565b87815260e060208201526000611c6060e0830189611921565b8281036040840152611c728189611921565b63ffffffff97881660608501529587166080840152505091841660a083015290921660c0909201919091529392505050565b600060208284031215611cb657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461155957600080fd5b600181811c90821680611cee57607f821691505b602082108103611d27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115610af657600081815260208120601f850160051c81016020861015611d545750805b601f850160051c820191505b81811015611d7357828155600101611d60565b505050505050565b815167ffffffffffffffff811115611d9557611d956117a0565b611da981611da38454611cda565b84611d2d565b602080601f831160018114611dfc5760008415611dc65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611d73565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611e4957888601518255948401946001909101908401611e2a565b5085821015611e8557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600067ffffffffffffffff80841115611eb057611eb06117a0565b8360051b6020611ec18183016117cf565b868152918501918181019036841115611ed957600080fd5b865b84811015611f2157803586811115611ef35760008081fd5b880136601f820112611f055760008081fd5b611f1336823587840161181e565b845250918301918301611edb565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff818116838216019080821115611f7957611f79611f2d565b5092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fb157611fb1611f2d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8616815260a06020820152600061203960a0830187611921565b61ffff9590951660408301525063ffffffff92909216606083015260809091015292915050565b60006020828403121561207257600080fd5b5051919050565b8082018082111561140b5761140b611f2d565b8181038181111561140b5761140b611f2d565b6000826120d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b808202811582820484141761140b5761140b611f2d565b600181815b8085111561214a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561213057612130611f2d565b8085161561213d57918102915b93841c93908002906120f6565b509250929050565b6000826121615750600161140b565b8161216e5750600061140b565b8160018114612184576002811461218e576121aa565b600191505061140b565b60ff84111561219f5761219f611f2d565b50506001821b61140b565b5060208310610133831016604e8410600b84101617156121cd575081810a61140b565b6121d783836120f1565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561220957612209611f2d565b029392505050565b6000611559838361215256fea164736f6c6343000813000a", } var FunctionsLoadTestClientABI = FunctionsLoadTestClientMetaData.ABI diff --git a/core/gethwrappers/functions/generated/functions_router/functions_router.go b/core/gethwrappers/functions/generated/functions_router/functions_router.go index 83c3f9b6132..b45052144ac 100644 --- a/core/gethwrappers/functions/generated/functions_router/functions_router.go +++ b/core/gethwrappers/functions/generated/functions_router/functions_router.go @@ -68,8 +68,8 @@ type IFunctionsSubscriptionsSubscription struct { } var FunctionsRouterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deductionAttempt\",\"type\":\"uint256\"}],\"name\":\"TotalBalanceInvariantViolated\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"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\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"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\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162006254380380620062548339810160408190526200003491620004df565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200067b565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b462000287565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b92910190620002ea565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516200027c9190620005dd565b60405180910390a150565b60065461010090046001600160a01b03163314620002e85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b828054828255906000526020600020906007016008900481019282156200038e5791602002820160005b838211156200035a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000314565b80156200038c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200035a565b505b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715620003f257620003f2620003b7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004235762000423620003b7565b604052919050565b805161ffff811681146200043e57600080fd5b919050565b600082601f8301126200045557600080fd5b815160206001600160401b03821115620004735762000473620003b7565b8160051b62000484828201620003f8565b92835284810182019282810190878511156200049f57600080fd5b83870192505b84831015620004d457825163ffffffff81168114620004c45760008081fd5b82529183019190830190620004a5565b979650505050505050565b60008060408385031215620004f357600080fd5b82516001600160a01b03811681146200050b57600080fd5b60208401519092506001600160401b03808211156200052957600080fd5b9084019060a082870312156200053e57600080fd5b62000548620003cd565b62000553836200042b565b815260208301516001600160481b03811681146200057057600080fd5b602082015260408301516001600160e01b0319811681146200059157600080fd5b6040820152620005a4606084016200042b565b6060820152608083015182811115620005bc57600080fd5b620005ca8882860162000443565b6080830152508093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160a080840152805160c0840181905260009291820190839060e08601905b808310156200067057835163ffffffff16825292840192600192909201919084019062000648565b509695505050505050565b608051615ba1620006b3600039600081816113b40152818161218701528181612a7f01528181612b4301526132be0152615ba16000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063aab396bd116100e3578063d7ae1d3011610097578063e82ad7d411610071578063e82ad7d4146106bf578063ea320e0b146106d2578063f2fde38b146106e557600080fd5b8063d7ae1d3014610686578063e72f6e3014610699578063e82622aa146106ac57600080fd5b8063badc3eb6116100c8578063badc3eb614610648578063c3f909d41461065e578063cc77470a1461067357600080fd5b8063aab396bd14610638578063b734c0f41461064057600080fd5b80639f87fad71161013a578063a47c76961161011f578063a47c7696146105f2578063a4c0ed3614610612578063a9c9a9181461062557600080fd5b80639f87fad7146105d7578063a21a23e4146105ea57600080fd5b8063823597401161016b57806382359740146105995780638456cb59146105ac5780638da5cb5b146105b457600080fd5b80637341c10c1461057e57806379ba50971461059157600080fd5b80633f4ba83a1161023f5780635c975abb116101f357806366419970116101cd57806366419970146104d6578063674603d0146104fd5780636a2215de1461054657600080fd5b80635c975abb146104995780635ed6dfba146104b057806366316d8d146104c357600080fd5b8063461d276211610224578063461d2762146104455780634b8832d31461045857806355fedefa1461046b57600080fd5b80633f4ba83a1461041c57806341db4ca31461042457600080fd5b80631ded3b36116102965780632a905ccc1161027b5780632a905ccc146103ba57806333060529146103e85780633e871e4d1461040957600080fd5b80631ded3b361461039457806321b60e7f146103a757600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f136600461487a565b6106f8565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f66103263660046148bb565b610757565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f9190614962565b6102f66103a2366004614975565b610853565b6102f66103b5366004614b38565b610885565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161030f565b6103fb6103f6366004614de4565b6109b2565b60405161030f929190614ecc565b6102f6610417366004614f59565b610d8a565b6102f661100f565b61043761043236600461505b565b611021565b60405190815260200161030f565b61043761045336600461505b565b611081565b6102f66104663660046150df565b61108d565b61043761047936600461487a565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f66104be36600461510d565b6111db565b6102f66104d136600461510d565b6113fd565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b61051061050b36600461513b565b61154f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161030f565b610559610554366004615169565b6115df565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f661058c3660046150df565b61169e565b6102f6611852565b6102f66105a736600461487a565b611979565b6102f6611ac0565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610559565b6102f66105e53660046150df565b611ad0565b6104e4611ea5565b61060561060036600461487a565b612032565b60405161030f91906151d3565b6102f661062036600461525b565b612167565b610559610633366004615169565b6123b3565b600954610437565b6102f6612412565b61065061255e565b60405161030f9291906152b7565b61066661262e565b60405161030f919061530e565b6104e46106813660046153b8565b612763565b6102f66106943660046150df565b6129e3565b6102f66106a73660046153b8565b612a46565b6102f66106ba3660046153d5565b612bbf565b6104a06106cd36600461487a565b612e90565b6102f66106e0366004615169565b612fdf565b6102f66106f33660046153b8565b612fec565b610700612ffd565b61070981613005565b67ffffffffffffffff81166000908152600360205260409020546107549082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661307b565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107bc576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106107d7576107d761544b565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff16111561084d576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107b3565b50505050565b61085b612ffd565b61086482613005565b67ffffffffffffffff90911660009081526003602081905260409091200155565b61088d613367565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361097492600b929101906146c5565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516109a7919061530e565b60405180910390a150565b6000806109bd6133ed565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a26576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251600090815260056020526040902054610a885782516020840151604051600294507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b60405180910390a2506000610d7f565b8251600090815260056020908152604091829020549151610aab918691016154ac565b6040516020818303038152906040528051906020012014610b035782516020840151604051600694507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b8261012001518360a0015163ffffffff16610b1e9190615608565b64ffffffffff165a1015610b695782516020840151604051600494507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b6000610b7e8460a0015163ffffffff166133f5565b610b88908861562d565b9050600081878660c0015168ffffffffffffffffff16610ba89190615655565b610bb29190615655565b9050610bc18560800151612032565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c395784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a90899061547a565b60405180910390a25060009150610d7f9050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c9e5784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a90899061547a565b505082516000908152600560205260408120819055835160a08501516060860151610cce92918c918c9190613497565b8051909150610cde576001610ce1565b60005b92506000610d1b8560800151866040015187606001518860c0015168ffffffffffffffffff168c610d1588602001516133f5565b8d613626565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610d729695949392919061567a565b60405180910390a3519150505b965096945050505050565b610d92613367565b8151815181141580610da45750600881115b15610ddb576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ecd576000848281518110610dfa57610dfa61544b565b602002602001015190506000848381518110610e1857610e1861544b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e83575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610eba576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080610ec6906156fd565b9050610dde565b506040805180820190915283815260208082018490528451600c91610ef6918391880190614770565b506020828101518051610f0f92600185019201906147ab565b5090505060005b835181101561084d577f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481848281518110610f5257610f5261544b565b602002602001015160086000878581518110610f7057610f7061544b565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858481518110610fb957610fb961544b565b6020026020010151604051610ff79392919092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a1611008816156fd565b9050610f16565b611017613367565b61101f6139a8565b565b60008061102d836115df565b905061107583828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613a259050565b98975050505050505050565b60008061102d836123b3565b6110956133ed565b61109e82613dce565b6110a6613e94565b73ffffffffffffffffffffffffffffffffffffffff8116158061110d575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15611144576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6111e3612ffd565b806bffffffffffffffffffffffff166000036112195750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611285576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff808416911610156112ee576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b306000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff166113719190615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506113f883836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613f9e9092919063ffffffff16565b505050565b6114056133ed565b806bffffffffffffffffffffffff1660000361144d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff9081169082168110156114b9576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff80841691161015611522576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b336000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615735565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600c5460ff8216101561166857600c805460ff83169081106116075761160761544b565b9060005260206000200154830361165857600d805460ff831690811061162f5761162f61544b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b6116618161575a565b90506115e3565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107b3565b6116a66133ed565b6116af82613dce565b6116b7613e94565b60006116c6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff82169003611729576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff161561177157505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff1633146118d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107b3565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6119816133ed565b611989613e94565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611a29576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107b3565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611845565b611ac8613367565b61101f61402b565b611ad86133ed565b611ae182613dce565b611ae9613e94565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b91576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611be6576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611c6157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c36575b5050505050905060005b8151811015611e09578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c9d57611c9d61544b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611df9578160018351611ccf9190615779565b81518110611cdf57611cdf61544b565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611d2257611d2261544b565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d9c57611d9c61578c565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611e09565b611e02816156fd565b9050611c6b565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b6000611eaf6133ed565b611eb7613e94565b60028054600090611ed19067ffffffffffffffff166157bb565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611f47578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611fe2926002850192909101906147ab565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a081019190915261206c82613005565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561214d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612122575b505050505081526020016003820154815250509050919050565b61216f6133ed565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146121de576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612218576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122268284018461487a565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661229f576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906122d68385615655565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff1661232c9190615655565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f882878461239391906157e2565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff16806115d9576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107b3565b61241a613367565b60005b600c5481101561253d576000600c600001828154811061243f5761243f61544b565b906000526020600020015490506000600c60010183815481106124645761246461544b565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055612536816156fd565b905061241d565b50600c600061254c8282614825565b61255a600183016000614825565b5050565b606080600c600001600c600101818054806020026020016040519081016040528092919081815260200182805480156125b657602002820191906000526020600020905b8154815260200190600101908083116125a2575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561261f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116125f4575b50505050509050915091509091565b6040805160a08101825260008082526020820181905291810182905260608082019290925260808101919091526040805160a081018252600a805461ffff808216845268ffffffffffffffffff620100008304166020808601919091527fffffffff000000000000000000000000000000000000000000000000000000006b010000000000000000000000840460e01b16858701526f01000000000000000000000000000000909204166060840152600b80548551818402810184019096528086529394929360808601939283018282801561275557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116127185790505b505050505081525050905090565b600061276d6133ed565b612775613e94565b6002805460009061278f9067ffffffffffffffff166157bb565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015612805578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff93841617845593860151606087015190911690930292169190911760018201556080830151805191926128a0926002850192909101906147ab565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b6129eb6133ed565b6129f482613dce565b6129fc613e94565b612a0582612e90565b15612a3c576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61255a828261307b565b612a4e612ffd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff91906157f5565b6000549091506bffffffffffffffffffffffff16818110156113f8576000612b278284615779565b9050612b6a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583613f9e565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612bc76133ed565b60005b818110156113f8576000838383818110612be657612be661544b565b90506101600201803603810190612bfd919061580e565b80516080820151600082815260056020908152604091829020549151949550929391929091612c2e918691016154ac565b6040516020818303038152906040528051906020012014612c7b576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612cc0576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d57919061582b565b5060408084015167ffffffffffffffff831660009081526003602052918220600101805491929091612d989084906bffffffffffffffffffffffff16615735565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612e20918591690100000000000000000090041661584d565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612e89906156fd565b9050612bca565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612f0857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612edd575b5050505050905060005b8151811015612fd557600060046000848481518110612f3357612f3361544b565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612fc457506001949350505050565b50612fce816156fd565b9050612f12565b5060009392505050565b612fe7613367565b600955565b612ff4613367565b61075481614086565b61101f613367565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610754576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561315c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613131575b505050918352505060039190910154602090910152805190915060005b82608001515181101561321d5760046000846080015183815181106131a0576131a061544b565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff0000000000000000000000000000000000169055613216816156fd565b9050613179565b5067ffffffffffffffff84166000908152600360205260408120818155600181018290559061324f6002830182614825565b5060006003919091018190558054829190819061327b9084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061330283826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613f9e9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e97565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16331461101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107b3565b61101f614182565b60006bffffffffffffffffffffffff821115613493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107b3565b5090565b60408051606080820183526000808352602083015291810191909152600a546040516000916b010000000000000000000000900460e01b906134e19089908990899060240161586e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f0100000000000000000000000000000090910416926000928392839282018180368337019050509050863b6135ac57600080fd5b5a848110156135ba57600080fd5b84900360408104810389106135ce57600080fd5b505a60008087516020890160008c8ef193505a900391503d60848111156135f3575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015298975050505050505050565b60408051808201909152600080825260208201526000613646848661562d565b90506000816136558886615655565b61365f9190615655565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff808316911610156136f25767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812080548392906137299084906bffffffffffffffffffffffff16615735565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600360205260409020600101548b82169116101590506137d65767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812060010180548b92906138109084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461384a9190615655565b33600090815260016020526040812080549091906138779084906bffffffffffffffffffffffff16615655565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926138be91859116615655565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f16855292529091208054600192600991613942918591690100000000000000000090041661584d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b6139b06141ef565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613a2f6133ed565b613a3885613005565b613a42338661425b565b613a4c8583610757565b8351600003613a86576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613a9186612032565b90506000613a9f338861154f565b905060008873ffffffffffffffffffffffffffffffffffffffff1663a631571e6040518061016001604052808a8152602001613af58c67ffffffffffffffff166000908152600360208190526040909120015490565b815233602082015260408781015188519190920191613b1391615735565b6bffffffffffffffffffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018b67ffffffffffffffff168152602001856020015167ffffffffffffffff1681526020018863ffffffff1681526020018961ffff168152602001856040015167ffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613bd99190615899565b610160604051808303816000875af1158015613bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1d91906159fe565b9050604051806101600160405280826000015181526020018a73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018967ffffffffffffffff1681526020018663ffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff16815250604051602001613d2491906154ac565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550613d64338983604001516142cf565b8767ffffffffffffffff168a82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9866020015133328d8d8d8a60400151604051613db89796959493929190615ad1565b60405180910390a4519998505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613e45576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461255a576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613ec45750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613f2590339060248101615b49565b602060405180830381865afa158015613f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f66919061582b565b610754576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107b3565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f89084906143aa565b614033614182565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586139fb3390565b3373ffffffffffffffffffffffffffffffffffffffff821603614105576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107b3565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff161561101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107b3565b60065460ff1661101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff1661255a576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143099084906bffffffffffffffffffffffff16615655565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff808916855292529091208054600194509092849261437f92849290041661584d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b600061440c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166144b69092919063ffffffff16565b8051909150156113f8578080602001905181019061442a919061582b565b6113f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107b3565b60606144c584846000856144cd565b949350505050565b60608247101561455f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107b3565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516145889190615b78565b60006040518083038185875af1925050503d80600081146145c5576040519150601f19603f3d011682016040523d82523d6000602084013e6145ca565b606091505b50915091506145db878383876145e6565b979650505050505050565b6060831561467c5782516000036146755773ffffffffffffffffffffffffffffffffffffffff85163b614675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b50816144c5565b6144c583838151156146915781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b39190614962565b828054828255906000526020600020906007016008900481019282156147645791602002820160005b8382111561473257835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026146ee565b80156147625782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614732565b505b5061349392915061483f565b828054828255906000526020600020908101928215614764579160200282015b82811115614764578251825591602001919060010190614790565b828054828255906000526020600020908101928215614764579160200282015b8281111561476457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906147cb565b508054600082559060005260206000209081019061075491905b5b808211156134935760008155600101614840565b67ffffffffffffffff8116811461075457600080fd5b803561487581614854565b919050565b60006020828403121561488c57600080fd5b813561489781614854565b9392505050565b63ffffffff8116811461075457600080fd5b80356148758161489e565b600080604083850312156148ce57600080fd5b82356148d981614854565b915060208301356148e98161489e565b809150509250929050565b60005b8381101561490f5781810151838201526020016148f7565b50506000910152565b600081518084526149308160208601602086016148f4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006148976020830184614918565b6000806040838503121561498857600080fd5b823561499381614854565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156149f3576149f36149a1565b60405290565b604051610160810167ffffffffffffffff811182821017156149f3576149f36149a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a6457614a646149a1565b604052919050565b803561ffff8116811461487557600080fd5b68ffffffffffffffffff8116811461075457600080fd5b803561487581614a7e565b600067ffffffffffffffff821115614aba57614aba6149a1565b5060051b60200190565b600082601f830112614ad557600080fd5b81356020614aea614ae583614aa0565b614a1d565b82815260059290921b84018101918181019086841115614b0957600080fd5b8286015b84811015614b2d578035614b208161489e565b8352918301918301614b0d565b509695505050505050565b600060208284031215614b4a57600080fd5b813567ffffffffffffffff80821115614b6257600080fd5b9083019060a08286031215614b7657600080fd5b614b7e6149d0565b614b8783614a6c565b81526020830135614b9781614a7e565b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114614bcf57600080fd5b6040820152614be060608401614a6c565b6060820152608083013582811115614bf757600080fd5b614c0387828601614ac4565b60808301525095945050505050565b600082601f830112614c2357600080fd5b813567ffffffffffffffff811115614c3d57614c3d6149a1565b614c6e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a1d565b818152846020838601011115614c8357600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461075457600080fd5b803561487581614ca0565b73ffffffffffffffffffffffffffffffffffffffff8116811461075457600080fd5b803561487581614cc5565b64ffffffffff8116811461075457600080fd5b803561487581614cf2565b60006101608284031215614d2357600080fd5b614d2b6149f9565b905081358152614d3d60208301614ce7565b6020820152614d4e60408301614cba565b6040820152614d5f60608301614ce7565b6060820152614d706080830161486a565b6080820152614d8160a083016148b0565b60a0820152614d9260c08301614a95565b60c0820152614da360e08301614a95565b60e0820152610100614db6818401614d05565b90820152610120614dc8838201614d05565b90820152610140614dda8382016148b0565b9082015292915050565b6000806000806000806102008789031215614dfe57600080fd5b863567ffffffffffffffff80821115614e1657600080fd5b614e228a838b01614c12565b97506020890135915080821115614e3857600080fd5b50614e4589828a01614c12565b9550506040870135614e5681614ca0565b93506060870135614e6681614ca0565b92506080870135614e7681614cc5565b9150614e858860a08901614d10565b90509295509295509295565b60078110614ec8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60408101614eda8285614e91565b6bffffffffffffffffffffffff831660208301529392505050565b600082601f830112614f0657600080fd5b81356020614f16614ae583614aa0565b82815260059290921b84018101918181019086841115614f3557600080fd5b8286015b84811015614b2d578035614f4c81614cc5565b8352918301918301614f39565b60008060408385031215614f6c57600080fd5b823567ffffffffffffffff80821115614f8457600080fd5b818501915085601f830112614f9857600080fd5b81356020614fa8614ae583614aa0565b82815260059290921b84018101918181019089841115614fc757600080fd5b948201945b83861015614fe557853582529482019490820190614fcc565b96505086013592505080821115614ffb57600080fd5b5061500885828601614ef5565b9150509250929050565b60008083601f84011261502457600080fd5b50813567ffffffffffffffff81111561503c57600080fd5b60208301915083602082850101111561505457600080fd5b9250929050565b60008060008060008060a0878903121561507457600080fd5b863561507f81614854565b9550602087013567ffffffffffffffff81111561509b57600080fd5b6150a789828a01615012565b90965094506150ba905060408801614a6c565b925060608701356150ca8161489e565b80925050608087013590509295509295509295565b600080604083850312156150f257600080fd5b82356150fd81614854565b915060208301356148e981614cc5565b6000806040838503121561512057600080fd5b823561512b81614cc5565b915060208301356148e981614ca0565b6000806040838503121561514e57600080fd5b823561515981614cc5565b915060208301356148e981614854565b60006020828403121561517b57600080fd5b5035919050565b600081518084526020808501945080840160005b838110156151c857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101615196565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a084015261524560e0840182615182565b905060a084015160c08401528091505092915050565b6000806000806060858703121561527157600080fd5b843561527c81614cc5565b935060208501359250604085013567ffffffffffffffff81111561529f57600080fd5b6152ab87828801615012565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b828110156152f0578151845292840192908401906001016152d4565b505050838103828501526153048186615182565b9695505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b80831015614b2d57835163ffffffff168252928401926001929092019190840190615392565b6000602082840312156153ca57600080fd5b813561489781614cc5565b600080602083850312156153e857600080fd5b823567ffffffffffffffff8082111561540057600080fd5b818501915085601f83011261541457600080fd5b81358181111561542357600080fd5b8660206101608302850101111561543957600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016144c56040830184614e91565b815181526020808301516101608301916154dd9084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516154fd60408401826bffffffffffffffffffffffff169052565b506060830151615525606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151615541608084018267ffffffffffffffff169052565b5060a083015161555960a084018263ffffffff169052565b5060c083015161557660c084018268ffffffffffffffffff169052565b5060e083015161559360e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff818116838216019080821115615626576156266155d9565b5092915050565b6bffffffffffffffffffffffff8181168382160280821691908281146155d1576155d16155d9565b6bffffffffffffffffffffffff818116838216019080821115615626576156266155d9565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff861660208201526156b46040820186614e91565b60c0606082015260006156ca60c0830186614918565b82810360808401526156dc8186614918565b905082810360a08401526156f08185614918565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361572e5761572e6155d9565b5060010190565b6bffffffffffffffffffffffff828116828216039080821115615626576156266155d9565b600060ff821660ff8103615770576157706155d9565b60010192915050565b818103818111156115d9576115d96155d9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff8083168181036157d8576157d86155d9565b6001019392505050565b808201808211156115d9576115d96155d9565b60006020828403121561580757600080fd5b5051919050565b6000610160828403121561582157600080fd5b6148978383614d10565b60006020828403121561583d57600080fd5b8151801515811461489757600080fd5b67ffffffffffffffff818116838216019080821115615626576156266155d9565b8381526060602082015260006158876060830185614918565b82810360408401526153048185614918565b60208152600082516101608060208501526158b8610180850183614918565b91506020850151604085015260408501516158eb606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e08501516101006159628187018363ffffffff169052565b86015190506101206159798682018361ffff169052565b86015190506101406159968682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b805161487581614cc5565b805161487581614ca0565b805161487581614854565b80516148758161489e565b805161487581614a7e565b805161487581614cf2565b60006101608284031215615a1157600080fd5b615a196149f9565b82518152615a29602084016159bc565b6020820152615a3a604084016159c7565b6040820152615a4b606084016159bc565b6060820152615a5c608084016159d2565b6080820152615a6d60a084016159dd565b60a0820152615a7e60c084016159e8565b60c0820152615a8f60e084016159e8565b60e0820152610100615aa28185016159f3565b90820152610120615ab48482016159f3565b90820152610140615ac68482016159dd565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615b1260e0830187614918565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006144c56040830184614918565b60008251615b8a8184602087016148f4565b919091019291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateRequestId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deductionAttempt\",\"type\":\"uint256\"}],\"name\":\"TotalBalanceInvariantViolated\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"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\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"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\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620062a3380380620062a38339810160408190526200003491620004df565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200067b565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b462000287565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b92910190620002ea565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516200027c9190620005dd565b60405180910390a150565b60065461010090046001600160a01b03163314620002e85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b828054828255906000526020600020906007016008900481019282156200038e5791602002820160005b838211156200035a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000314565b80156200038c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200035a565b505b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715620003f257620003f2620003b7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004235762000423620003b7565b604052919050565b805161ffff811681146200043e57600080fd5b919050565b600082601f8301126200045557600080fd5b815160206001600160401b03821115620004735762000473620003b7565b8160051b62000484828201620003f8565b92835284810182019282810190878511156200049f57600080fd5b83870192505b84831015620004d457825163ffffffff81168114620004c45760008081fd5b82529183019190830190620004a5565b979650505050505050565b60008060408385031215620004f357600080fd5b82516001600160a01b03811681146200050b57600080fd5b60208401519092506001600160401b03808211156200052957600080fd5b9084019060a082870312156200053e57600080fd5b62000548620003cd565b62000553836200042b565b815260208301516001600160481b03811681146200057057600080fd5b602082015260408301516001600160e01b0319811681146200059157600080fd5b6040820152620005a4606084016200042b565b6060820152608083015182811115620005bc57600080fd5b620005ca8882860162000443565b6080830152508093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160a080840152805160c0840181905260009291820190839060e08601905b808310156200067057835163ffffffff16825292840192600192909201919084019062000648565b509695505050505050565b608051615bf0620006b3600039600081816113b40152818161218701528181612a7f01528181612b4301526132be0152615bf06000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063aab396bd116100e3578063d7ae1d3011610097578063e82ad7d411610071578063e82ad7d4146106bf578063ea320e0b146106d2578063f2fde38b146106e557600080fd5b8063d7ae1d3014610686578063e72f6e3014610699578063e82622aa146106ac57600080fd5b8063badc3eb6116100c8578063badc3eb614610648578063c3f909d41461065e578063cc77470a1461067357600080fd5b8063aab396bd14610638578063b734c0f41461064057600080fd5b80639f87fad71161013a578063a47c76961161011f578063a47c7696146105f2578063a4c0ed3614610612578063a9c9a9181461062557600080fd5b80639f87fad7146105d7578063a21a23e4146105ea57600080fd5b8063823597401161016b57806382359740146105995780638456cb59146105ac5780638da5cb5b146105b457600080fd5b80637341c10c1461057e57806379ba50971461059157600080fd5b80633f4ba83a1161023f5780635c975abb116101f357806366419970116101cd57806366419970146104d6578063674603d0146104fd5780636a2215de1461054657600080fd5b80635c975abb146104995780635ed6dfba146104b057806366316d8d146104c357600080fd5b8063461d276211610224578063461d2762146104455780634b8832d31461045857806355fedefa1461046b57600080fd5b80633f4ba83a1461041c57806341db4ca31461042457600080fd5b80631ded3b36116102965780632a905ccc1161027b5780632a905ccc146103ba57806333060529146103e85780633e871e4d1461040957600080fd5b80631ded3b361461039457806321b60e7f146103a757600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f13660046148c9565b6106f8565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f661032636600461490a565b610757565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f91906149b1565b6102f66103a23660046149c4565b610853565b6102f66103b5366004614b87565b610885565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161030f565b6103fb6103f6366004614e33565b6109b2565b60405161030f929190614f1b565b6102f6610417366004614fa8565b610d8a565b6102f661100f565b6104376104323660046150aa565b611021565b60405190815260200161030f565b6104376104533660046150aa565b611081565b6102f661046636600461512e565b61108d565b6104376104793660046148c9565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f66104be36600461515c565b6111db565b6102f66104d136600461515c565b6113fd565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b61051061050b36600461518a565b61154f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161030f565b6105596105543660046151b8565b6115df565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f661058c36600461512e565b61169e565b6102f6611852565b6102f66105a73660046148c9565b611979565b6102f6611ac0565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610559565b6102f66105e536600461512e565b611ad0565b6104e4611ea5565b6106056106003660046148c9565b612032565b60405161030f9190615222565b6102f66106203660046152aa565b612167565b6105596106333660046151b8565b6123b3565b600954610437565b6102f6612412565b61065061255e565b60405161030f929190615306565b61066661262e565b60405161030f919061535d565b6104e4610681366004615407565b612763565b6102f661069436600461512e565b6129e3565b6102f66106a7366004615407565b612a46565b6102f66106ba366004615424565b612bbf565b6104a06106cd3660046148c9565b612e90565b6102f66106e03660046151b8565b612fdf565b6102f66106f3366004615407565b612fec565b610700612ffd565b61070981613005565b67ffffffffffffffff81166000908152600360205260409020546107549082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661307b565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107bc576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106107d7576107d761549a565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff16111561084d576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107b3565b50505050565b61085b612ffd565b61086482613005565b67ffffffffffffffff90911660009081526003602081905260409091200155565b61088d613367565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361097492600b92910190614714565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516109a7919061535d565b60405180910390a150565b6000806109bd6133ed565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a26576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251600090815260056020526040902054610a885782516020840151604051600294507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154c9565b60405180910390a2506000610d7f565b8251600090815260056020908152604091829020549151610aab918691016154fb565b6040516020818303038152906040528051906020012014610b035782516020840151604051600694507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154c9565b8261012001518360a0015163ffffffff16610b1e9190615657565b64ffffffffff165a1015610b695782516020840151604051600494507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154c9565b6000610b7e8460a0015163ffffffff166133f5565b610b88908861567c565b9050600081878660c0015168ffffffffffffffffff16610ba891906156a4565b610bb291906156a4565b9050610bc18560800151612032565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c395784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154c9565b60405180910390a25060009150610d7f9050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c9e5784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154c9565b505082516000908152600560205260408120819055835160a08501516060860151610cce92918c918c9190613497565b8051909150610cde576001610ce1565b60005b92506000610d1b8560800151866040015187606001518860c0015168ffffffffffffffffff168c610d1588602001516133f5565b8d613626565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610d72969594939291906156c9565b60405180910390a3519150505b965096945050505050565b610d92613367565b8151815181141580610da45750600881115b15610ddb576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ecd576000848281518110610dfa57610dfa61549a565b602002602001015190506000848381518110610e1857610e1861549a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e83575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610eba576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080610ec69061574c565b9050610dde565b506040805180820190915283815260208082018490528451600c91610ef69183918801906147bf565b506020828101518051610f0f92600185019201906147fa565b5090505060005b835181101561084d577f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481848281518110610f5257610f5261549a565b602002602001015160086000878581518110610f7057610f7061549a565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858481518110610fb957610fb961549a565b6020026020010151604051610ff79392919092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a16110088161574c565b9050610f16565b611017613367565b61101f6139a8565b565b60008061102d836115df565b905061107583828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613a259050565b98975050505050505050565b60008061102d836123b3565b6110956133ed565b61109e82613e1d565b6110a6613ee3565b73ffffffffffffffffffffffffffffffffffffffff8116158061110d575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15611144576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6111e3612ffd565b806bffffffffffffffffffffffff166000036112195750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611285576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff808416911610156112ee576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b306000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff166113719190615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506113f883836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613fed9092919063ffffffff16565b505050565b6114056133ed565b806bffffffffffffffffffffffff1660000361144d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff9081169082168110156114b9576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff80841691161015611522576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b336000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615784565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600c5460ff8216101561166857600c805460ff83169081106116075761160761549a565b9060005260206000200154830361165857600d805460ff831690811061162f5761162f61549a565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b611661816157a9565b90506115e3565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107b3565b6116a66133ed565b6116af82613e1d565b6116b7613ee3565b60006116c6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff82169003611729576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff161561177157505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff1633146118d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107b3565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6119816133ed565b611989613ee3565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611a29576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107b3565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611845565b611ac8613367565b61101f61407a565b611ad86133ed565b611ae182613e1d565b611ae9613ee3565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b91576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611be6576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611c6157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c36575b5050505050905060005b8151811015611e09578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c9d57611c9d61549a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611df9578160018351611ccf91906157c8565b81518110611cdf57611cdf61549a565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611d2257611d2261549a565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d9c57611d9c6157db565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611e09565b611e028161574c565b9050611c6b565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b6000611eaf6133ed565b611eb7613ee3565b60028054600090611ed19067ffffffffffffffff1661580a565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611f47578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611fe2926002850192909101906147fa565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a081019190915261206c82613005565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561214d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612122575b505050505081526020016003820154815250509050919050565b61216f6133ed565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146121de576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612218576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612226828401846148c9565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661229f576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906122d683856156a4565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff1661232c91906156a4565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846123939190615831565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff16806115d9576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107b3565b61241a613367565b60005b600c5481101561253d576000600c600001828154811061243f5761243f61549a565b906000526020600020015490506000600c60010183815481106124645761246461549a565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556125368161574c565b905061241d565b50600c600061254c8282614874565b61255a600183016000614874565b5050565b606080600c600001600c600101818054806020026020016040519081016040528092919081815260200182805480156125b657602002820191906000526020600020905b8154815260200190600101908083116125a2575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561261f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116125f4575b50505050509050915091509091565b6040805160a08101825260008082526020820181905291810182905260608082019290925260808101919091526040805160a081018252600a805461ffff808216845268ffffffffffffffffff620100008304166020808601919091527fffffffff000000000000000000000000000000000000000000000000000000006b010000000000000000000000840460e01b16858701526f01000000000000000000000000000000909204166060840152600b80548551818402810184019096528086529394929360808601939283018282801561275557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116127185790505b505050505081525050905090565b600061276d6133ed565b612775613ee3565b6002805460009061278f9067ffffffffffffffff1661580a565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015612805578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff93841617845593860151606087015190911690930292169190911760018201556080830151805191926128a0926002850192909101906147fa565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b6129eb6133ed565b6129f482613e1d565b6129fc613ee3565b612a0582612e90565b15612a3c576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61255a828261307b565b612a4e612ffd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff9190615844565b6000549091506bffffffffffffffffffffffff16818110156113f8576000612b2782846157c8565b9050612b6a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583613fed565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612bc76133ed565b60005b818110156113f8576000838383818110612be657612be661549a565b90506101600201803603810190612bfd919061585d565b80516080820151600082815260056020908152604091829020549151949550929391929091612c2e918691016154fb565b6040516020818303038152906040528051906020012014612c7b576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612cc0576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d57919061587a565b5060408084015167ffffffffffffffff831660009081526003602052918220600101805491929091612d989084906bffffffffffffffffffffffff16615784565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612e20918591690100000000000000000090041661589c565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612e899061574c565b9050612bca565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612f0857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612edd575b5050505050905060005b8151811015612fd557600060046000848481518110612f3357612f3361549a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612fc457506001949350505050565b50612fce8161574c565b9050612f12565b5060009392505050565b612fe7613367565b600955565b612ff4613367565b610754816140d5565b61101f613367565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610754576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561315c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613131575b505050918352505060039190910154602090910152805190915060005b82608001515181101561321d5760046000846080015183815181106131a0576131a061549a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690556132168161574c565b9050613179565b5067ffffffffffffffff84166000908152600360205260408120818155600181018290559061324f6002830182614874565b5060006003919091018190558054829190819061327b9084906bffffffffffffffffffffffff16615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061330283826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613fed9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e97565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16331461101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107b3565b61101f6141d1565b60006bffffffffffffffffffffffff821115613493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107b3565b5090565b60408051606080820183526000808352602083015291810191909152600a546040516000916b010000000000000000000000900460e01b906134e1908990899089906024016158bd565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f0100000000000000000000000000000090910416926000928392839282018180368337019050509050863b6135ac57600080fd5b5a848110156135ba57600080fd5b84900360408104810389106135ce57600080fd5b505a60008087516020890160008c8ef193505a900391503d60848111156135f3575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015298975050505050505050565b60408051808201909152600080825260208201526000613646848661567c565b905060008161365588866156a4565b61365f91906156a4565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff808316911610156136f25767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812080548392906137299084906bffffffffffffffffffffffff16615784565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600360205260409020600101548b82169116101590506137d65767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812060010180548b92906138109084906bffffffffffffffffffffffff16615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461384a91906156a4565b33600090815260016020526040812080549091906138779084906bffffffffffffffffffffffff166156a4565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926138be918591166156a4565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f16855292529091208054600192600991613942918591690100000000000000000090041661589c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b6139b061423e565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613a2f6133ed565b613a3885613005565b613a4233866142aa565b613a4c8583610757565b8351600003613a86576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613a9186612032565b90506000613a9f338861154f565b905060008873ffffffffffffffffffffffffffffffffffffffff1663a631571e6040518061016001604052808a8152602001613af58c67ffffffffffffffff166000908152600360208190526040909120015490565b815233602082015260408781015188519190920191613b1391615784565b6bffffffffffffffffffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018b67ffffffffffffffff168152602001856020015167ffffffffffffffff1681526020018863ffffffff1681526020018961ffff168152602001856040015167ffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613bd991906158e8565b610160604051808303816000875af1158015613bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1d9190615a4d565b805160009081526005602052604090205490915015613c6e5780516040517f304f32e800000000000000000000000000000000000000000000000000000000815260048101919091526024016107b3565b604051806101600160405280826000015181526020018a73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018967ffffffffffffffff1681526020018663ffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff16815250604051602001613d7391906154fb565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550613db33389836040015161431e565b8767ffffffffffffffff168a82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9866020015133328d8d8d8a60400151604051613e079796959493929190615b20565b60405180910390a4519998505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613e94576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461255a576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613f135750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613f7490339060248101615b98565b602060405180830381865afa158015613f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb5919061587a565b610754576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107b3565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f89084906143f9565b6140826141d1565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586139fb3390565b3373ffffffffffffffffffffffffffffffffffffffff821603614154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107b3565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff161561101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107b3565b60065460ff1661101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff1661255a576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143589084906bffffffffffffffffffffffff166156a4565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff80891685529252909120805460019450909284926143ce92849290041661589c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b600061445b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166145059092919063ffffffff16565b8051909150156113f85780806020019051810190614479919061587a565b6113f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107b3565b6060614514848460008561451c565b949350505050565b6060824710156145ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107b3565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516145d79190615bc7565b60006040518083038185875af1925050503d8060008114614614576040519150601f19603f3d011682016040523d82523d6000602084013e614619565b606091505b509150915061462a87838387614635565b979650505050505050565b606083156146cb5782516000036146c45773ffffffffffffffffffffffffffffffffffffffff85163b6146c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b5081614514565b61451483838151156146e05781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b391906149b1565b828054828255906000526020600020906007016008900481019282156147b35791602002820160005b8382111561478157835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261473d565b80156147b15782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614781565b505b5061349392915061488e565b8280548282559060005260206000209081019282156147b3579160200282015b828111156147b35782518255916020019190600101906147df565b8280548282559060005260206000209081019282156147b3579160200282015b828111156147b357825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061481a565b508054600082559060005260206000209081019061075491905b5b80821115613493576000815560010161488f565b67ffffffffffffffff8116811461075457600080fd5b80356148c4816148a3565b919050565b6000602082840312156148db57600080fd5b81356148e6816148a3565b9392505050565b63ffffffff8116811461075457600080fd5b80356148c4816148ed565b6000806040838503121561491d57600080fd5b8235614928816148a3565b91506020830135614938816148ed565b809150509250929050565b60005b8381101561495e578181015183820152602001614946565b50506000910152565b6000815180845261497f816020860160208601614943565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006148e66020830184614967565b600080604083850312156149d757600080fd5b82356149e2816148a3565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614a4257614a426149f0565b60405290565b604051610160810167ffffffffffffffff81118282101715614a4257614a426149f0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ab357614ab36149f0565b604052919050565b803561ffff811681146148c457600080fd5b68ffffffffffffffffff8116811461075457600080fd5b80356148c481614acd565b600067ffffffffffffffff821115614b0957614b096149f0565b5060051b60200190565b600082601f830112614b2457600080fd5b81356020614b39614b3483614aef565b614a6c565b82815260059290921b84018101918181019086841115614b5857600080fd5b8286015b84811015614b7c578035614b6f816148ed565b8352918301918301614b5c565b509695505050505050565b600060208284031215614b9957600080fd5b813567ffffffffffffffff80821115614bb157600080fd5b9083019060a08286031215614bc557600080fd5b614bcd614a1f565b614bd683614abb565b81526020830135614be681614acd565b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114614c1e57600080fd5b6040820152614c2f60608401614abb565b6060820152608083013582811115614c4657600080fd5b614c5287828601614b13565b60808301525095945050505050565b600082601f830112614c7257600080fd5b813567ffffffffffffffff811115614c8c57614c8c6149f0565b614cbd60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a6c565b818152846020838601011115614cd257600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461075457600080fd5b80356148c481614cef565b73ffffffffffffffffffffffffffffffffffffffff8116811461075457600080fd5b80356148c481614d14565b64ffffffffff8116811461075457600080fd5b80356148c481614d41565b60006101608284031215614d7257600080fd5b614d7a614a48565b905081358152614d8c60208301614d36565b6020820152614d9d60408301614d09565b6040820152614dae60608301614d36565b6060820152614dbf608083016148b9565b6080820152614dd060a083016148ff565b60a0820152614de160c08301614ae4565b60c0820152614df260e08301614ae4565b60e0820152610100614e05818401614d54565b90820152610120614e17838201614d54565b90820152610140614e298382016148ff565b9082015292915050565b6000806000806000806102008789031215614e4d57600080fd5b863567ffffffffffffffff80821115614e6557600080fd5b614e718a838b01614c61565b97506020890135915080821115614e8757600080fd5b50614e9489828a01614c61565b9550506040870135614ea581614cef565b93506060870135614eb581614cef565b92506080870135614ec581614d14565b9150614ed48860a08901614d5f565b90509295509295509295565b60078110614f17577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60408101614f298285614ee0565b6bffffffffffffffffffffffff831660208301529392505050565b600082601f830112614f5557600080fd5b81356020614f65614b3483614aef565b82815260059290921b84018101918181019086841115614f8457600080fd5b8286015b84811015614b7c578035614f9b81614d14565b8352918301918301614f88565b60008060408385031215614fbb57600080fd5b823567ffffffffffffffff80821115614fd357600080fd5b818501915085601f830112614fe757600080fd5b81356020614ff7614b3483614aef565b82815260059290921b8401810191818101908984111561501657600080fd5b948201945b838610156150345785358252948201949082019061501b565b9650508601359250508082111561504a57600080fd5b5061505785828601614f44565b9150509250929050565b60008083601f84011261507357600080fd5b50813567ffffffffffffffff81111561508b57600080fd5b6020830191508360208285010111156150a357600080fd5b9250929050565b60008060008060008060a087890312156150c357600080fd5b86356150ce816148a3565b9550602087013567ffffffffffffffff8111156150ea57600080fd5b6150f689828a01615061565b9096509450615109905060408801614abb565b92506060870135615119816148ed565b80925050608087013590509295509295509295565b6000806040838503121561514157600080fd5b823561514c816148a3565b9150602083013561493881614d14565b6000806040838503121561516f57600080fd5b823561517a81614d14565b9150602083013561493881614cef565b6000806040838503121561519d57600080fd5b82356151a881614d14565b91506020830135614938816148a3565b6000602082840312156151ca57600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561521757815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016151e5565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a084015261529460e08401826151d1565b905060a084015160c08401528091505092915050565b600080600080606085870312156152c057600080fd5b84356152cb81614d14565b935060208501359250604085013567ffffffffffffffff8111156152ee57600080fd5b6152fa87828801615061565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b8281101561533f57815184529284019290840190600101615323565b5050508381038285015261535381866151d1565b9695505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b80831015614b7c57835163ffffffff1682529284019260019290920191908401906153e1565b60006020828403121561541957600080fd5b81356148e681614d14565b6000806020838503121561543757600080fd5b823567ffffffffffffffff8082111561544f57600080fd5b818501915085601f83011261546357600080fd5b81358181111561547257600080fd5b8660206101608302850101111561548857600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016145146040830184614ee0565b8151815260208083015161016083019161552c9084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015161554c60408401826bffffffffffffffffffffffff169052565b506060830151615574606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151615590608084018267ffffffffffffffff169052565b5060a08301516155a860a084018263ffffffff169052565b5060c08301516155c560c084018268ffffffffffffffffff169052565b5060e08301516155e260e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff81811683821601908082111561567557615675615628565b5092915050565b6bffffffffffffffffffffffff81811683821602808216919082811461562057615620615628565b6bffffffffffffffffffffffff81811683821601908082111561567557615675615628565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff861660208201526157036040820186614ee0565b60c06060820152600061571960c0830186614967565b828103608084015261572b8186614967565b905082810360a084015261573f8185614967565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361577d5761577d615628565b5060010190565b6bffffffffffffffffffffffff82811682821603908082111561567557615675615628565b600060ff821660ff81036157bf576157bf615628565b60010192915050565b818103818111156115d9576115d9615628565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff80831681810361582757615827615628565b6001019392505050565b808201808211156115d9576115d9615628565b60006020828403121561585657600080fd5b5051919050565b6000610160828403121561587057600080fd5b6148e68383614d5f565b60006020828403121561588c57600080fd5b815180151581146148e657600080fd5b67ffffffffffffffff81811683821601908082111561567557615675615628565b8381526060602082015260006158d66060830185614967565b82810360408401526153538185614967565b6020815260008251610160806020850152615907610180850183614967565b915060208501516040850152604085015161593a606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e08501516101006159b18187018363ffffffff169052565b86015190506101206159c88682018361ffff169052565b86015190506101406159e58682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b80516148c481614d14565b80516148c481614cef565b80516148c4816148a3565b80516148c4816148ed565b80516148c481614acd565b80516148c481614d41565b60006101608284031215615a6057600080fd5b615a68614a48565b82518152615a7860208401615a0b565b6020820152615a8960408401615a16565b6040820152615a9a60608401615a0b565b6060820152615aab60808401615a21565b6080820152615abc60a08401615a2c565b60a0820152615acd60c08401615a37565b60c0820152615ade60e08401615a37565b60e0820152610100615af1818501615a42565b90820152610120615b03848201615a42565b90820152610140615b15848201615a2c565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615b6160e0830187614967565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006145146040830184614967565b60008251615bd9818460208701614943565b919091019291505056fea164736f6c6343000813000a", } var FunctionsRouterABI = FunctionsRouterMetaData.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 0d7dc5a6217..9c10a5e77b8 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 @@ -3,11 +3,11 @@ functions: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.abi functions_allow_list: ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.bin b2697ad4dfece903a1d34028826a017fa445eb3cd984006f1734fa9d47836ca0 functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca -functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin 25036bdb94a50a81df4222418bf9aa1e0c8540d5834b7e6e639aa63a2a2c8206 -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin e453fd45029ff99658d029bfbb8711b748c432323f12585c039a30977e801a79 -functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin 1323b4ee0bcefd61a248177cf84d98015ae08e2b05223e06a1724112efdca8cd +functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin c018c964cfb524b254ad26f078336108076c890837dd8eadab46e06283f46b71 +functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin c8dbbd5ebb34435800d6674700068837c3a252db60046a14b0e61e829db517de functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c -functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin dd1d3527e19d65efe029c4a131ded44dc0ca961e5c4f459743992435431ec478 +functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin c7896ff5657bbfd5c48a61efec7e932ede3ad9a6a9e57195a46ba02ade31ccee functions_v1_events_mock: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.bin 0f0ba42e0cc33c7abc8b8fd4fdfce903748a169886dd5f16cfdd56e75bcf708d ocr2dr: ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.bin d9a794b33f47cc57563d216f7cf3a612309fc3062356a27e30005cf1d59e449d ocr2dr_client: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.bin 84aa63f9dbc5c7eac240db699b09e613ca4c6cd56dab10bdc25b02461b717e21 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 bedfdc92d19..ec655980abf 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 @@ -214,7 +214,6 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, // Deploy Coordinator contract (matches updateConfig() in FunctionsBilling.sol) coordinatorConfig := functions_coordinator.FunctionsBillingConfig{ - MaxCallbackGasLimit: uint32(450_000), FeedStalenessSeconds: uint32(86_400), GasOverheadBeforeCallback: uint32(325_000), GasOverheadAfterCallback: uint32(50_000), From 7d44d7bb30b558a6a1e15a4f4c4e555e73ef4169 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Thu, 7 Sep 2023 23:35:37 -0400 Subject: [PATCH 61/88] [Functions] Minor contract fixes (#10511) * (fix): Functions Subscriptions add consumer checks if sub consumers greater or equal to max to account for changes to the maximum * (fix): Functions Router during fulfillment do not revert on invalid client * Functions Coordinator oracleWithdrawAll checks for 0 balances * (test): Add unit tests for changes * Update gas snapshot * Changes after rebase --- .../gas-snapshots/functions.gas-snapshot | 32 +++-- .../functions/dev/1_0_0/FunctionsBilling.sol | 6 +- .../functions/dev/1_0_0/FunctionsRouter.sol | 19 ++- .../dev/1_0_0/FunctionsSubscriptions.sol | 2 +- .../tests/1_0_0/FunctionsCoordinator.t.sol | 43 +++++- .../tests/1_0_0/FunctionsRouter.t.sol | 47 +++++++ .../tests/1_0_0/FunctionsSubscriptions.t.sol | 18 +++ .../v0.8/functions/tests/1_0_0/Setup.t.sol | 131 ++++++++++++++++++ .../functions_coordinator.go | 2 +- .../functions_router/functions_router.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 4 +- 11 files changed, 276 insertions(+), 30 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index ad4b158a7ff..9a1ebe16603 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,5 +1,7 @@ FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32391) FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 52979) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13274) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 147058) FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13452) FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974) FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255) @@ -11,16 +13,17 @@ FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35791) FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987) FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12073) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 48299) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 38830) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 36239) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 48277) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 38808) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 36217) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35161) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 165) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28037) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 210) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28015) FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 33206) -FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 103393) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 1762917) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 205990) +FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 93612) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 103408) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 1762929) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 206005) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17842) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12883) FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 31332) @@ -44,7 +47,7 @@ FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 192424) FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29382) FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57929) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186036) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186033) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 48353) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25038) FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29088) @@ -58,7 +61,7 @@ FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalid FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35718) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40788) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 204484) -FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192600) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192597) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30666) FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13402) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13294) @@ -72,12 +75,13 @@ FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOw FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94703) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62713) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 59611) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137842) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12914) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137833) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 161337) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12926) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57789) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87166) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18006) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95394) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18051) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95391) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15041) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57863) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89296) diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol index 5ae302da86f..b0d83c5e061 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol @@ -347,8 +347,10 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // Bounded by "maxNumOracles" on OCR2Abstract.sol for (uint256 i = 0; i < transmitters.length; ++i) { uint96 balance = s_withdrawableTokens[transmitters[i]]; - s_withdrawableTokens[transmitters[i]] = 0; - IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(transmitters[i], balance); + if (balance > 0) { + s_withdrawableTokens[transmitters[i]] = 0; + IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(transmitters[i], balance); + } } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol index 4ec25985802..abc3921fb0c 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol @@ -389,6 +389,18 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, uint32 callbackGasLimit, address client ) private returns (CallbackResult memory) { + bool destinationNoLongerExists; + // solhint-disable-next-line no-inline-assembly + assembly { + // solidity calls check that a contract actually exists at the destination, so we do the same + destinationNoLongerExists := iszero(extcodesize(client)) + } + if (destinationNoLongerExists) { + // Return without attempting callback + // The subscription will still be charged to reimburse transmitter's gas overhead + return CallbackResult({success: false, gasUsed: 0, returnData: new bytes(0)}); + } + bytes memory encodedCallback = abi.encodeWithSelector( s_config.handleOracleFulfillmentSelector, requestId, @@ -410,13 +422,6 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // solhint-disable-next-line no-inline-assembly assembly { - // solidity calls check that a contract actually exists at the destination, so we do the same - // Note we do this check prior to measuring gas so gasForCallExactCheck (our "cushion") - // doesn't need to account for it. - if iszero(extcodesize(client)) { - revert(0, 0) - } - let g := gas() // Compute g -= gasForCallExactCheck and check for underflow // The gas actually passed to the callee is _min(gasAmount, 63//64*gas available). diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol index cabe8b0d284..dbcf97081bb 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol @@ -395,7 +395,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // Already maxed, cannot add any more consumers. uint16 maximumConsumers = _getMaxConsumers(); - if (s_subscriptions[subscriptionId].consumers.length == maximumConsumers) { + if (s_subscriptions[subscriptionId].consumers.length >= maximumConsumers) { revert TooManyConsumers(maximumConsumers); } if (s_consumers[consumer][subscriptionId].allowed) { diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol index 8ab936e5033..cf3a86cce41 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol @@ -5,7 +5,7 @@ import {FunctionsCoordinator} from "../../dev/1_0_0/FunctionsCoordinator.sol"; import {FunctionsBilling} from "../../dev/1_0_0/FunctionsBilling.sol"; import {FunctionsRequest} from "../../dev/1_0_0/libraries/FunctionsRequest.sol"; -import {FunctionsSubscriptionSetup} from "./Setup.t.sol"; +import {FunctionsSubscriptionSetup, FunctionsMultipleFulfillmentsSetup} from "./Setup.t.sol"; // ================================================================ // | Functions Coordinator | @@ -209,8 +209,47 @@ contract FunctionsBilling_OracleWithdraw { } /// @notice #oracleWithdrawAll -contract FunctionsBilling_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(); + } + function test_OracleWithdrawAll_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsCoordinator.oracleWithdrawAll(); + } + + function test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() public { + uint256 transmitter1BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1); + assertEq(transmitter1BalanceBefore, 0); + uint256 transmitter2BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_2); + assertEq(transmitter2BalanceBefore, 0); + uint256 transmitter3BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_3); + assertEq(transmitter3BalanceBefore, 0); + uint256 transmitter4BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_4); + assertEq(transmitter4BalanceBefore, 0); + + s_functionsCoordinator.oracleWithdrawAll(); + + uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / 3; + + uint256 transmitter1BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1); + assertEq(transmitter1BalanceAfter, expectedTransmitterBalance); + uint256 transmitter2BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_2); + assertEq(transmitter2BalanceAfter, expectedTransmitterBalance); + uint256 transmitter3BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_3); + assertEq(transmitter3BalanceAfter, expectedTransmitterBalance); + // Transmitter 4 has no balance + uint256 transmitter4BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_4); + assertEq(transmitter4BalanceAfter, 0); + } } /// @notice #_getTransmitters diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol index c6295943df1..9b9637e2711 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol @@ -1191,6 +1191,53 @@ contract FunctionsRouter_Fulfill is FunctionsClientRequestSetup { assertEq(callbackGasCostJuels, 0); } + function test_Fulfill_SuccessClientNoLongerExists() public { + // Delete the Client contract in the time between request and fulfillment + vm.etch(address(s_functionsClient), new bytes(0)); + + // Send as committed Coordinator + vm.stopPrank(); + vm.startPrank(address(s_functionsCoordinator)); + + bytes memory response = bytes("hello world!"); + bytes memory err = new bytes(0); + uint96 juelsPerGas = 0; + uint96 costWithoutCallback = 0; + address transmitter = NOP_TRANSMITTER_ADDRESS_1; + FunctionsResponse.Commitment memory commitment = s_requestCommitment; + + // topic0 (function signature, always checked), topic1 (true), topic2 (true), NOT topic3 (false), and data (true). + bool checkTopic1RequestId = true; + bool checkTopic2SubscriptionId = true; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1RequestId, checkTopic2SubscriptionId, checkTopic3, checkData); + emit RequestProcessed({ + requestId: s_requestId, + subscriptionId: s_subscriptionId, + totalCostJuels: s_adminFee + costWithoutCallback, // NOTE: tx.gasprice is at 0, so no callback gas used + transmitter: transmitter, + resultCode: FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR, + response: response, + err: err, + callbackReturnData: new bytes(0) + }); + + vm.recordLogs(); + + (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill( + response, + err, + juelsPerGas, + costWithoutCallback, + transmitter, + commitment + ); + + assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR)); + assertEq(callbackGasCostJuels, 0); + } + function test_Fulfill_SuccessFulfilled() public { // Send as committed Coordinator vm.stopPrank(); diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol index 2fb0d4219cc..4f6cb600d2b 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol @@ -807,6 +807,24 @@ contract FunctionsSubscriptions_AddConsumer is FunctionsSubscriptionSetup { s_functionsRouter.addConsumer(s_subscriptionId, address(3)); } + function test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() public { + // Fill Consumers to s_maxConsumersPerSubscription + // Already has one from setup + s_functionsRouter.addConsumer(s_subscriptionId, address(1)); + s_functionsRouter.addConsumer(s_subscriptionId, address(2)); + + // Lower maxConsumersPerSubscription + s_maxConsumersPerSubscription = 1; + FunctionsRouter.Config memory newRouterConfig = getRouterConfig(); + s_functionsRouter.updateConfig(newRouterConfig); + + // .AddConsumer should still revert + vm.expectRevert( + abi.encodeWithSelector(FunctionsSubscriptions.TooManyConsumers.selector, s_maxConsumersPerSubscription) + ); + s_functionsRouter.addConsumer(s_subscriptionId, address(3)); + } + event SubscriptionConsumerAdded(uint64 indexed subscriptionId, address consumer); function test_AddConsumer_Success() public { diff --git a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol index 638e369b90b..e6e7df15f50 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol @@ -264,3 +264,134 @@ contract FunctionsFulfillmentSetup is FunctionsClientRequestSetup { vm.startPrank(OWNER_ADDRESS); } } + +contract FunctionsMultipleFulfillmentsSetup is FunctionsFulfillmentSetup { + bytes32 s_requestId2; + FunctionsResponse.Commitment s_requestCommitment2; + bytes32 s_requestId3; + FunctionsResponse.Commitment s_requestCommitment3; + + function setUp() public virtual override { + FunctionsFulfillmentSetup.setUp(); + + // Make 2 additional requests (1 already complete) + + // *** Request #2 *** + vm.recordLogs(); + s_requestId2 = s_functionsClient.sendRequest( + s_donId, + "return 'hello world';", + new bytes(0), + new string[](0), + new bytes[](0), + s_subscriptionId, + 5500 + ); + + // Get commitment data from OracleRequest event log + Vm.Log[] memory entriesAfterRequest2 = vm.getRecordedLogs(); + (, , , , , , , FunctionsResponse.Commitment memory commitment2) = abi.decode( + entriesAfterRequest2[0].data, + (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment) + ); + s_requestCommitment2 = commitment2; + + // Transmit as transmitter 2 + vm.stopPrank(); + vm.startPrank(NOP_TRANSMITTER_ADDRESS_2); + + // Build report + bytes32[] memory requestIds2 = new bytes32[](1); + requestIds2[0] = s_requestId2; + bytes[] memory results2 = new bytes[](1); + results2[0] = bytes("hello world!"); + bytes[] memory errors2 = new bytes[](1); + // No error + bytes[] memory onchainMetadata2 = new bytes[](1); + onchainMetadata2[0] = abi.encode(s_requestCommitment2); + bytes[] memory offchainMetadata2 = new bytes[](1); + // No offchain metadata + bytes memory report2 = abi.encode(requestIds2, results2, errors2, onchainMetadata2, offchainMetadata2); + + // Build signers + address[31] memory signers2; + signers2[0] = NOP_SIGNER_ADDRESS_2; + + // Send report + vm.recordLogs(); + s_functionsCoordinator.callReportWithSigners(report2, signers2); + + // Get actual cost from RequestProcessed event log + Vm.Log[] memory entriesAfterFulfill2 = vm.getRecordedLogs(); + (uint96 totalCostJuels2, , , , , ) = abi.decode( + entriesAfterFulfill2[2].data, + (uint96, address, FunctionsResponse.FulfillResult, bytes, bytes, bytes) + ); + // totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels + s_fulfillmentCoordinatorBalance += totalCostJuels2 - s_adminFee; + s_fulfillmentRouterOwnerBalance += s_adminFee; + + // Return prank to Owner + vm.stopPrank(); + vm.startPrank(OWNER_ADDRESS); + + // *** Request #3 *** + vm.recordLogs(); + s_requestId3 = s_functionsClient.sendRequest( + s_donId, + "return 'hello world';", + new bytes(0), + new string[](0), + new bytes[](0), + s_subscriptionId, + 5500 + ); + + // Get commitment data from OracleRequest event log + Vm.Log[] memory entriesAfterRequest3 = vm.getRecordedLogs(); + (, , , , , , , FunctionsResponse.Commitment memory commitment3) = abi.decode( + entriesAfterRequest3[0].data, + (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment) + ); + s_requestCommitment3 = commitment3; + + // Transmit as transmitter 3 + vm.stopPrank(); + vm.startPrank(NOP_TRANSMITTER_ADDRESS_3); + + // Build report + bytes32[] memory requestIds3 = new bytes32[](1); + requestIds3[0] = s_requestId3; + bytes[] memory results3 = new bytes[](1); + results3[0] = bytes("hello world!"); + bytes[] memory errors3 = new bytes[](1); + // No error + bytes[] memory onchainMetadata3 = new bytes[](1); + onchainMetadata3[0] = abi.encode(s_requestCommitment3); + bytes[] memory offchainMetadata3 = new bytes[](1); + // No offchain metadata + bytes memory report3 = abi.encode(requestIds3, results3, errors3, onchainMetadata3, offchainMetadata3); + + // Build signers + address[31] memory signers3; + signers3[0] = NOP_SIGNER_ADDRESS_3; + + // Send report + vm.recordLogs(); + s_functionsCoordinator.callReportWithSigners(report3, signers3); + + // Get actual cost from RequestProcessed event log + Vm.Log[] memory entriesAfterFulfill3 = vm.getRecordedLogs(); + (uint96 totalCostJuels3, , , , , ) = abi.decode( + entriesAfterFulfill3[2].data, + (uint96, address, FunctionsResponse.FulfillResult, bytes, bytes, bytes) + ); + + // totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels + s_fulfillmentCoordinatorBalance += totalCostJuels3 - s_adminFee; + + // Return prank to Owner + vm.stopPrank(); + vm.startPrank(OWNER_ADDRESS); + } +} diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index a66c6bc3685..fad5be26a06 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -71,7 +71,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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":[],\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"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\":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\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b506040516200514638038062005146833981016040819052620000349162000418565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b505050505050620005c6565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033b565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160e81b0261ffff60e81b196001600160481b03909216600160a01b02600160a01b600160e81b031963ffffffff948516600160801b0216600160801b600160e81b03199585166c010000000000000000000000000263ffffffff60601b19978616680100000000000000000297909716600160401b600160801b0319998616640100000000026001600160401b0319909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980546001600160e01b039092166001600160e01b0319909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a906200033090839062000536565b60405180910390a150565b6200034562000347565b565b6000546001600160a01b03163314620003455760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003bb57600080fd5b919050565b805163ffffffff81168114620003bb57600080fd5b80516001600160481b0381168114620003bb57600080fd5b805161ffff81168114620003bb57600080fd5b80516001600160e01b0381168114620003bb57600080fd5b60008060008385036101408112156200043057600080fd5b6200043b85620003a3565b935061010080601f19830112156200045257600080fd5b60405191508082016001600160401b03811183821017156200048457634e487b7160e01b600052604160045260246000fd5b6040526200049560208701620003c0565b8252620004a560408701620003c0565b6020830152620004b860608701620003c0565b6040830152620004cb60808701620003c0565b6060830152620004de60a08701620003c0565b6080830152620004f160c08701620003d5565b60a08301526200050460e08701620003ed565b60c08301526200051681870162000400565b60e08301525091506200052d6101208501620003a3565b90509250925092565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525060018060481b0360a08401511660a083015260c0830151620005a360c084018261ffff169052565b5060e0830151620005bf60e08401826001600160e01b03169052565b5092915050565b60805160a051614b3062000616600039600081816105ce0152818161075c01528181610a4501528181610cdb0152818161104e015281816118380152613287015260006112760152614b306000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806385b214cf116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610539578063e4ddcea61461054c578063f2fde38b1461056257600080fd5b8063c3f909d4146103c4578063d227d24514610501578063d328a91e1461053157600080fd5b8063a631571e116100bd578063a631571e14610371578063afcb95d714610391578063b1dc65a4146103b157600080fd5b806385b214cf146103135780638da5cb5b146103365780639314176d1461035e57600080fd5b806379ba509711610145578063814118341161011f578063814118341461028957806381f1b9381461029e57806381ff7048146102a657600080fd5b806379ba5097146102665780637d4807871461026e5780637f15e1661461027657600080fd5b80632a905ccc116101765780632a905ccc146101f957806359b5b7ac1461021b57806366316d8d1461025357600080fd5b8063083a546614610192578063181f5a77146101a7575b600080fd5b6101a56101a036600461357a565b610575565b005b6101e36040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f09190613620565b60405180910390f35b6102016105ca565b60405168ffffffffffffffffff90911681526020016101f0565b610201610229366004613770565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101a56102613660046137ff565b610660565b6101a5610819565b6101a561091b565b6101a561028436600461357a565b610b31565b610291610b81565b6040516101f09190613889565b6101e3610bf0565b6102f060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f0565b61032661032136600461389c565b610cc1565b60405190151581526020016101f0565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6101a561036c366004613932565b610da1565b61038461037f3660046139fc565b610fdd565b6040516101f09190613b51565b6040805160018152600060208201819052918101919091526060016101f0565b6101a56103bf366004613ba5565b61117d565b6104f46040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915250604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08201527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e082015290565b6040516101f09190613c5c565b61051461050f366004613d1c565b611834565b6040516bffffffffffffffffffffffff90911681526020016101f0565b6101e3611996565b6101a5610547366004613e35565b6119ed565b610554612419565b6040519081526020016101f0565b6101a5610570366004613f02565b61263e565b61057d612652565b60008190036105b8576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105c5828483613fb8565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065b91906140de565b905090565b6106686126d5565b806bffffffffffffffffffffffff166000036106a25750336000908152600a60205260409020546bffffffffffffffffffffffff166106fc565b336000908152600a60205260409020546bffffffffffffffffffffffff808316911610156106fc576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906107299084906bffffffffffffffffffffffff1661412a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061077e7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b1580156107fd57600080fd5b505af1158015610811573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461089f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610923612880565b61092b6126d5565b6000610935610b81565b905060005b8151811015610b2d576000600a600084848151811061095b5761095b61414f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff1690506000600a60008585815181106109d0576109d061414f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610a677f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610a9457610a9461414f565b6020026020010151836040518363ffffffff1660e01b8152600401610ae992919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610b0357600080fd5b505af1158015610b17573d6000803e3d6000fd5b505050505080610b269061417e565b905061093a565b5050565b610b39612652565b6000819003610b74576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105c5828483613fb8565b60606006805480602002602001604051908101604052809291908181526020018280548015610be657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610bbb575b5050505050905090565b6060600d8054610bff90613f1f565b9050600003610c3a576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610c4790613f1f565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7390613f1f565b8015610be65780601f10610c9557610100808354040283529160200191610be6565b820191906000526020600020905b815481529060010190602001808311610ca357509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d32576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260076020526040902054610d4d57506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610d909084815260200190565b60405180910390a15060015b919050565b610da9612880565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167d010000000000000000000000000000000000000000000000000000000000027fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90921674010000000000000000000000000000000000000000027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff63ffffffff94851670010000000000000000000000000000000002167fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff9585166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9786166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a90610fd2908390613c5c565b60405180910390a150565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146110a5576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110b66110b1836141b6565b612888565b90506110c86060830160408401613f02565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261111660c0870160a088016142a3565b61112861016088016101408901613f02565b61113288806142c0565b6111446101208b016101008c01614325565b60208b013561115a6101008d0160e08e01614340565b8b6040516111709998979695949392919061435d565b60405180910390a3919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610896565b6112728b8b8b8b8b8b612c89565b60007f0000000000000000000000000000000000000000000000000000000000000000156112cf576002826020015183604001516112b09190614405565b6112ba919061444d565b6112c5906001614405565b60ff1690506112e5565b60208201516112df906001614405565b60ff1690505b88811461134e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610896565b8887146113b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610896565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113fa576113fa61446f565b600281111561140b5761140b61446f565b90525090506002816020015160028111156114285761142861446f565b14801561146f57506006816000015160ff168154811061144a5761144a61414f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6114d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610896565b50505050506114e2613512565b6000808a8a6040516114f592919061449e565b60405190819003812061150c918e906020016144ae565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156118165760006001848984602081106115755761157561414f565b61158291901a601b614405565b8e8e868181106115945761159461414f565b905060200201358d8d878181106115ad576115ad61414f565b90506020020135604051600081526020016040526040516115ea949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561160c573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561168c5761168c61446f565b600281111561169d5761169d61446f565b90525092506001836020015160028111156116ba576116ba61446f565b14611721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610896565b8251600090879060ff16601f811061173b5761173b61414f565b602002015173ffffffffffffffffffffffffffffffffffffffff16146117bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610896565b8086846000015160ff16601f81106117d7576117d761414f565b73ffffffffffffffffffffffffffffffffffffffff9092166020929092020152611802600186614405565b9450508061180f9061417e565b9050611556565b505050611827833383858e8e612d40565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b1580156118d457600080fd5b505afa1580156118e8573d6000803e3d6000fd5b5050505066038d7ea4c6800082111561192d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006119376105ca565b9050600061197a87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061022992505050565b905061198885858385612f0e565b925050505b95945050505050565b6060600c80546119a590613f1f565b90506000036119e0576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610c4790613f1f565b855185518560ff16601f831115611a60576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610896565b80600003611aca576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610896565b818314611b58576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610896565b611b638160036144c2565b8311611bcb576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610896565b611bd3612652565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611c1a9088612ff8565b60055415611dcf57600554600090611c34906001906144d9565b9050600060058281548110611c4b57611c4b61414f565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611c8557611c8561414f565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611d0557611d056144ec565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611d6e57611d6e6144ec565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611c1a915050565b60005b8151518110156122365760006004600084600001518481518110611df857611df861414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611e4257611e4261446f565b14611ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610896565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611eda57611eda61414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115611f7b57611f7b61446f565b021790555060009150611f8b9050565b6004600084602001518481518110611fa557611fa561414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611fef57611fef61446f565b14612056576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610896565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106120895761208961414f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561212a5761212a61446f565b0217905550508251805160059250839081106121485761214861414f565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106121c4576121c461414f565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061222e8161417e565b915050611dd2565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff43811682029290921780855592048116929182916014916122ee9184917401000000000000000000000000000000000000000090041661451b565b92506101000a81548163ffffffff021916908363ffffffff16021790555061234d4630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613011565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612404988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614538565b60405180910390a15050505050505050505050565b604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c01000000000000000000000000808304821660608501527001000000000000000000000000000000008304909116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a0808501919091527d01000000000000000000000000000000000000000000000000000000000090920461ffff1660c08401526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa158015612573573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259791906145e8565b5093505092505080426125aa91906144d9565b836020015163ffffffff161080156125cc57506000836020015163ffffffff16115b156125fa57505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b60008213612637576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610896565b5092915050565b612646612652565b61264f816130bc565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146126d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610896565b565b600b546bffffffffffffffffffffffff166000036126ef57565b60006126f9610b81565b90508051600003612736576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b54600091612755916bffffffffffffffffffffffff16614638565b905060005b82518110156128215781600a600085848151811061277a5761277a61414f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166127e29190614663565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508061281a9061417e565b905061275a565b50815161282e9082614688565b600b805460009061284e9084906bffffffffffffffffffffffff1661412a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6126d3612652565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260408051610100808201835260085463ffffffff80821684526401000000008204811660208501526801000000000000000082048116948401949094526c010000000000000000000000008104841660608401527001000000000000000000000000000000008104909316608083015274010000000000000000000000000000000000000000830468ffffffffffffffffff1660a08301527d01000000000000000000000000000000000000000000000000000000000090920461ffff90811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e084015292850151919291161115612a0e576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff1690506000612a4f8560e001513a848860800151612f0e565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612aab576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b2e3087604001518860a001518960c001516001612acc91906146b8565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff1642612c2091906146d9565b63ffffffff16815250945084604051602001612c3c9190613b51565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b6000612c968260206144c2565b612ca18560206144c2565b612cad886101446146d9565b612cb791906146d9565b612cc191906146d9565b612ccc9060006146d9565b9050368114612d37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610896565b50505050505050565b606080808080612d52868801886147c7565b8451949950929750909550935091501580612d6f57508351855114155b80612d7c57508251855114155b80612d8957508151855114155b80612d9657508051855114155b15612dcd576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612f00576000612e65878381518110612df057612df061414f565b6020026020010151878481518110612e0a57612e0a61414f565b6020026020010151878581518110612e2457612e2461414f565b6020026020010151878681518110612e3e57612e3e61414f565b6020026020010151878781518110612e5857612e5861414f565b60200260200101516131b1565b90506000816006811115612e7b57612e7b61446f565b1480612e9857506001816006811115612e9657612e9661446f565b145b15612eef57868281518110612eaf57612eaf61414f565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612ef98161417e565b9050612dd0565b505050505050505050505050565b60085460009081908690612f469063ffffffff6c0100000000000000000000000082048116916801000000000000000090041661451b565b612f50919061451b565b60085463ffffffff918216925060009161271091612f6f9116886144c2565b612f799190614899565b612f8390876146d9565b90506000612f9082613441565b90506000612fac846bffffffffffffffffffffffff84166144c2565b90506000612fc868ffffffffffffffffff808916908a16614663565b9050612fea612fe56bffffffffffffffffffffffff8316846146d9565b613470565b9a9950505050505050505050565b6000613002610b81565b511115610b2d57610b2d6126d5565b6000808a8a8a8a8a8a8a8a8a604051602001613035999897969594939291906148ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361313b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610896565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906131c89190614983565b9050806040516020016131db9190613b51565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a815260079093529120541461322d57600691505061198d565b60008781526007602052604090205461324a57600291505061198d565b60006132553a613441565b9050600082610120015183610100015161326f9190614a56565b6132809064ffffffffff1683614688565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff16886132df9190614663565b338b6040518763ffffffff1660e01b815260040161330296959493929190614a74565b60408051808303816000875af1158015613320573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133449190614af0565b9092509050600082600681111561335d5761335d61446f565b148061337a575060018260068111156133785761337861446f565b145b156134335760008b8152600760205260408120556133988184614663565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff9092169390929161340491859116614663565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b600061346a61344e612419565b61346084670de0b6b3a76400006144c2565b612fe59190614899565b92915050565b60006bffffffffffffffffffffffff82111561350e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610896565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f84011261354357600080fd5b50813567ffffffffffffffff81111561355b57600080fd5b60208301915083602082850101111561357357600080fd5b9250929050565b6000806020838503121561358d57600080fd5b823567ffffffffffffffff8111156135a457600080fd5b6135b085828601613531565b90969095509350505050565b6000815180845260005b818110156135e2576020818501810151868301820152016135c6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061363360208301846135bc565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff8111828210171561368d5761368d61363a565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136da576136da61363a565b604052919050565b600082601f8301126136f357600080fd5b813567ffffffffffffffff81111561370d5761370d61363a565b61373e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613693565b81815284602083860101111561375357600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561378257600080fd5b813567ffffffffffffffff81111561379957600080fd5b6137a5848285016136e2565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461264f57600080fd5b8035610d9c816137ad565b6bffffffffffffffffffffffff8116811461264f57600080fd5b8035610d9c816137da565b6000806040838503121561381257600080fd5b823561381d816137ad565b9150602083013561382d816137da565b809150509250929050565b600081518084526020808501945080840160005b8381101561387e57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161384c565b509495945050505050565b6020815260006136336020830184613838565b6000602082840312156138ae57600080fd5b5035919050565b63ffffffff8116811461264f57600080fd5b8035610d9c816138b5565b68ffffffffffffffffff8116811461264f57600080fd5b8035610d9c816138d2565b803561ffff81168114610d9c57600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114610d9c57600080fd5b600061010080838503121561394657600080fd5b6040519081019067ffffffffffffffff821181831017156139695761396961363a565b816040528335915061397a826138b5565b818152613989602085016138c7565b602082015261399a604085016138c7565b60408201526139ab606085016138c7565b60608201526139bc608085016138c7565b60808201526139cd60a085016138e9565b60a08201526139de60c085016138f4565b60c08201526139ef60e08501613906565b60e0820152949350505050565b600060208284031215613a0e57600080fd5b813567ffffffffffffffff811115613a2557600080fd5b8201610160818503121561363357600080fd5b805182526020810151613a63602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613a8360408401826bffffffffffffffffffffffff169052565b506060810151613aab606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613ac7608084018267ffffffffffffffff169052565b5060a0810151613adf60a084018263ffffffff169052565b5060c0810151613afc60c084018268ffffffffffffffffff169052565b5060e0810151613b1960e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161346a8284613a38565b60008083601f840112613b7257600080fd5b50813567ffffffffffffffff811115613b8a57600080fd5b6020830191508360208260051b850101111561357357600080fd5b60008060008060008060008060e0898b031215613bc157600080fd5b606089018a811115613bd257600080fd5b8998503567ffffffffffffffff80821115613bec57600080fd5b613bf88c838d01613531565b909950975060808b0135915080821115613c1157600080fd5b613c1d8c838d01613b60565b909750955060a08b0135915080821115613c3657600080fd5b50613c438b828c01613b60565b999c989b50969995989497949560c00135949350505050565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525068ffffffffffffffffff60a08401511660a083015260c0830151613ccb60c084018261ffff169052565b5060e083015161263760e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b67ffffffffffffffff8116811461264f57600080fd5b8035610d9c81613cfb565b600080600080600060808688031215613d3457600080fd5b8535613d3f81613cfb565b9450602086013567ffffffffffffffff811115613d5b57600080fd5b613d6788828901613531565b9095509350506040860135613d7b816138b5565b949793965091946060013592915050565b600067ffffffffffffffff821115613da657613da661363a565b5060051b60200190565b600082601f830112613dc157600080fd5b81356020613dd6613dd183613d8c565b613693565b82815260059290921b84018101918181019086841115613df557600080fd5b8286015b84811015613e19578035613e0c816137ad565b8352918301918301613df9565b509695505050505050565b803560ff81168114610d9c57600080fd5b60008060008060008060c08789031215613e4e57600080fd5b863567ffffffffffffffff80821115613e6657600080fd5b613e728a838b01613db0565b97506020890135915080821115613e8857600080fd5b613e948a838b01613db0565b9650613ea260408a01613e24565b95506060890135915080821115613eb857600080fd5b613ec48a838b016136e2565b9450613ed260808a01613d11565b935060a0890135915080821115613ee857600080fd5b50613ef589828a016136e2565b9150509295509295509295565b600060208284031215613f1457600080fd5b8135613633816137ad565b600181811c90821680613f3357607f821691505b602082108103613f6c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105c557600081815260208120601f850160051c81016020861015613f995750805b601f850160051c820191505b8181101561081157828155600101613fa5565b67ffffffffffffffff831115613fd057613fd061363a565b613fe483613fde8354613f1f565b83613f72565b6000601f84116001811461403657600085156140005750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556140cc565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140855786850135825560209485019460019092019101614065565b50868210156140c0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8051610d9c816138d2565b6000602082840312156140f057600080fd5b8151613633816138d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff828116828216039080821115612637576126376140fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141af576141af6140fb565b5060010190565b600061016082360312156141c957600080fd5b6141d1613669565b823567ffffffffffffffff8111156141e857600080fd5b6141f4368286016136e2565b8252506020830135602082015261420d604084016137cf565b604082015261421e606084016137f4565b606082015261422f608084016138e9565b608082015261424060a08401613d11565b60a082015261425160c08401613d11565b60c082015261426260e084016138c7565b60e08201526101006142758185016138f4565b90820152610120614287848201613d11565b908201526101406142998482016137cf565b9082015292915050565b6000602082840312156142b557600080fd5b813561363381613cfb565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142f557600080fd5b83018035915067ffffffffffffffff82111561431057600080fd5b60200191503681900382131561357357600080fd5b60006020828403121561433757600080fd5b613633826138f4565b60006020828403121561435257600080fd5b8135613633816138b5565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301019050612fea60e0830184613a38565b60ff818116838216019081111561346a5761346a6140fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806144605761446061441e565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761346a5761346a6140fb565b8181038181111561346a5761346a6140fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff818116838216019080821115612637576126376140fb565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526145688184018a613838565b9050828103608084015261457c8189613838565b905060ff871660a084015282810360c084015261459981876135bc565b905067ffffffffffffffff851660e08401528281036101008401526145be81856135bc565b9c9b505050505050505050505050565b805169ffffffffffffffffffff81168114610d9c57600080fd5b600080600080600060a0868803121561460057600080fd5b614609866145ce565b945060208601519350604086015192506060860151915061462c608087016145ce565b90509295509295909350565b60006bffffffffffffffffffffffff808416806146575761465761441e565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115612637576126376140fb565b6bffffffffffffffffffffffff8181168382160280821691908281146146b0576146b06140fb565b505092915050565b67ffffffffffffffff818116838216019080821115612637576126376140fb565b8082018082111561346a5761346a6140fb565b600082601f8301126146fd57600080fd5b8135602061470d613dd183613d8c565b82815260059290921b8401810191818101908684111561472c57600080fd5b8286015b84811015613e195780358352918301918301614730565b600082601f83011261475857600080fd5b81356020614768613dd183613d8c565b82815260059290921b8401810191818101908684111561478757600080fd5b8286015b84811015613e1957803567ffffffffffffffff8111156147ab5760008081fd5b6147b98986838b01016136e2565b84525091830191830161478b565b600080600080600060a086880312156147df57600080fd5b853567ffffffffffffffff808211156147f757600080fd5b61480389838a016146ec565b9650602088013591508082111561481957600080fd5b61482589838a01614747565b9550604088013591508082111561483b57600080fd5b61484789838a01614747565b9450606088013591508082111561485d57600080fd5b61486989838a01614747565b9350608088013591508082111561487f57600080fd5b5061488c88828901614747565b9150509295509295909350565b6000826148a8576148a861441e565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526148f48285018b613838565b91508382036080850152614908828a613838565b915060ff881660a085015283820360c085015261492582886135bc565b90861660e085015283810361010085015290506145be81856135bc565b8051610d9c816137ad565b8051610d9c816137da565b8051610d9c81613cfb565b8051610d9c816138b5565b805164ffffffffff81168114610d9c57600080fd5b6000610160828403121561499657600080fd5b61499e613669565b825181526149ae60208401614942565b60208201526149bf6040840161494d565b60408201526149d060608401614942565b60608201526149e160808401614958565b60808201526149f260a08401614963565b60a0820152614a0360c084016140d3565b60c0820152614a1460e084016140d3565b60e0820152610100614a2781850161496e565b90820152610120614a3984820161496e565b90820152610140614a4b848201614963565b908201529392505050565b64ffffffffff818116838216019080821115612637576126376140fb565b6000610200808352614a888184018a6135bc565b90508281036020840152614a9c81896135bc565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614ae5905060a0830184613a38565b979650505050505050565b60008060408385031215614b0357600080fd5b825160078110614b1257600080fd5b602084015190925061382d816137da56fea164736f6c6343000813000a", + Bin: "0x60c06040523480156200001157600080fd5b506040516200513038038062005130833981016040819052620000349162000418565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b505050505050620005c6565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033b565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160e81b0261ffff60e81b196001600160481b03909216600160a01b02600160a01b600160e81b031963ffffffff948516600160801b0216600160801b600160e81b03199585166c010000000000000000000000000263ffffffff60601b19978616680100000000000000000297909716600160401b600160801b0319998616640100000000026001600160401b0319909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980546001600160e01b039092166001600160e01b0319909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a906200033090839062000536565b60405180910390a150565b6200034562000347565b565b6000546001600160a01b03163314620003455760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003bb57600080fd5b919050565b805163ffffffff81168114620003bb57600080fd5b80516001600160481b0381168114620003bb57600080fd5b805161ffff81168114620003bb57600080fd5b80516001600160e01b0381168114620003bb57600080fd5b60008060008385036101408112156200043057600080fd5b6200043b85620003a3565b935061010080601f19830112156200045257600080fd5b60405191508082016001600160401b03811183821017156200048457634e487b7160e01b600052604160045260246000fd5b6040526200049560208701620003c0565b8252620004a560408701620003c0565b6020830152620004b860608701620003c0565b6040830152620004cb60808701620003c0565b6060830152620004de60a08701620003c0565b6080830152620004f160c08701620003d5565b60a08301526200050460e08701620003ed565b60c08301526200051681870162000400565b60e08301525091506200052d6101208501620003a3565b90509250925092565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525060018060481b0360a08401511660a083015260c0830151620005a360c084018261ffff169052565b5060e0830151620005bf60e08401826001600160e01b03169052565b5092915050565b60805160a051614b1a62000616600039600081816105ce0152818161075c01528181610a2f01528181610cc501528181611038015281816118220152613271015260006112600152614b1a6000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806385b214cf116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610539578063e4ddcea61461054c578063f2fde38b1461056257600080fd5b8063c3f909d4146103c4578063d227d24514610501578063d328a91e1461053157600080fd5b8063a631571e116100bd578063a631571e14610371578063afcb95d714610391578063b1dc65a4146103b157600080fd5b806385b214cf146103135780638da5cb5b146103365780639314176d1461035e57600080fd5b806379ba509711610145578063814118341161011f578063814118341461028957806381f1b9381461029e57806381ff7048146102a657600080fd5b806379ba5097146102665780637d4807871461026e5780637f15e1661461027657600080fd5b80632a905ccc116101765780632a905ccc146101f957806359b5b7ac1461021b57806366316d8d1461025357600080fd5b8063083a546614610192578063181f5a77146101a7575b600080fd5b6101a56101a0366004613564565b610575565b005b6101e36040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f0919061360a565b60405180910390f35b6102016105ca565b60405168ffffffffffffffffff90911681526020016101f0565b61020161022936600461375a565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101a56102613660046137e9565b610660565b6101a5610819565b6101a561091b565b6101a5610284366004613564565b610b1b565b610291610b6b565b6040516101f09190613873565b6101e3610bda565b6102f060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f0565b610326610321366004613886565b610cab565b60405190151581526020016101f0565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6101a561036c36600461391c565b610d8b565b61038461037f3660046139e6565b610fc7565b6040516101f09190613b3b565b6040805160018152600060208201819052918101919091526060016101f0565b6101a56103bf366004613b8f565b611167565b6104f46040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915250604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08201527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e082015290565b6040516101f09190613c46565b61051461050f366004613d06565b61181e565b6040516bffffffffffffffffffffffff90911681526020016101f0565b6101e3611980565b6101a5610547366004613e1f565b6119d7565b610554612403565b6040519081526020016101f0565b6101a5610570366004613eec565b612628565b61057d61263c565b60008190036105b8576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105c5828483613fa2565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065b91906140c8565b905090565b6106686126bf565b806bffffffffffffffffffffffff166000036106a25750336000908152600a60205260409020546bffffffffffffffffffffffff166106fc565b336000908152600a60205260409020546bffffffffffffffffffffffff808316911610156106fc576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906107299084906bffffffffffffffffffffffff16614114565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061077e7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b1580156107fd57600080fd5b505af1158015610811573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461089f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61092361286a565b61092b6126bf565b6000610935610b6b565b905060005b8151811015610b17576000600a600084848151811061095b5761095b614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610b06576000600a60008585815181106109ba576109ba614139565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610a517f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610a7e57610a7e614139565b6020026020010151836040518363ffffffff1660e01b8152600401610ad392919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610aed57600080fd5b505af1158015610b01573d6000803e3d6000fd5b505050505b50610b1081614168565b905061093a565b5050565b610b2361263c565b6000819003610b5e576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105c5828483613fa2565b60606006805480602002602001604051908101604052809291908181526020018280548015610bd057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ba5575b5050505050905090565b6060600d8054610be990613f09565b9050600003610c24576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610c3190613f09565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5d90613f09565b8015610bd05780601f10610c7f57610100808354040283529160200191610bd0565b820191906000526020600020905b815481529060010190602001808311610c8d57509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d1c576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260076020526040902054610d3757506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610d7a9084815260200190565b60405180910390a15060015b919050565b610d9361286a565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167d010000000000000000000000000000000000000000000000000000000000027fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90921674010000000000000000000000000000000000000000027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff63ffffffff94851670010000000000000000000000000000000002167fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff9585166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9786166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a90610fbc908390613c46565b60405180910390a150565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461108f576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a061109b836141a0565b612872565b90506110b26060830160408401613eec565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261110060c0870160a0880161428d565b61111261016088016101408901613eec565b61111c88806142aa565b61112e6101208b016101008c0161430f565b60208b01356111446101008d0160e08e0161432a565b8b60405161115a99989796959493929190614347565b60405180910390a3919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925290831461124e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610896565b61125c8b8b8b8b8b8b612c73565b60007f0000000000000000000000000000000000000000000000000000000000000000156112b95760028260200151836040015161129a91906143ef565b6112a49190614437565b6112af9060016143ef565b60ff1690506112cf565b60208201516112c99060016143ef565b60ff1690505b888114611338576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610896565b8887146113a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610896565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113e4576113e4614459565b60028111156113f5576113f5614459565b905250905060028160200151600281111561141257611412614459565b14801561145957506006816000015160ff168154811061143457611434614139565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6114bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610896565b50505050506114cc6134fc565b6000808a8a6040516114df929190614488565b6040519081900381206114f6918e90602001614498565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b8981101561180057600060018489846020811061155f5761155f614139565b61156c91901a601b6143ef565b8e8e8681811061157e5761157e614139565b905060200201358d8d8781811061159757611597614139565b90506020020135604051600081526020016040526040516115d4949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156115f6573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561167657611676614459565b600281111561168757611687614459565b90525092506001836020015160028111156116a4576116a4614459565b1461170b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610896565b8251600090879060ff16601f811061172557611725614139565b602002015173ffffffffffffffffffffffffffffffffffffffff16146117a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610896565b8086846000015160ff16601f81106117c1576117c1614139565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526117ec6001866143ef565b945050806117f990614168565b9050611540565b505050611811833383858e8e612d2a565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b1580156118be57600080fd5b505afa1580156118d2573d6000803e3d6000fd5b5050505066038d7ea4c68000821115611917576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006119216105ca565b9050600061196487878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061022992505050565b905061197285858385612ef8565b925050505b95945050505050565b6060600c805461198f90613f09565b90506000036119ca576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610c3190613f09565b855185518560ff16601f831115611a4a576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610896565b80600003611ab4576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610896565b818314611b42576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610896565b611b4d8160036144ac565b8311611bb5576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610896565b611bbd61263c565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611c049088612fe2565b60055415611db957600554600090611c1e906001906144c3565b9050600060058281548110611c3557611c35614139565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611c6f57611c6f614139565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611cef57611cef6144d6565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611d5857611d586144d6565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611c04915050565b60005b8151518110156122205760006004600084600001518481518110611de257611de2614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611e2c57611e2c614459565b14611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610896565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611ec457611ec4614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115611f6557611f65614459565b021790555060009150611f759050565b6004600084602001518481518110611f8f57611f8f614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611fd957611fd9614459565b14612040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610896565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061207357612073614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561211457612114614459565b02179055505082518051600592508390811061213257612132614139565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106121ae576121ae614139565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061221881614168565b915050611dbc565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff43811682029290921780855592048116929182916014916122d891849174010000000000000000000000000000000000000000900416614505565b92506101000a81548163ffffffff021916908363ffffffff1602179055506123374630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151612ffb565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986123ee988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614522565b60405180910390a15050505050505050505050565b604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c01000000000000000000000000808304821660608501527001000000000000000000000000000000008304909116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a0808501919091527d01000000000000000000000000000000000000000000000000000000000090920461ffff1660c08401526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa15801561255d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258191906145d2565b50935050925050804261259491906144c3565b836020015163ffffffff161080156125b657506000836020015163ffffffff16115b156125e457505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b60008213612621576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610896565b5092915050565b61263061263c565b612639816130a6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146126bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610896565b565b600b546bffffffffffffffffffffffff166000036126d957565b60006126e3610b6b565b90508051600003612720576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b5460009161273f916bffffffffffffffffffffffff16614622565b905060005b825181101561280b5781600a600085848151811061276457612764614139565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166127cc919061464d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508061280490614168565b9050612744565b5081516128189082614672565b600b80546000906128389084906bffffffffffffffffffffffff16614114565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6126bd61263c565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260408051610100808201835260085463ffffffff80821684526401000000008204811660208501526801000000000000000082048116948401949094526c010000000000000000000000008104841660608401527001000000000000000000000000000000008104909316608083015274010000000000000000000000000000000000000000830468ffffffffffffffffff1660a08301527d01000000000000000000000000000000000000000000000000000000000090920461ffff90811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152928501519192911611156129f8576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff1690506000612a398560e001513a848860800151612ef8565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612a95576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b183087604001518860a001518960c001516001612ab691906146a2565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff1642612c0a91906146c3565b63ffffffff16815250945084604051602001612c269190613b3b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b6000612c808260206144ac565b612c8b8560206144ac565b612c97886101446146c3565b612ca191906146c3565b612cab91906146c3565b612cb69060006146c3565b9050368114612d21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610896565b50505050505050565b606080808080612d3c868801886147b1565b8451949950929750909550935091501580612d5957508351855114155b80612d6657508251855114155b80612d7357508151855114155b80612d8057508051855114155b15612db7576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612eea576000612e4f878381518110612dda57612dda614139565b6020026020010151878481518110612df457612df4614139565b6020026020010151878581518110612e0e57612e0e614139565b6020026020010151878681518110612e2857612e28614139565b6020026020010151878781518110612e4257612e42614139565b602002602001015161319b565b90506000816006811115612e6557612e65614459565b1480612e8257506001816006811115612e8057612e80614459565b145b15612ed957868281518110612e9957612e99614139565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612ee381614168565b9050612dba565b505050505050505050505050565b60085460009081908690612f309063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614505565b612f3a9190614505565b60085463ffffffff918216925060009161271091612f599116886144ac565b612f639190614883565b612f6d90876146c3565b90506000612f7a8261342b565b90506000612f96846bffffffffffffffffffffffff84166144ac565b90506000612fb268ffffffffffffffffff808916908a1661464d565b9050612fd4612fcf6bffffffffffffffffffffffff8316846146c3565b61345a565b9a9950505050505050505050565b6000612fec610b6b565b511115610b1757610b176126bf565b6000808a8a8a8a8a8a8a8a8a60405160200161301f99989796959493929190614897565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613125576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610896565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906131b2919061496d565b9050806040516020016131c59190613b3b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a8152600790935291205414613217576006915050611977565b600087815260076020526040902054613234576002915050611977565b600061323f3a61342b565b905060008261012001518361010001516132599190614a40565b61326a9064ffffffffff1683614672565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff16886132c9919061464d565b338b6040518763ffffffff1660e01b81526004016132ec96959493929190614a5e565b60408051808303816000875af115801561330a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332e9190614ada565b9092509050600082600681111561334757613347614459565b14806133645750600182600681111561336257613362614459565b145b1561341d5760008b815260076020526040812055613382818461464d565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff909216939092916133ee9185911661464d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b6000613454613438612403565b61344a84670de0b6b3a76400006144ac565b612fcf9190614883565b92915050565b60006bffffffffffffffffffffffff8211156134f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610896565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f84011261352d57600080fd5b50813567ffffffffffffffff81111561354557600080fd5b60208301915083602082850101111561355d57600080fd5b9250929050565b6000806020838503121561357757600080fd5b823567ffffffffffffffff81111561358e57600080fd5b61359a8582860161351b565b90969095509350505050565b6000815180845260005b818110156135cc576020818501810151868301820152016135b0565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061361d60208301846135a6565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff8111828210171561367757613677613624565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136c4576136c4613624565b604052919050565b600082601f8301126136dd57600080fd5b813567ffffffffffffffff8111156136f7576136f7613624565b61372860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161367d565b81815284602083860101111561373d57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561376c57600080fd5b813567ffffffffffffffff81111561378357600080fd5b61378f848285016136cc565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461263957600080fd5b8035610d8681613797565b6bffffffffffffffffffffffff8116811461263957600080fd5b8035610d86816137c4565b600080604083850312156137fc57600080fd5b823561380781613797565b91506020830135613817816137c4565b809150509250929050565b600081518084526020808501945080840160005b8381101561386857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613836565b509495945050505050565b60208152600061361d6020830184613822565b60006020828403121561389857600080fd5b5035919050565b63ffffffff8116811461263957600080fd5b8035610d868161389f565b68ffffffffffffffffff8116811461263957600080fd5b8035610d86816138bc565b803561ffff81168114610d8657600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114610d8657600080fd5b600061010080838503121561393057600080fd5b6040519081019067ffffffffffffffff8211818310171561395357613953613624565b81604052833591506139648261389f565b818152613973602085016138b1565b6020820152613984604085016138b1565b6040820152613995606085016138b1565b60608201526139a6608085016138b1565b60808201526139b760a085016138d3565b60a08201526139c860c085016138de565b60c08201526139d960e085016138f0565b60e0820152949350505050565b6000602082840312156139f857600080fd5b813567ffffffffffffffff811115613a0f57600080fd5b8201610160818503121561361d57600080fd5b805182526020810151613a4d602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613a6d60408401826bffffffffffffffffffffffff169052565b506060810151613a95606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613ab1608084018267ffffffffffffffff169052565b5060a0810151613ac960a084018263ffffffff169052565b5060c0810151613ae660c084018268ffffffffffffffffff169052565b5060e0810151613b0360e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b61016081016134548284613a22565b60008083601f840112613b5c57600080fd5b50813567ffffffffffffffff811115613b7457600080fd5b6020830191508360208260051b850101111561355d57600080fd5b60008060008060008060008060e0898b031215613bab57600080fd5b606089018a811115613bbc57600080fd5b8998503567ffffffffffffffff80821115613bd657600080fd5b613be28c838d0161351b565b909950975060808b0135915080821115613bfb57600080fd5b613c078c838d01613b4a565b909750955060a08b0135915080821115613c2057600080fd5b50613c2d8b828c01613b4a565b999c989b50969995989497949560c00135949350505050565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525068ffffffffffffffffff60a08401511660a083015260c0830151613cb560c084018261ffff169052565b5060e083015161262160e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b67ffffffffffffffff8116811461263957600080fd5b8035610d8681613ce5565b600080600080600060808688031215613d1e57600080fd5b8535613d2981613ce5565b9450602086013567ffffffffffffffff811115613d4557600080fd5b613d518882890161351b565b9095509350506040860135613d658161389f565b949793965091946060013592915050565b600067ffffffffffffffff821115613d9057613d90613624565b5060051b60200190565b600082601f830112613dab57600080fd5b81356020613dc0613dbb83613d76565b61367d565b82815260059290921b84018101918181019086841115613ddf57600080fd5b8286015b84811015613e03578035613df681613797565b8352918301918301613de3565b509695505050505050565b803560ff81168114610d8657600080fd5b60008060008060008060c08789031215613e3857600080fd5b863567ffffffffffffffff80821115613e5057600080fd5b613e5c8a838b01613d9a565b97506020890135915080821115613e7257600080fd5b613e7e8a838b01613d9a565b9650613e8c60408a01613e0e565b95506060890135915080821115613ea257600080fd5b613eae8a838b016136cc565b9450613ebc60808a01613cfb565b935060a0890135915080821115613ed257600080fd5b50613edf89828a016136cc565b9150509295509295509295565b600060208284031215613efe57600080fd5b813561361d81613797565b600181811c90821680613f1d57607f821691505b602082108103613f56577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105c557600081815260208120601f850160051c81016020861015613f835750805b601f850160051c820191505b8181101561081157828155600101613f8f565b67ffffffffffffffff831115613fba57613fba613624565b613fce83613fc88354613f09565b83613f5c565b6000601f8411600181146140205760008515613fea5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556140b6565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561406f578685013582556020948501946001909201910161404f565b50868210156140aa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8051610d86816138bc565b6000602082840312156140da57600080fd5b815161361d816138bc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff828116828216039080821115612621576126216140e5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614199576141996140e5565b5060010190565b600061016082360312156141b357600080fd5b6141bb613653565b823567ffffffffffffffff8111156141d257600080fd5b6141de368286016136cc565b825250602083013560208201526141f7604084016137b9565b6040820152614208606084016137de565b6060820152614219608084016138d3565b608082015261422a60a08401613cfb565b60a082015261423b60c08401613cfb565b60c082015261424c60e084016138b1565b60e082015261010061425f8185016138de565b90820152610120614271848201613cfb565b908201526101406142838482016137b9565b9082015292915050565b60006020828403121561429f57600080fd5b813561361d81613ce5565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142df57600080fd5b83018035915067ffffffffffffffff8211156142fa57600080fd5b60200191503681900382131561355d57600080fd5b60006020828403121561432157600080fd5b61361d826138de565b60006020828403121561433c57600080fd5b813561361d8161389f565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301019050612fd460e0830184613a22565b60ff8181168382160190811115613454576134546140e5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff83168061444a5761444a614408565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b8082028115828204841417613454576134546140e5565b81810381811115613454576134546140e5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff818116838216019080821115612621576126216140e5565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526145528184018a613822565b905082810360808401526145668189613822565b905060ff871660a084015282810360c084015261458381876135a6565b905067ffffffffffffffff851660e08401528281036101008401526145a881856135a6565b9c9b505050505050505050505050565b805169ffffffffffffffffffff81168114610d8657600080fd5b600080600080600060a086880312156145ea57600080fd5b6145f3866145b8565b9450602086015193506040860151925060608601519150614616608087016145b8565b90509295509295909350565b60006bffffffffffffffffffffffff8084168061464157614641614408565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115612621576126216140e5565b6bffffffffffffffffffffffff81811683821602808216919082811461469a5761469a6140e5565b505092915050565b67ffffffffffffffff818116838216019080821115612621576126216140e5565b80820180821115613454576134546140e5565b600082601f8301126146e757600080fd5b813560206146f7613dbb83613d76565b82815260059290921b8401810191818101908684111561471657600080fd5b8286015b84811015613e03578035835291830191830161471a565b600082601f83011261474257600080fd5b81356020614752613dbb83613d76565b82815260059290921b8401810191818101908684111561477157600080fd5b8286015b84811015613e0357803567ffffffffffffffff8111156147955760008081fd5b6147a38986838b01016136cc565b845250918301918301614775565b600080600080600060a086880312156147c957600080fd5b853567ffffffffffffffff808211156147e157600080fd5b6147ed89838a016146d6565b9650602088013591508082111561480357600080fd5b61480f89838a01614731565b9550604088013591508082111561482557600080fd5b61483189838a01614731565b9450606088013591508082111561484757600080fd5b61485389838a01614731565b9350608088013591508082111561486957600080fd5b5061487688828901614731565b9150509295509295909350565b60008261489257614892614408565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526148de8285018b613822565b915083820360808501526148f2828a613822565b915060ff881660a085015283820360c085015261490f82886135a6565b90861660e085015283810361010085015290506145a881856135a6565b8051610d8681613797565b8051610d86816137c4565b8051610d8681613ce5565b8051610d868161389f565b805164ffffffffff81168114610d8657600080fd5b6000610160828403121561498057600080fd5b614988613653565b825181526149986020840161492c565b60208201526149a960408401614937565b60408201526149ba6060840161492c565b60608201526149cb60808401614942565b60808201526149dc60a0840161494d565b60a08201526149ed60c084016140bd565b60c08201526149fe60e084016140bd565b60e0820152610100614a11818501614958565b90820152610120614a23848201614958565b90820152610140614a3584820161494d565b908201529392505050565b64ffffffffff818116838216019080821115612621576126216140e5565b6000610200808352614a728184018a6135a6565b90508281036020840152614a8681896135a6565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614acf905060a0830184613a22565b979650505050505050565b60008060408385031215614aed57600080fd5b825160078110614afc57600080fd5b6020840151909250613817816137c456fea164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI diff --git a/core/gethwrappers/functions/generated/functions_router/functions_router.go b/core/gethwrappers/functions/generated/functions_router/functions_router.go index b45052144ac..c035e320157 100644 --- a/core/gethwrappers/functions/generated/functions_router/functions_router.go +++ b/core/gethwrappers/functions/generated/functions_router/functions_router.go @@ -69,7 +69,7 @@ type IFunctionsSubscriptionsSubscription struct { var FunctionsRouterMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateRequestId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deductionAttempt\",\"type\":\"uint256\"}],\"name\":\"TotalBalanceInvariantViolated\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"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\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"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\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620062a3380380620062a38339810160408190526200003491620004df565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200067b565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b462000287565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b92910190620002ea565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516200027c9190620005dd565b60405180910390a150565b60065461010090046001600160a01b03163314620002e85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b828054828255906000526020600020906007016008900481019282156200038e5791602002820160005b838211156200035a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000314565b80156200038c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200035a565b505b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715620003f257620003f2620003b7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004235762000423620003b7565b604052919050565b805161ffff811681146200043e57600080fd5b919050565b600082601f8301126200045557600080fd5b815160206001600160401b03821115620004735762000473620003b7565b8160051b62000484828201620003f8565b92835284810182019282810190878511156200049f57600080fd5b83870192505b84831015620004d457825163ffffffff81168114620004c45760008081fd5b82529183019190830190620004a5565b979650505050505050565b60008060408385031215620004f357600080fd5b82516001600160a01b03811681146200050b57600080fd5b60208401519092506001600160401b03808211156200052957600080fd5b9084019060a082870312156200053e57600080fd5b62000548620003cd565b62000553836200042b565b815260208301516001600160481b03811681146200057057600080fd5b602082015260408301516001600160e01b0319811681146200059157600080fd5b6040820152620005a4606084016200042b565b6060820152608083015182811115620005bc57600080fd5b620005ca8882860162000443565b6080830152508093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160a080840152805160c0840181905260009291820190839060e08601905b808310156200067057835163ffffffff16825292840192600192909201919084019062000648565b509695505050505050565b608051615bf0620006b3600039600081816113b40152818161218701528181612a7f01528181612b4301526132be0152615bf06000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063aab396bd116100e3578063d7ae1d3011610097578063e82ad7d411610071578063e82ad7d4146106bf578063ea320e0b146106d2578063f2fde38b146106e557600080fd5b8063d7ae1d3014610686578063e72f6e3014610699578063e82622aa146106ac57600080fd5b8063badc3eb6116100c8578063badc3eb614610648578063c3f909d41461065e578063cc77470a1461067357600080fd5b8063aab396bd14610638578063b734c0f41461064057600080fd5b80639f87fad71161013a578063a47c76961161011f578063a47c7696146105f2578063a4c0ed3614610612578063a9c9a9181461062557600080fd5b80639f87fad7146105d7578063a21a23e4146105ea57600080fd5b8063823597401161016b57806382359740146105995780638456cb59146105ac5780638da5cb5b146105b457600080fd5b80637341c10c1461057e57806379ba50971461059157600080fd5b80633f4ba83a1161023f5780635c975abb116101f357806366419970116101cd57806366419970146104d6578063674603d0146104fd5780636a2215de1461054657600080fd5b80635c975abb146104995780635ed6dfba146104b057806366316d8d146104c357600080fd5b8063461d276211610224578063461d2762146104455780634b8832d31461045857806355fedefa1461046b57600080fd5b80633f4ba83a1461041c57806341db4ca31461042457600080fd5b80631ded3b36116102965780632a905ccc1161027b5780632a905ccc146103ba57806333060529146103e85780633e871e4d1461040957600080fd5b80631ded3b361461039457806321b60e7f146103a757600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f13660046148c9565b6106f8565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f661032636600461490a565b610757565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f91906149b1565b6102f66103a23660046149c4565b610853565b6102f66103b5366004614b87565b610885565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161030f565b6103fb6103f6366004614e33565b6109b2565b60405161030f929190614f1b565b6102f6610417366004614fa8565b610d8a565b6102f661100f565b6104376104323660046150aa565b611021565b60405190815260200161030f565b6104376104533660046150aa565b611081565b6102f661046636600461512e565b61108d565b6104376104793660046148c9565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f66104be36600461515c565b6111db565b6102f66104d136600461515c565b6113fd565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b61051061050b36600461518a565b61154f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161030f565b6105596105543660046151b8565b6115df565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f661058c36600461512e565b61169e565b6102f6611852565b6102f66105a73660046148c9565b611979565b6102f6611ac0565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610559565b6102f66105e536600461512e565b611ad0565b6104e4611ea5565b6106056106003660046148c9565b612032565b60405161030f9190615222565b6102f66106203660046152aa565b612167565b6105596106333660046151b8565b6123b3565b600954610437565b6102f6612412565b61065061255e565b60405161030f929190615306565b61066661262e565b60405161030f919061535d565b6104e4610681366004615407565b612763565b6102f661069436600461512e565b6129e3565b6102f66106a7366004615407565b612a46565b6102f66106ba366004615424565b612bbf565b6104a06106cd3660046148c9565b612e90565b6102f66106e03660046151b8565b612fdf565b6102f66106f3366004615407565b612fec565b610700612ffd565b61070981613005565b67ffffffffffffffff81166000908152600360205260409020546107549082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661307b565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107bc576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106107d7576107d761549a565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff16111561084d576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107b3565b50505050565b61085b612ffd565b61086482613005565b67ffffffffffffffff90911660009081526003602081905260409091200155565b61088d613367565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361097492600b92910190614714565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516109a7919061535d565b60405180910390a150565b6000806109bd6133ed565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a26576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251600090815260056020526040902054610a885782516020840151604051600294507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154c9565b60405180910390a2506000610d7f565b8251600090815260056020908152604091829020549151610aab918691016154fb565b6040516020818303038152906040528051906020012014610b035782516020840151604051600694507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154c9565b8261012001518360a0015163ffffffff16610b1e9190615657565b64ffffffffff165a1015610b695782516020840151604051600494507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154c9565b6000610b7e8460a0015163ffffffff166133f5565b610b88908861567c565b9050600081878660c0015168ffffffffffffffffff16610ba891906156a4565b610bb291906156a4565b9050610bc18560800151612032565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c395784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154c9565b60405180910390a25060009150610d7f9050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c9e5784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154c9565b505082516000908152600560205260408120819055835160a08501516060860151610cce92918c918c9190613497565b8051909150610cde576001610ce1565b60005b92506000610d1b8560800151866040015187606001518860c0015168ffffffffffffffffff168c610d1588602001516133f5565b8d613626565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610d72969594939291906156c9565b60405180910390a3519150505b965096945050505050565b610d92613367565b8151815181141580610da45750600881115b15610ddb576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ecd576000848281518110610dfa57610dfa61549a565b602002602001015190506000848381518110610e1857610e1861549a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e83575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610eba576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080610ec69061574c565b9050610dde565b506040805180820190915283815260208082018490528451600c91610ef69183918801906147bf565b506020828101518051610f0f92600185019201906147fa565b5090505060005b835181101561084d577f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481848281518110610f5257610f5261549a565b602002602001015160086000878581518110610f7057610f7061549a565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858481518110610fb957610fb961549a565b6020026020010151604051610ff79392919092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a16110088161574c565b9050610f16565b611017613367565b61101f6139a8565b565b60008061102d836115df565b905061107583828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613a259050565b98975050505050505050565b60008061102d836123b3565b6110956133ed565b61109e82613e1d565b6110a6613ee3565b73ffffffffffffffffffffffffffffffffffffffff8116158061110d575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15611144576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6111e3612ffd565b806bffffffffffffffffffffffff166000036112195750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611285576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff808416911610156112ee576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b306000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff166113719190615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506113f883836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613fed9092919063ffffffff16565b505050565b6114056133ed565b806bffffffffffffffffffffffff1660000361144d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff9081169082168110156114b9576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff80841691161015611522576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b336000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615784565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600c5460ff8216101561166857600c805460ff83169081106116075761160761549a565b9060005260206000200154830361165857600d805460ff831690811061162f5761162f61549a565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b611661816157a9565b90506115e3565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107b3565b6116a66133ed565b6116af82613e1d565b6116b7613ee3565b60006116c6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff82169003611729576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff161561177157505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff1633146118d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107b3565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6119816133ed565b611989613ee3565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611a29576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107b3565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611845565b611ac8613367565b61101f61407a565b611ad86133ed565b611ae182613e1d565b611ae9613ee3565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b91576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611be6576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611c6157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c36575b5050505050905060005b8151811015611e09578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c9d57611c9d61549a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611df9578160018351611ccf91906157c8565b81518110611cdf57611cdf61549a565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611d2257611d2261549a565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d9c57611d9c6157db565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611e09565b611e028161574c565b9050611c6b565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b6000611eaf6133ed565b611eb7613ee3565b60028054600090611ed19067ffffffffffffffff1661580a565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611f47578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611fe2926002850192909101906147fa565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a081019190915261206c82613005565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561214d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612122575b505050505081526020016003820154815250509050919050565b61216f6133ed565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146121de576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612218576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612226828401846148c9565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661229f576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906122d683856156a4565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff1661232c91906156a4565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846123939190615831565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff16806115d9576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107b3565b61241a613367565b60005b600c5481101561253d576000600c600001828154811061243f5761243f61549a565b906000526020600020015490506000600c60010183815481106124645761246461549a565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556125368161574c565b905061241d565b50600c600061254c8282614874565b61255a600183016000614874565b5050565b606080600c600001600c600101818054806020026020016040519081016040528092919081815260200182805480156125b657602002820191906000526020600020905b8154815260200190600101908083116125a2575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561261f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116125f4575b50505050509050915091509091565b6040805160a08101825260008082526020820181905291810182905260608082019290925260808101919091526040805160a081018252600a805461ffff808216845268ffffffffffffffffff620100008304166020808601919091527fffffffff000000000000000000000000000000000000000000000000000000006b010000000000000000000000840460e01b16858701526f01000000000000000000000000000000909204166060840152600b80548551818402810184019096528086529394929360808601939283018282801561275557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116127185790505b505050505081525050905090565b600061276d6133ed565b612775613ee3565b6002805460009061278f9067ffffffffffffffff1661580a565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015612805578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff93841617845593860151606087015190911690930292169190911760018201556080830151805191926128a0926002850192909101906147fa565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b6129eb6133ed565b6129f482613e1d565b6129fc613ee3565b612a0582612e90565b15612a3c576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61255a828261307b565b612a4e612ffd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff9190615844565b6000549091506bffffffffffffffffffffffff16818110156113f8576000612b2782846157c8565b9050612b6a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583613fed565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612bc76133ed565b60005b818110156113f8576000838383818110612be657612be661549a565b90506101600201803603810190612bfd919061585d565b80516080820151600082815260056020908152604091829020549151949550929391929091612c2e918691016154fb565b6040516020818303038152906040528051906020012014612c7b576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612cc0576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d57919061587a565b5060408084015167ffffffffffffffff831660009081526003602052918220600101805491929091612d989084906bffffffffffffffffffffffff16615784565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612e20918591690100000000000000000090041661589c565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612e899061574c565b9050612bca565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612f0857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612edd575b5050505050905060005b8151811015612fd557600060046000848481518110612f3357612f3361549a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612fc457506001949350505050565b50612fce8161574c565b9050612f12565b5060009392505050565b612fe7613367565b600955565b612ff4613367565b610754816140d5565b61101f613367565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610754576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561315c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613131575b505050918352505060039190910154602090910152805190915060005b82608001515181101561321d5760046000846080015183815181106131a0576131a061549a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690556132168161574c565b9050613179565b5067ffffffffffffffff84166000908152600360205260408120818155600181018290559061324f6002830182614874565b5060006003919091018190558054829190819061327b9084906bffffffffffffffffffffffff16615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061330283826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613fed9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e97565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16331461101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107b3565b61101f6141d1565b60006bffffffffffffffffffffffff821115613493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107b3565b5090565b60408051606080820183526000808352602083015291810191909152600a546040516000916b010000000000000000000000900460e01b906134e1908990899089906024016158bd565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f0100000000000000000000000000000090910416926000928392839282018180368337019050509050863b6135ac57600080fd5b5a848110156135ba57600080fd5b84900360408104810389106135ce57600080fd5b505a60008087516020890160008c8ef193505a900391503d60848111156135f3575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015298975050505050505050565b60408051808201909152600080825260208201526000613646848661567c565b905060008161365588866156a4565b61365f91906156a4565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff808316911610156136f25767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812080548392906137299084906bffffffffffffffffffffffff16615784565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600360205260409020600101548b82169116101590506137d65767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812060010180548b92906138109084906bffffffffffffffffffffffff16615784565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461384a91906156a4565b33600090815260016020526040812080549091906138779084906bffffffffffffffffffffffff166156a4565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926138be918591166156a4565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f16855292529091208054600192600991613942918591690100000000000000000090041661589c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b6139b061423e565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613a2f6133ed565b613a3885613005565b613a4233866142aa565b613a4c8583610757565b8351600003613a86576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613a9186612032565b90506000613a9f338861154f565b905060008873ffffffffffffffffffffffffffffffffffffffff1663a631571e6040518061016001604052808a8152602001613af58c67ffffffffffffffff166000908152600360208190526040909120015490565b815233602082015260408781015188519190920191613b1391615784565b6bffffffffffffffffffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018b67ffffffffffffffff168152602001856020015167ffffffffffffffff1681526020018863ffffffff1681526020018961ffff168152602001856040015167ffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613bd991906158e8565b610160604051808303816000875af1158015613bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1d9190615a4d565b805160009081526005602052604090205490915015613c6e5780516040517f304f32e800000000000000000000000000000000000000000000000000000000815260048101919091526024016107b3565b604051806101600160405280826000015181526020018a73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018967ffffffffffffffff1681526020018663ffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff16815250604051602001613d7391906154fb565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550613db33389836040015161431e565b8767ffffffffffffffff168a82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9866020015133328d8d8d8a60400151604051613e079796959493929190615b20565b60405180910390a4519998505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613e94576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461255a576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613f135750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613f7490339060248101615b98565b602060405180830381865afa158015613f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb5919061587a565b610754576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107b3565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f89084906143f9565b6140826141d1565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586139fb3390565b3373ffffffffffffffffffffffffffffffffffffffff821603614154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107b3565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff161561101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107b3565b60065460ff1661101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff1661255a576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143589084906bffffffffffffffffffffffff166156a4565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff80891685529252909120805460019450909284926143ce92849290041661589c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b600061445b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166145059092919063ffffffff16565b8051909150156113f85780806020019051810190614479919061587a565b6113f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107b3565b6060614514848460008561451c565b949350505050565b6060824710156145ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107b3565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516145d79190615bc7565b60006040518083038185875af1925050503d8060008114614614576040519150601f19603f3d011682016040523d82523d6000602084013e614619565b606091505b509150915061462a87838387614635565b979650505050505050565b606083156146cb5782516000036146c45773ffffffffffffffffffffffffffffffffffffffff85163b6146c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b5081614514565b61451483838151156146e05781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b391906149b1565b828054828255906000526020600020906007016008900481019282156147b35791602002820160005b8382111561478157835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261473d565b80156147b15782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614781565b505b5061349392915061488e565b8280548282559060005260206000209081019282156147b3579160200282015b828111156147b35782518255916020019190600101906147df565b8280548282559060005260206000209081019282156147b3579160200282015b828111156147b357825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061481a565b508054600082559060005260206000209081019061075491905b5b80821115613493576000815560010161488f565b67ffffffffffffffff8116811461075457600080fd5b80356148c4816148a3565b919050565b6000602082840312156148db57600080fd5b81356148e6816148a3565b9392505050565b63ffffffff8116811461075457600080fd5b80356148c4816148ed565b6000806040838503121561491d57600080fd5b8235614928816148a3565b91506020830135614938816148ed565b809150509250929050565b60005b8381101561495e578181015183820152602001614946565b50506000910152565b6000815180845261497f816020860160208601614943565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006148e66020830184614967565b600080604083850312156149d757600080fd5b82356149e2816148a3565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614a4257614a426149f0565b60405290565b604051610160810167ffffffffffffffff81118282101715614a4257614a426149f0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ab357614ab36149f0565b604052919050565b803561ffff811681146148c457600080fd5b68ffffffffffffffffff8116811461075457600080fd5b80356148c481614acd565b600067ffffffffffffffff821115614b0957614b096149f0565b5060051b60200190565b600082601f830112614b2457600080fd5b81356020614b39614b3483614aef565b614a6c565b82815260059290921b84018101918181019086841115614b5857600080fd5b8286015b84811015614b7c578035614b6f816148ed565b8352918301918301614b5c565b509695505050505050565b600060208284031215614b9957600080fd5b813567ffffffffffffffff80821115614bb157600080fd5b9083019060a08286031215614bc557600080fd5b614bcd614a1f565b614bd683614abb565b81526020830135614be681614acd565b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114614c1e57600080fd5b6040820152614c2f60608401614abb565b6060820152608083013582811115614c4657600080fd5b614c5287828601614b13565b60808301525095945050505050565b600082601f830112614c7257600080fd5b813567ffffffffffffffff811115614c8c57614c8c6149f0565b614cbd60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a6c565b818152846020838601011115614cd257600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461075457600080fd5b80356148c481614cef565b73ffffffffffffffffffffffffffffffffffffffff8116811461075457600080fd5b80356148c481614d14565b64ffffffffff8116811461075457600080fd5b80356148c481614d41565b60006101608284031215614d7257600080fd5b614d7a614a48565b905081358152614d8c60208301614d36565b6020820152614d9d60408301614d09565b6040820152614dae60608301614d36565b6060820152614dbf608083016148b9565b6080820152614dd060a083016148ff565b60a0820152614de160c08301614ae4565b60c0820152614df260e08301614ae4565b60e0820152610100614e05818401614d54565b90820152610120614e17838201614d54565b90820152610140614e298382016148ff565b9082015292915050565b6000806000806000806102008789031215614e4d57600080fd5b863567ffffffffffffffff80821115614e6557600080fd5b614e718a838b01614c61565b97506020890135915080821115614e8757600080fd5b50614e9489828a01614c61565b9550506040870135614ea581614cef565b93506060870135614eb581614cef565b92506080870135614ec581614d14565b9150614ed48860a08901614d5f565b90509295509295509295565b60078110614f17577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60408101614f298285614ee0565b6bffffffffffffffffffffffff831660208301529392505050565b600082601f830112614f5557600080fd5b81356020614f65614b3483614aef565b82815260059290921b84018101918181019086841115614f8457600080fd5b8286015b84811015614b7c578035614f9b81614d14565b8352918301918301614f88565b60008060408385031215614fbb57600080fd5b823567ffffffffffffffff80821115614fd357600080fd5b818501915085601f830112614fe757600080fd5b81356020614ff7614b3483614aef565b82815260059290921b8401810191818101908984111561501657600080fd5b948201945b838610156150345785358252948201949082019061501b565b9650508601359250508082111561504a57600080fd5b5061505785828601614f44565b9150509250929050565b60008083601f84011261507357600080fd5b50813567ffffffffffffffff81111561508b57600080fd5b6020830191508360208285010111156150a357600080fd5b9250929050565b60008060008060008060a087890312156150c357600080fd5b86356150ce816148a3565b9550602087013567ffffffffffffffff8111156150ea57600080fd5b6150f689828a01615061565b9096509450615109905060408801614abb565b92506060870135615119816148ed565b80925050608087013590509295509295509295565b6000806040838503121561514157600080fd5b823561514c816148a3565b9150602083013561493881614d14565b6000806040838503121561516f57600080fd5b823561517a81614d14565b9150602083013561493881614cef565b6000806040838503121561519d57600080fd5b82356151a881614d14565b91506020830135614938816148a3565b6000602082840312156151ca57600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561521757815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016151e5565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a084015261529460e08401826151d1565b905060a084015160c08401528091505092915050565b600080600080606085870312156152c057600080fd5b84356152cb81614d14565b935060208501359250604085013567ffffffffffffffff8111156152ee57600080fd5b6152fa87828801615061565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b8281101561533f57815184529284019290840190600101615323565b5050508381038285015261535381866151d1565b9695505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b80831015614b7c57835163ffffffff1682529284019260019290920191908401906153e1565b60006020828403121561541957600080fd5b81356148e681614d14565b6000806020838503121561543757600080fd5b823567ffffffffffffffff8082111561544f57600080fd5b818501915085601f83011261546357600080fd5b81358181111561547257600080fd5b8660206101608302850101111561548857600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016145146040830184614ee0565b8151815260208083015161016083019161552c9084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015161554c60408401826bffffffffffffffffffffffff169052565b506060830151615574606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151615590608084018267ffffffffffffffff169052565b5060a08301516155a860a084018263ffffffff169052565b5060c08301516155c560c084018268ffffffffffffffffff169052565b5060e08301516155e260e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff81811683821601908082111561567557615675615628565b5092915050565b6bffffffffffffffffffffffff81811683821602808216919082811461562057615620615628565b6bffffffffffffffffffffffff81811683821601908082111561567557615675615628565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff861660208201526157036040820186614ee0565b60c06060820152600061571960c0830186614967565b828103608084015261572b8186614967565b905082810360a084015261573f8185614967565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361577d5761577d615628565b5060010190565b6bffffffffffffffffffffffff82811682821603908082111561567557615675615628565b600060ff821660ff81036157bf576157bf615628565b60010192915050565b818103818111156115d9576115d9615628565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff80831681810361582757615827615628565b6001019392505050565b808201808211156115d9576115d9615628565b60006020828403121561585657600080fd5b5051919050565b6000610160828403121561587057600080fd5b6148e68383614d5f565b60006020828403121561588c57600080fd5b815180151581146148e657600080fd5b67ffffffffffffffff81811683821601908082111561567557615675615628565b8381526060602082015260006158d66060830185614967565b82810360408401526153538185614967565b6020815260008251610160806020850152615907610180850183614967565b915060208501516040850152604085015161593a606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e08501516101006159b18187018363ffffffff169052565b86015190506101206159c88682018361ffff169052565b86015190506101406159e58682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b80516148c481614d14565b80516148c481614cef565b80516148c4816148a3565b80516148c4816148ed565b80516148c481614acd565b80516148c481614d41565b60006101608284031215615a6057600080fd5b615a68614a48565b82518152615a7860208401615a0b565b6020820152615a8960408401615a16565b6040820152615a9a60608401615a0b565b6060820152615aab60808401615a21565b6080820152615abc60a08401615a2c565b60a0820152615acd60c08401615a37565b60c0820152615ade60e08401615a37565b60e0820152610100615af1818501615a42565b90820152610120615b03848201615a42565b90820152610140615b15848201615a2c565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615b6160e0830187614967565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006145146040830184614967565b60008251615bd9818460208701614943565b919091019291505056fea164736f6c6343000813000a", + Bin: "0x60a06040523480156200001157600080fd5b50604051620062d1380380620062d18339810160408190526200003491620004df565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200067b565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b462000287565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b92910190620002ea565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516200027c9190620005dd565b60405180910390a150565b60065461010090046001600160a01b03163314620002e85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b828054828255906000526020600020906007016008900481019282156200038e5791602002820160005b838211156200035a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000314565b80156200038c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200035a565b505b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715620003f257620003f2620003b7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004235762000423620003b7565b604052919050565b805161ffff811681146200043e57600080fd5b919050565b600082601f8301126200045557600080fd5b815160206001600160401b03821115620004735762000473620003b7565b8160051b62000484828201620003f8565b92835284810182019282810190878511156200049f57600080fd5b83870192505b84831015620004d457825163ffffffff81168114620004c45760008081fd5b82529183019190830190620004a5565b979650505050505050565b60008060408385031215620004f357600080fd5b82516001600160a01b03811681146200050b57600080fd5b60208401519092506001600160401b03808211156200052957600080fd5b9084019060a082870312156200053e57600080fd5b62000548620003cd565b62000553836200042b565b815260208301516001600160481b03811681146200057057600080fd5b602082015260408301516001600160e01b0319811681146200059157600080fd5b6040820152620005a4606084016200042b565b6060820152608083015182811115620005bc57600080fd5b620005ca8882860162000443565b6080830152508093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160a080840152805160c0840181905260009291820190839060e08601905b808310156200067057835163ffffffff16825292840192600192909201919084019062000648565b509695505050505050565b608051615c1e620006b3600039600081816113b40152818161218601528181612a7e01528181612b4201526132bd0152615c1e6000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063aab396bd116100e3578063d7ae1d3011610097578063e82ad7d411610071578063e82ad7d4146106bf578063ea320e0b146106d2578063f2fde38b146106e557600080fd5b8063d7ae1d3014610686578063e72f6e3014610699578063e82622aa146106ac57600080fd5b8063badc3eb6116100c8578063badc3eb614610648578063c3f909d41461065e578063cc77470a1461067357600080fd5b8063aab396bd14610638578063b734c0f41461064057600080fd5b80639f87fad71161013a578063a47c76961161011f578063a47c7696146105f2578063a4c0ed3614610612578063a9c9a9181461062557600080fd5b80639f87fad7146105d7578063a21a23e4146105ea57600080fd5b8063823597401161016b57806382359740146105995780638456cb59146105ac5780638da5cb5b146105b457600080fd5b80637341c10c1461057e57806379ba50971461059157600080fd5b80633f4ba83a1161023f5780635c975abb116101f357806366419970116101cd57806366419970146104d6578063674603d0146104fd5780636a2215de1461054657600080fd5b80635c975abb146104995780635ed6dfba146104b057806366316d8d146104c357600080fd5b8063461d276211610224578063461d2762146104455780634b8832d31461045857806355fedefa1461046b57600080fd5b80633f4ba83a1461041c57806341db4ca31461042457600080fd5b80631ded3b36116102965780632a905ccc1161027b5780632a905ccc146103ba57806333060529146103e85780633e871e4d1461040957600080fd5b80631ded3b361461039457806321b60e7f146103a757600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f13660046148f7565b6106f8565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f6610326366004614938565b610757565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f91906149df565b6102f66103a23660046149f2565b610853565b6102f66103b5366004614bb5565b610885565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161030f565b6103fb6103f6366004614e61565b6109b2565b60405161030f929190614f49565b6102f6610417366004614fd6565b610d8a565b6102f661100f565b6104376104323660046150d8565b611021565b60405190815260200161030f565b6104376104533660046150d8565b611081565b6102f661046636600461515c565b61108d565b6104376104793660046148f7565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f66104be36600461518a565b6111db565b6102f66104d136600461518a565b6113fd565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b61051061050b3660046151b8565b61154f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161030f565b6105596105543660046151e6565b6115df565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f661058c36600461515c565b61169e565b6102f6611851565b6102f66105a73660046148f7565b611978565b6102f6611abf565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610559565b6102f66105e536600461515c565b611acf565b6104e4611ea4565b6106056106003660046148f7565b612031565b60405161030f9190615250565b6102f66106203660046152d8565b612166565b6105596106333660046151e6565b6123b2565b600954610437565b6102f6612411565b61065061255d565b60405161030f929190615334565b61066661262d565b60405161030f919061538b565b6104e4610681366004615435565b612762565b6102f661069436600461515c565b6129e2565b6102f66106a7366004615435565b612a45565b6102f66106ba366004615452565b612bbe565b6104a06106cd3660046148f7565b612e8f565b6102f66106e03660046151e6565b612fde565b6102f66106f3366004615435565b612feb565b610700612ffc565b61070981613004565b67ffffffffffffffff81166000908152600360205260409020546107549082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661307a565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107bc576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106107d7576107d76154c8565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff16111561084d576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107b3565b50505050565b61085b612ffc565b61086482613004565b67ffffffffffffffff90911660009081526003602081905260409091200155565b61088d613366565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361097492600b92910190614742565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516109a7919061538b565b60405180910390a150565b6000806109bd6133ec565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a26576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251600090815260056020526040902054610a885782516020840151604051600294507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154f7565b60405180910390a2506000610d7f565b8251600090815260056020908152604091829020549151610aab91869101615529565b6040516020818303038152906040528051906020012014610b035782516020840151604051600694507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154f7565b8261012001518360a0015163ffffffff16610b1e9190615685565b64ffffffffff165a1015610b695782516020840151604051600494507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154f7565b6000610b7e8460a0015163ffffffff166133f4565b610b8890886156aa565b9050600081878660c0015168ffffffffffffffffff16610ba891906156d2565b610bb291906156d2565b9050610bc18560800151612031565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c395784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154f7565b60405180910390a25060009150610d7f9050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c9e5784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154f7565b505082516000908152600560205260408120819055835160a08501516060860151610cce92918c918c9190613496565b8051909150610cde576001610ce1565b60005b92506000610d1b8560800151866040015187606001518860c0015168ffffffffffffffffff168c610d1588602001516133f4565b8d613654565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610d72969594939291906156f7565b60405180910390a3519150505b965096945050505050565b610d92613366565b8151815181141580610da45750600881115b15610ddb576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ecd576000848281518110610dfa57610dfa6154c8565b602002602001015190506000848381518110610e1857610e186154c8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e83575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610eba576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080610ec69061577a565b9050610dde565b506040805180820190915283815260208082018490528451600c91610ef69183918801906147ed565b506020828101518051610f0f9260018501920190614828565b5090505060005b835181101561084d577f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481848281518110610f5257610f526154c8565b602002602001015160086000878581518110610f7057610f706154c8565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858481518110610fb957610fb96154c8565b6020026020010151604051610ff79392919092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a16110088161577a565b9050610f16565b611017613366565b61101f6139d6565b565b60008061102d836115df565b905061107583828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613a539050565b98975050505050505050565b60008061102d836123b2565b6110956133ec565b61109e82613e4b565b6110a6613f11565b73ffffffffffffffffffffffffffffffffffffffff8116158061110d575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15611144576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6111e3612ffc565b806bffffffffffffffffffffffff166000036112195750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611285576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff808416911610156112ee576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b306000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff166157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff1661137191906157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506113f883836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661401b9092919063ffffffff16565b505050565b6114056133ec565b806bffffffffffffffffffffffff1660000361144d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff9081169082168110156114b9576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff80841691161015611522576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b336000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff166157b2565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600c5460ff8216101561166857600c805460ff8316908110611607576116076154c8565b9060005260206000200154830361165857600d805460ff831690811061162f5761162f6154c8565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b611661816157d7565b90506115e3565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107b3565b6116a66133ec565b6116af82613e4b565b6116b7613f11565b60006116c6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff821611611728576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff161561177057505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff1633146118d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107b3565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6119806133ec565b611988613f11565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611a28576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107b3565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611844565b611ac7613366565b61101f6140a8565b611ad76133ec565b611ae082613e4b565b611ae8613f11565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b90576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611be5576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611c6057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c35575b5050505050905060005b8151811015611e08578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c9c57611c9c6154c8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611df8578160018351611cce91906157f6565b81518110611cde57611cde6154c8565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611d2157611d216154c8565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d9b57611d9b615809565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611e08565b611e018161577a565b9050611c6a565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b6000611eae6133ec565b611eb6613f11565b60028054600090611ed09067ffffffffffffffff16615838565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611f46578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611fe192600285019290910190614828565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a081019190915261206b82613004565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561214c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612121575b505050505081526020016003820154815250509050919050565b61216e6133ec565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146121dd576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612217576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612225828401846148f7565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661229e576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906122d583856156d2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff1661232b91906156d2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f8828784612392919061585f565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff16806115d9576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107b3565b612419613366565b60005b600c5481101561253c576000600c600001828154811061243e5761243e6154c8565b906000526020600020015490506000600c6001018381548110612463576124636154c8565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556125358161577a565b905061241c565b50600c600061254b82826148a2565b6125596001830160006148a2565b5050565b606080600c600001600c600101818054806020026020016040519081016040528092919081815260200182805480156125b557602002820191906000526020600020905b8154815260200190600101908083116125a1575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561261e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116125f3575b50505050509050915091509091565b6040805160a08101825260008082526020820181905291810182905260608082019290925260808101919091526040805160a081018252600a805461ffff808216845268ffffffffffffffffff620100008304166020808601919091527fffffffff000000000000000000000000000000000000000000000000000000006b010000000000000000000000840460e01b16858701526f01000000000000000000000000000000909204166060840152600b80548551818402810184019096528086529394929360808601939283018282801561275457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116127175790505b505050505081525050905090565b600061276c6133ec565b612774613f11565b6002805460009061278e9067ffffffffffffffff16615838565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015612804578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff938416178455938601516060870151909116909302921691909117600182015560808301518051919261289f92600285019290910190614828565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b6129ea6133ec565b6129f382613e4b565b6129fb613f11565b612a0482612e8f565b15612a3b576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612559828261307a565b612a4d612ffc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612ada573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612afe9190615872565b6000549091506bffffffffffffffffffffffff16818110156113f8576000612b2682846157f6565b9050612b6973ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016858361401b565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612bc66133ec565b60005b818110156113f8576000838383818110612be557612be56154c8565b90506101600201803603810190612bfc919061588b565b80516080820151600082815260056020908152604091829020549151949550929391929091612c2d91869101615529565b6040516020818303038152906040528051906020012014612c7a576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612cbf576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015612d32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5691906158a8565b5060408084015167ffffffffffffffff831660009081526003602052918220600101805491929091612d979084906bffffffffffffffffffffffff166157b2565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612e1f91859169010000000000000000009004166158ca565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612e889061577a565b9050612bc9565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612f0757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612edc575b5050505050905060005b8151811015612fd457600060046000848481518110612f3257612f326154c8565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612fc357506001949350505050565b50612fcd8161577a565b9050612f11565b5060009392505050565b612fe6613366565b600955565b612ff3613366565b61075481614103565b61101f613366565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610754576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561315b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613130575b505050918352505060039190910154602090910152805190915060005b82608001515181101561321c57600460008460800151838151811061319f5761319f6154c8565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690556132158161577a565b9050613178565b5067ffffffffffffffff84166000908152600360205260408120818155600181018290559061324e60028301826148a2565b5060006003919091018190558054829190819061327a9084906bffffffffffffffffffffffff166157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061330183826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661401b9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e96565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16331461101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107b3565b61101f6141ff565b60006bffffffffffffffffffffffff821115613492576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107b3565b5090565b60408051606080820183526000808352602083015291810191909152813b1580156134e957505060408051606081018252600080825260208083018290528351918252810183529181019190915261364b565b600a546040516000916b010000000000000000000000900460e01b90613517908a908a908a906024016158eb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f01000000000000000000000000000000909104169260009283928392820181803683370190505090505a848110156135e557600080fd5b8490036040810481038a106135f957600080fd5b505a60008087516020890160008d8ff193505a900391503d608481111561361e575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015293505050505b95945050505050565b6040805180820190915260008082526020820152600061367484866156aa565b905060008161368388866156d2565b61368d91906156d2565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff808316911610156137205767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812080548392906137579084906bffffffffffffffffffffffff166157b2565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600360205260409020600101548b82169116101590506138045767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812060010180548b929061383e9084906bffffffffffffffffffffffff166157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461387891906156d2565b33600090815260016020526040812080549091906138a59084906bffffffffffffffffffffffff166156d2565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926138ec918591166156d2565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f1685529252909120805460019260099161397091859169010000000000000000009004166158ca565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b6139de61426c565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613a5d6133ec565b613a6685613004565b613a7033866142d8565b613a7a8583610757565b8351600003613ab4576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613abf86612031565b90506000613acd338861154f565b905060008873ffffffffffffffffffffffffffffffffffffffff1663a631571e6040518061016001604052808a8152602001613b238c67ffffffffffffffff166000908152600360208190526040909120015490565b815233602082015260408781015188519190920191613b41916157b2565b6bffffffffffffffffffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018b67ffffffffffffffff168152602001856020015167ffffffffffffffff1681526020018863ffffffff1681526020018961ffff168152602001856040015167ffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613c079190615916565b610160604051808303816000875af1158015613c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c4b9190615a7b565b805160009081526005602052604090205490915015613c9c5780516040517f304f32e800000000000000000000000000000000000000000000000000000000815260048101919091526024016107b3565b604051806101600160405280826000015181526020018a73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018967ffffffffffffffff1681526020018663ffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff16815250604051602001613da19190615529565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550613de13389836040015161434c565b8767ffffffffffffffff168a82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9866020015133328d8d8d8a60400151604051613e359796959493929190615b4e565b60405180910390a4519998505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613ec2576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614612559576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613f415750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613fa290339060248101615bc6565b602060405180830381865afa158015613fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fe391906158a8565b610754576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107b3565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f8908490614427565b6140b06141ff565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613a293390565b3373ffffffffffffffffffffffffffffffffffffffff821603614182576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107b3565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff161561101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107b3565b60065460ff1661101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff16612559576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143869084906bffffffffffffffffffffffff166156d2565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff80891685529252909120805460019450909284926143fc9284929004166158ca565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b6000614489826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166145339092919063ffffffff16565b8051909150156113f857808060200190518101906144a791906158a8565b6113f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107b3565b6060614542848460008561454a565b949350505050565b6060824710156145dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107b3565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516146059190615bf5565b60006040518083038185875af1925050503d8060008114614642576040519150601f19603f3d011682016040523d82523d6000602084013e614647565b606091505b509150915061465887838387614663565b979650505050505050565b606083156146f95782516000036146f25773ffffffffffffffffffffffffffffffffffffffff85163b6146f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b5081614542565b614542838381511561470e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b391906149df565b828054828255906000526020600020906007016008900481019282156147e15791602002820160005b838211156147af57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261476b565b80156147df5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026147af565b505b506134929291506148bc565b8280548282559060005260206000209081019282156147e1579160200282015b828111156147e157825182559160200191906001019061480d565b8280548282559060005260206000209081019282156147e1579160200282015b828111156147e157825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614848565b508054600082559060005260206000209081019061075491905b5b8082111561349257600081556001016148bd565b67ffffffffffffffff8116811461075457600080fd5b80356148f2816148d1565b919050565b60006020828403121561490957600080fd5b8135614914816148d1565b9392505050565b63ffffffff8116811461075457600080fd5b80356148f28161491b565b6000806040838503121561494b57600080fd5b8235614956816148d1565b915060208301356149668161491b565b809150509250929050565b60005b8381101561498c578181015183820152602001614974565b50506000910152565b600081518084526149ad816020860160208601614971565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006149146020830184614995565b60008060408385031215614a0557600080fd5b8235614a10816148d1565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614a7057614a70614a1e565b60405290565b604051610160810167ffffffffffffffff81118282101715614a7057614a70614a1e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ae157614ae1614a1e565b604052919050565b803561ffff811681146148f257600080fd5b68ffffffffffffffffff8116811461075457600080fd5b80356148f281614afb565b600067ffffffffffffffff821115614b3757614b37614a1e565b5060051b60200190565b600082601f830112614b5257600080fd5b81356020614b67614b6283614b1d565b614a9a565b82815260059290921b84018101918181019086841115614b8657600080fd5b8286015b84811015614baa578035614b9d8161491b565b8352918301918301614b8a565b509695505050505050565b600060208284031215614bc757600080fd5b813567ffffffffffffffff80821115614bdf57600080fd5b9083019060a08286031215614bf357600080fd5b614bfb614a4d565b614c0483614ae9565b81526020830135614c1481614afb565b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114614c4c57600080fd5b6040820152614c5d60608401614ae9565b6060820152608083013582811115614c7457600080fd5b614c8087828601614b41565b60808301525095945050505050565b600082601f830112614ca057600080fd5b813567ffffffffffffffff811115614cba57614cba614a1e565b614ceb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a9a565b818152846020838601011115614d0057600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461075457600080fd5b80356148f281614d1d565b73ffffffffffffffffffffffffffffffffffffffff8116811461075457600080fd5b80356148f281614d42565b64ffffffffff8116811461075457600080fd5b80356148f281614d6f565b60006101608284031215614da057600080fd5b614da8614a76565b905081358152614dba60208301614d64565b6020820152614dcb60408301614d37565b6040820152614ddc60608301614d64565b6060820152614ded608083016148e7565b6080820152614dfe60a0830161492d565b60a0820152614e0f60c08301614b12565b60c0820152614e2060e08301614b12565b60e0820152610100614e33818401614d82565b90820152610120614e45838201614d82565b90820152610140614e5783820161492d565b9082015292915050565b6000806000806000806102008789031215614e7b57600080fd5b863567ffffffffffffffff80821115614e9357600080fd5b614e9f8a838b01614c8f565b97506020890135915080821115614eb557600080fd5b50614ec289828a01614c8f565b9550506040870135614ed381614d1d565b93506060870135614ee381614d1d565b92506080870135614ef381614d42565b9150614f028860a08901614d8d565b90509295509295509295565b60078110614f45577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60408101614f578285614f0e565b6bffffffffffffffffffffffff831660208301529392505050565b600082601f830112614f8357600080fd5b81356020614f93614b6283614b1d565b82815260059290921b84018101918181019086841115614fb257600080fd5b8286015b84811015614baa578035614fc981614d42565b8352918301918301614fb6565b60008060408385031215614fe957600080fd5b823567ffffffffffffffff8082111561500157600080fd5b818501915085601f83011261501557600080fd5b81356020615025614b6283614b1d565b82815260059290921b8401810191818101908984111561504457600080fd5b948201945b8386101561506257853582529482019490820190615049565b9650508601359250508082111561507857600080fd5b5061508585828601614f72565b9150509250929050565b60008083601f8401126150a157600080fd5b50813567ffffffffffffffff8111156150b957600080fd5b6020830191508360208285010111156150d157600080fd5b9250929050565b60008060008060008060a087890312156150f157600080fd5b86356150fc816148d1565b9550602087013567ffffffffffffffff81111561511857600080fd5b61512489828a0161508f565b9096509450615137905060408801614ae9565b925060608701356151478161491b565b80925050608087013590509295509295509295565b6000806040838503121561516f57600080fd5b823561517a816148d1565b9150602083013561496681614d42565b6000806040838503121561519d57600080fd5b82356151a881614d42565b9150602083013561496681614d1d565b600080604083850312156151cb57600080fd5b82356151d681614d42565b91506020830135614966816148d1565b6000602082840312156151f857600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561524557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101615213565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a08401526152c260e08401826151ff565b905060a084015160c08401528091505092915050565b600080600080606085870312156152ee57600080fd5b84356152f981614d42565b935060208501359250604085013567ffffffffffffffff81111561531c57600080fd5b6153288782880161508f565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b8281101561536d57815184529284019290840190600101615351565b5050508381038285015261538181866151ff565b9695505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b80831015614baa57835163ffffffff16825292840192600192909201919084019061540f565b60006020828403121561544757600080fd5b813561491481614d42565b6000806020838503121561546557600080fd5b823567ffffffffffffffff8082111561547d57600080fd5b818501915085601f83011261549157600080fd5b8135818111156154a057600080fd5b866020610160830285010111156154b657600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016145426040830184614f0e565b8151815260208083015161016083019161555a9084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015161557a60408401826bffffffffffffffffffffffff169052565b5060608301516155a2606084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060808301516155be608084018267ffffffffffffffff169052565b5060a08301516155d660a084018263ffffffff169052565b5060c08301516155f360c084018268ffffffffffffffffff169052565b5060e083015161561060e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff8181168382160190808211156156a3576156a3615656565b5092915050565b6bffffffffffffffffffffffff81811683821602808216919082811461564e5761564e615656565b6bffffffffffffffffffffffff8181168382160190808211156156a3576156a3615656565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff861660208201526157316040820186614f0e565b60c06060820152600061574760c0830186614995565b82810360808401526157598186614995565b905082810360a084015261576d8185614995565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036157ab576157ab615656565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156156a3576156a3615656565b600060ff821660ff81036157ed576157ed615656565b60010192915050565b818103818111156115d9576115d9615656565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff80831681810361585557615855615656565b6001019392505050565b808201808211156115d9576115d9615656565b60006020828403121561588457600080fd5b5051919050565b6000610160828403121561589e57600080fd5b6149148383614d8d565b6000602082840312156158ba57600080fd5b8151801515811461491457600080fd5b67ffffffffffffffff8181168382160190808211156156a3576156a3615656565b8381526060602082015260006159046060830185614995565b82810360408401526153818185614995565b6020815260008251610160806020850152615935610180850183614995565b9150602085015160408501526040850151615968606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e08501516101006159df8187018363ffffffff169052565b86015190506101206159f68682018361ffff169052565b8601519050610140615a138682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b80516148f281614d42565b80516148f281614d1d565b80516148f2816148d1565b80516148f28161491b565b80516148f281614afb565b80516148f281614d6f565b60006101608284031215615a8e57600080fd5b615a96614a76565b82518152615aa660208401615a39565b6020820152615ab760408401615a44565b6040820152615ac860608401615a39565b6060820152615ad960808401615a4f565b6080820152615aea60a08401615a5a565b60a0820152615afb60c08401615a65565b60c0820152615b0c60e08401615a65565b60e0820152610100615b1f818501615a70565b90820152610120615b31848201615a70565b90820152610140615b43848201615a5a565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615b8f60e0830187614995565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006145426040830184614995565b60008251615c07818460208701614971565b919091019291505056fea164736f6c6343000813000a", } var FunctionsRouterABI = FunctionsRouterMetaData.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 9c10a5e77b8..9ba9e1ea565 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,10 +4,10 @@ functions_allow_list: ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfSer functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin c018c964cfb524b254ad26f078336108076c890837dd8eadab46e06283f46b71 +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin e7ccac9717c937a2a360a8de661178b4cceb7e3456fe56429009783549071941 functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin c8dbbd5ebb34435800d6674700068837c3a252db60046a14b0e61e829db517de functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c -functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin c7896ff5657bbfd5c48a61efec7e932ede3ad9a6a9e57195a46ba02ade31ccee +functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin 29b2dae67ffdbb7893e1e37ab5c3652f470bb4748827bba31c3b997c42b0e682 functions_v1_events_mock: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.bin 0f0ba42e0cc33c7abc8b8fd4fdfce903748a169886dd5f16cfdd56e75bcf708d ocr2dr: ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.bin d9a794b33f47cc57563d216f7cf3a612309fc3062356a27e30005cf1d59e449d ocr2dr_client: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.bin 84aa63f9dbc5c7eac240db699b09e613ca4c6cd56dab10bdc25b02461b717e21 From 1347424c6372d8bd00ac38426369009cfd510605 Mon Sep 17 00:00:00 2001 From: Cedric Date: Fri, 8 Sep 2023 11:14:02 +0100 Subject: [PATCH 62/88] WIP (#10542) --- .github/workflows/ci-core.yml | 2 +- tools/flakeytests/runner.go | 65 ++++++---- tools/flakeytests/runner_test.go | 197 ++++--------------------------- 3 files changed, 69 insertions(+), 195 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 7b0b5e36ad7..8dc29d5db77 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -289,7 +289,7 @@ jobs: -gh_sha=$GITHUB_SHA \ -gh_event_path=$GITHUB_EVENT_PATH \ -command=./tools/bin/go_core_tests \ - `ls -R ./artifacts/go_core_tests*/output-short.txt` + `ls -R ./artifacts/go_core_tests*/output.txt` - name: Store logs artifacts if: always() uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 diff --git a/tools/flakeytests/runner.go b/tools/flakeytests/runner.go index 592b673a23b..87777e85109 100644 --- a/tools/flakeytests/runner.go +++ b/tools/flakeytests/runner.go @@ -3,6 +3,7 @@ package flakeytests import ( "bufio" "bytes" + "encoding/json" "fmt" "io" "log" @@ -10,13 +11,11 @@ import ( "os/exec" "regexp" "strings" + "time" ) var ( - failedTestRe = regexp.MustCompile(`^--- FAIL: (Test\w+)`) - logPanicRe = regexp.MustCompile(`^panic: Log in goroutine after (Test\w+)`) - - failedPkgRe = regexp.MustCompile(`^FAIL\s+github\.com\/smartcontractkit\/chainlink\/v2\/(\S+)`) + panicRe = regexp.MustCompile(`^panic:`) ) type Runner struct { @@ -53,29 +52,55 @@ func runGoTest(pkg string, tests []string, numReruns int, w io.Writer) error { return cmd.Run() } +type TestEvent struct { + Time time.Time + Action string + Package string + Test string + Elapsed float64 // seconds + Output string +} + +func newEvent(b []byte) (*TestEvent, error) { + e := &TestEvent{} + err := json.Unmarshal(b, e) + if err != nil { + return nil, err + } + + e.Package = strings.Replace(e.Package, "github.com/smartcontractkit/chainlink/v2/", "", -1) + return e, nil + +} + func parseOutput(readers ...io.Reader) (map[string]map[string]int, error) { - testsWithoutPackage := []string{} tests := map[string]map[string]int{} for _, r := range readers { s := bufio.NewScanner(r) for s.Scan() { - t := s.Text() - switch { - case failedTestRe.MatchString(t): - m := failedTestRe.FindStringSubmatch(t) - testsWithoutPackage = append(testsWithoutPackage, m[1]) - case logPanicRe.MatchString(t): - m := logPanicRe.FindStringSubmatch(t) - testsWithoutPackage = append(testsWithoutPackage, m[1]) - case failedPkgRe.MatchString(t): - p := failedPkgRe.FindStringSubmatch(t) - for _, t := range testsWithoutPackage { - if tests[p[1]] == nil { - tests[p[1]] = map[string]int{} + t := s.Bytes() + if len(t) == 0 { + continue + } + + e, err := newEvent(t) + if err != nil { + return nil, err + } + + switch e.Action { + case "fail": + if tests[e.Package] == nil { + tests[e.Package] = map[string]int{} + } + tests[e.Package][e.Test]++ + case "output": + if panicRe.MatchString(e.Output) { + if tests[e.Package] == nil { + tests[e.Package] = map[string]int{} } - tests[p[1]][t]++ + tests[e.Package][e.Test]++ } - testsWithoutPackage = []string{} } } diff --git a/tools/flakeytests/runner_test.go b/tools/flakeytests/runner_test.go index 6560d43e2f9..63c7e7e3a68 100644 --- a/tools/flakeytests/runner_test.go +++ b/tools/flakeytests/runner_test.go @@ -23,25 +23,7 @@ func newMockReporter() *mockReporter { } func TestParser(t *testing.T) { - output := ` ---- FAIL: TestLink (0.00s) - --- FAIL: TestLink/1.1_link#01 (0.00s) - currencies_test.go:325: - Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325 - Error: Not equal: - expected: "1.2 link" - actual : "1.1 link" - - Diff: - --- Expected - +++ Actual - @@ -1 +1 @@ - -1.2 link - +1.1 link - Test: TestLink/1.1_link#01 -FAIL -FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s -FAIL + output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} ` r := strings.NewReader(output) @@ -53,65 +35,9 @@ FAIL assert.Equal(t, ts["core/assets"]["TestLink"], 1) } -func TestParser_PanicInTest(t *testing.T) { - output := ` -? github.com/smartcontractkit/chainlink/v2/tools/flakeytests/cmd/runner [no test files] ---- FAIL: TestParser (0.00s) -panic: foo [recovered] - panic: foo - -goroutine 21 [running]: -testing.tRunner.func1.2({0x1009953c0, 0x1009d1e40}) - /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1526 +0x1c8 -testing.tRunner.func1() - /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1529 +0x384 -panic({0x1009953c0, 0x1009d1e40}) - /opt/homebrew/Cellar/go/1.20.3/libexec/src/runtime/panic.go:884 +0x204 -github.com/smartcontractkit/chainlink/v2/tools/flakeytests.TestParser(0x0?) - /Users/ccordenier/Development/chainlink/tools/flakeytests/runner_test.go:50 +0xa4 -testing.tRunner(0x14000083520, 0x1009d1588) - /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1576 +0x10c -created by testing.(*T).Run - /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1629 +0x368 -FAIL github.com/smartcontractkit/chainlink/v2/tools/flakeytests 0.197s -FAIL` - - r := strings.NewReader(output) - ts, err := parseOutput(r) - require.NoError(t, err) - - assert.Len(t, ts, 1) - assert.Len(t, ts["tools/flakeytests"], 1) - assert.Equal(t, ts["tools/flakeytests"]["TestParser"], 1) -} - func TestParser_PanicDueToLogging(t *testing.T) { output := ` -panic: Log in goroutine after TestIntegration_LogEventProvider_Backfill has completed: 2023-07-19T10:10:45.925Z WARN KeepersRegistry.LogEventProvider logprovider/provider.go:218 failed to read logs {"version": "2.3.0@d898528", "where": "reader", "err": "fetched logs with errors: context canceled"} - -goroutine 4999 [running]: -testing.(*common).logDepth(0xc0051f6000, {0xc003011960, 0xd3}, 0x3) - /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1003 +0x4e7 -testing.(*common).log(...) - /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:985 -testing.(*common).Logf(0xc0051f6000, {0x21ba777?, 0x41ac8a?}, {0xc00217c330?, 0x1e530c0?, 0x1?}) - /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1036 +0x5a -go.uber.org/zap/zaptest.testingWriter.Write({{0x7f4c5c94f018?, 0xc0051f6000?}, 0xa8?}, {0xc003017000?, 0xd4, 0xc00217c320?}) - /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/zaptest/logger.go:130 +0xe6 -go.uber.org/zap/zapcore.(*ioCore).Write(0xc0022f60f0, {0x1, {0xc1260b897723e1ca, 0x4bdc75e54, 0x3d56e40}, {0x22e96a1, 0x20}, {0x22c3204, 0x13}, {0x1, ...}, ...}, ...) - /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/zapcore/core.go:99 +0xb5 -go.uber.org/zap/zapcore.(*CheckedEntry).Write(0xc001265ba0, {0xc0023ca100, 0x1, 0x2}) - /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/zapcore/entry.go:255 +0x1d9 -go.uber.org/zap.(*SugaredLogger).log(0xc00363a008, 0x1, {0x22c3204?, 0x13?}, {0x0?, 0x0?, 0x0?}, {0xc004ea3f80, 0x2, 0x2}) - /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/sugar.go:295 +0xee -go.uber.org/zap.(*SugaredLogger).Warnw(...) - /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/sugar.go:216 -github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider.(*logEventProvider).startReader(0xc00076d730, {0x2917018?, 0xc0043c4000?}, 0xc003b2a000) - /home/runner/work/chainlink/chainlink/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go:218 +0x29f -created by github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider.(*logEventProvider).Start - /home/runner/work/chainlink/chainlink/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go:108 +0x133 -FAIL github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider 20.380s -FAIL +{"Time":"2023-09-07T16:01:40.649849+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_LinkScanValue","Output":"panic: foo\n"} ` r := strings.NewReader(output) @@ -119,14 +45,24 @@ FAIL require.NoError(t, err) assert.Len(t, ts, 1) - assert.Len(t, ts["core/services/ocr2/plugins/ocr2keeper/evm21/logprovider"], 1) - assert.Equal(t, ts["core/services/ocr2/plugins/ocr2keeper/evm21/logprovider"]["TestIntegration_LogEventProvider_Backfill"], 1) + assert.Len(t, ts["core/assets"], 1) + assert.Equal(t, ts["core/assets"]["TestAssets_LinkScanValue"], 1) } func TestParser_SuccessfulOutput(t *testing.T) { output := ` -? github.com/smartcontractkit/chainlink/v2/tools/flakeytests/cmd/runner [no test files] -ok github.com/smartcontractkit/chainlink/v2/tools/flakeytests 0.320s +{"Time":"2023-09-07T16:22:52.556853+01:00","Action":"start","Package":"github.com/smartcontractkit/chainlink/v2/core/assets"} +{"Time":"2023-09-07T16:22:52.762353+01:00","Action":"run","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString"} +{"Time":"2023-09-07T16:22:52.762456+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"=== RUN TestAssets_NewLinkAndString\n"} +{"Time":"2023-09-07T16:22:52.76249+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"=== PAUSE TestAssets_NewLinkAndString\n"} +{"Time":"2023-09-07T16:22:52.7625+01:00","Action":"pause","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString"} +{"Time":"2023-09-07T16:22:52.762511+01:00","Action":"cont","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString"} +{"Time":"2023-09-07T16:22:52.762528+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"=== CONT TestAssets_NewLinkAndString\n"} +{"Time":"2023-09-07T16:22:52.762546+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"--- PASS: TestAssets_NewLinkAndString (0.00s)\n"} +{"Time":"2023-09-07T16:22:52.762557+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Elapsed":0} +{"Time":"2023-09-07T16:22:52.762566+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Output":"PASS\n"} +{"Time":"2023-09-07T16:22:52.762955+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Output":"ok \tgithub.com/smartcontractkit/chainlink/v2/core/assets\t0.206s\n"} +{"Time":"2023-09-07T16:22:52.765598+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Elapsed":0.209} ` r := strings.NewReader(output) @@ -136,26 +72,7 @@ ok github.com/smartcontractkit/chainlink/v2/tools/flakeytests 0.320s } func TestRunner_WithFlake(t *testing.T) { - output := ` ---- FAIL: TestLink (0.00s) - --- FAIL: TestLink/1.1_link#01 (0.00s) - currencies_test.go:325: - Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325 - Error: Not equal: - expected: "1.2 link" - actual : "1.1 link" - - Diff: - --- Expected - +++ Actual - @@ -1 +1 @@ - -1.2 link - +1.1 link - Test: TestLink/1.1_link#01 -FAIL -FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s -FAIL -` + output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` m := newMockReporter() r := &Runner{ numReruns: 2, @@ -177,61 +94,11 @@ FAIL } func TestRunner_AllFailures(t *testing.T) { - output := ` ---- FAIL: TestLink (0.00s) - --- FAIL: TestLink/1.1_link#01 (0.00s) - currencies_test.go:325: - Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325 - Error: Not equal: - expected: "1.2 link" - actual : "1.1 link" - - Diff: - --- Expected - +++ Actual - @@ -1 +1 @@ - -1.2 link - +1.1 link - Test: TestLink/1.1_link#01 -FAIL -FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s -FAIL -` + output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` rerunOutput := ` ---- FAIL: TestLink (0.00s) - --- FAIL: TestLink/1.1_link#01 (0.00s) - currencies_test.go:325: - Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325 - Error: Not equal: - expected: "1.2 link" - actual : "1.1 link" - - Diff: - --- Expected - +++ Actual - @@ -1 +1 @@ - -1.2 link - +1.1 link - Test: TestLink/1.1_link#01 ---- FAIL: TestLink (0.00s) - --- FAIL: TestLink/1.1_link#01 (0.00s) - currencies_test.go:325: - Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325 - Error: Not equal: - expected: "1.2 link" - actual : "1.1 link" - - Diff: - --- Expected - +++ Actual - @@ -1 +1 @@ - -1.2 link - +1.1 link - Test: TestLink/1.1_link#01 -FAIL -FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.315s -FAIL +{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} +{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} ` m := newMockReporter() r := &Runner{ @@ -251,29 +118,11 @@ FAIL } func TestRunner_RerunSuccessful(t *testing.T) { - output := ` ---- FAIL: TestLink (0.00s) - --- FAIL: TestLink/1.1_link#01 (0.00s) - currencies_test.go:325: - Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325 - Error: Not equal: - expected: "1.2 link" - actual : "1.1 link" - - Diff: - --- Expected - +++ Actual - @@ -1 +1 @@ - -1.2 link - +1.1 link - Test: TestLink/1.1_link#01 -FAIL -FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s -FAIL -` + output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` rerunOutput := ` -ok github.com/smartcontractkit/chainlink/v2/core/assets 0.320s +{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} +{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} ` m := newMockReporter() r := &Runner{ From b338b715fef32737122efb084082b03fa274b08f Mon Sep 17 00:00:00 2001 From: Ryan Hall Date: Fri, 8 Sep 2023 07:28:01 -0400 Subject: [PATCH 63/88] update log recoverer to update the block time periodically (#10544) * update log recoverer to update the block time periodically * add check for currentBlockTime > 0 --------- Co-authored-by: Akshay Aggarwal --- .../ocr2keeper/evm21/logprovider/recoverer.go | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go index 31de875d021..b1be71aad19 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "math" "math/big" "sort" "sync" @@ -38,6 +39,8 @@ var ( // recoveryLogsBuffer is the number of blocks to be used as a safety buffer when reading logs recoveryLogsBuffer = int64(200) recoveryLogsBurst = int64(500) + // blockTimeUpdateCadence is the cadence at which the chain's blocktime is re-calculated + blockTimeUpdateCadence = 10 * time.Minute ) type LogRecoverer interface { @@ -67,11 +70,12 @@ type logRecoverer struct { pending []ocr2keepers.UpkeepPayload visited map[string]visitedRecord - filterStore UpkeepFilterStore - states core.UpkeepStateReader - packer LogDataPacker - poller logpoller.LogPoller - client client.Client + filterStore UpkeepFilterStore + states core.UpkeepStateReader + packer LogDataPacker + poller logpoller.LogPoller + client client.Client + blockTimeResolver *blockTimeResolver } var _ LogRecoverer = &logRecoverer{} @@ -84,13 +88,14 @@ func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client clie lookbackBlocks: &atomic.Int64{}, interval: opts.ReadInterval * 5, - pending: make([]ocr2keepers.UpkeepPayload, 0), - visited: make(map[string]visitedRecord), - poller: poller, - filterStore: filterStore, - states: stateStore, - packer: packer, - client: client, + pending: make([]ocr2keepers.UpkeepPayload, 0), + visited: make(map[string]visitedRecord), + poller: poller, + filterStore: filterStore, + states: stateStore, + packer: packer, + client: client, + blockTimeResolver: newBlockTimeResolver(poller), } rec.lookbackBlocks.Store(opts.LookbackBlocks) @@ -111,35 +116,30 @@ func (r *logRecoverer) Start(pctx context.Context) error { r.cancel = cancel r.lock.Unlock() - blockTimeResolver := newBlockTimeResolver(r.poller) - blockTime, err := blockTimeResolver.BlockTime(ctx, defaultSampleSize) - if err != nil { - // TODO: TBD exit or just log a warning - // return fmt.Errorf("failed to compute block time: %w", err) - r.lggr.Warnw("failed to compute block time", "err", err) - } - if blockTime > 0 { - r.blockTime.Store(int64(blockTime)) - } + r.updateBlockTime(ctx) r.lggr.Infow("starting log recoverer", "blockTime", r.blockTime.Load(), "lookbackBlocks", r.lookbackBlocks.Load(), "interval", r.interval) { go func(ctx context.Context, interval time.Duration) { - ticker := time.NewTicker(interval) - defer ticker.Stop() + recoverTicker := time.NewTicker(interval) + defer recoverTicker.Stop() gcTicker := time.NewTicker(utils.WithJitter(GCInterval)) defer gcTicker.Stop() + blockTimeUpdateTicker := time.NewTicker(blockTimeUpdateCadence) + defer blockTimeUpdateTicker.Stop() for { select { - case <-ticker.C: + case <-recoverTicker.C: if err := r.recover(ctx); err != nil { r.lggr.Warnw("failed to recover logs", "err", err) } case <-gcTicker.C: r.clean(ctx) gcTicker.Reset(utils.WithJitter(GCInterval)) + case <-blockTimeUpdateTicker.C: + r.updateBlockTime(ctx) case <-ctx.Done(): return } @@ -650,3 +650,21 @@ func (r *logRecoverer) sortPending(latestBlock uint64) { return shuffledIDs[r.pending[i].WorkID] < shuffledIDs[r.pending[j].WorkID] }) } + +func (r *logRecoverer) updateBlockTime(ctx context.Context) { + blockTime, err := r.blockTimeResolver.BlockTime(ctx, defaultSampleSize) + if err != nil { + r.lggr.Warnw("failed to compute block time", "err", err) + return + } + if blockTime > 0 { + currentBlockTime := r.blockTime.Load() + newBlockTime := int64(blockTime) + if currentBlockTime > 0 && (int64(math.Abs(float64(currentBlockTime-newBlockTime)))*100/currentBlockTime) > 20 { + r.lggr.Warnf("updating blocktime from %d to %d, this change is larger than 20%", currentBlockTime, newBlockTime) + } else { + r.lggr.Debugf("updating blocktime from %d to %d", currentBlockTime, newBlockTime) + } + r.blockTime.Store(newBlockTime) + } +} From 0b1814dcb658999d145375b280ee53c76a8b4d6e Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Fri, 8 Sep 2023 16:51:52 +0300 Subject: [PATCH 64/88] add CI, refactor for more test groups (#10558) --- .../workflows/integration-staging-tests.yml | 63 +++++++++ integration-tests/load/functions/README.md | 40 ++++-- integration-tests/load/functions/config.go | 55 ++++++-- integration-tests/load/functions/config.toml | 48 ++++++- .../load/functions/functions_test.go | 132 +++++++++++++++++- integration-tests/load/functions/gateway.go | 62 ++++---- .../load/functions/gateway_gun.go | 13 +- .../load/functions/request_gun.go | 87 ++++++++++-- integration-tests/load/functions/setup.go | 16 ++- 9 files changed, 426 insertions(+), 90 deletions(-) create mode 100644 .github/workflows/integration-staging-tests.yml diff --git a/.github/workflows/integration-staging-tests.yml b/.github/workflows/integration-staging-tests.yml new file mode 100644 index 00000000000..7d2d0b66bdc --- /dev/null +++ b/.github/workflows/integration-staging-tests.yml @@ -0,0 +1,63 @@ +name: E2E Functions staging tests + +on: +# TODO: enable when env will be stable +# schedule: +# - cron: "0 0 * * *" + workflow_dispatch: + inputs: + network: + description: Blockchain network (testnet) + type: choice + default: "MUMBAI" + options: + - "MUMBAI" + test_type: + description: Test type + type: choice + default: "mumbai_functions_soak_test_real" + options: + - "mumbai_functions_soak_test_http" + - "mumbai_functions_stress_test_http" + - "mumbai_functions_soak_test_only_secrets" + - "mumbai_functions_stress_test_only_secrets" + - "mumbai_functions_soak_test_real" + - "mumbai_functions_stress_test_real" +# TODO: disabled, need GATI access +# - "gateway_secrets_set_soak_test" +# - "gateway_secrets_list_soak_test" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + e2e-soak-test: + environment: sdlc + runs-on: ubuntu20.04-8cores-32GB + permissions: + contents: read + id-token: write + env: + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_TOKEN: ${{ secrets.LOKI_TOKEN }} + + SELECTED_NETWORKS: ${{ inputs.network }} + SELECTED_TEST: ${{ inputs.test_type }} + MUMBAI_URLS: ${{ secrets.FUNCTIONS_STAGING_MUMBAI_URLS }} + MUMBAI_KEYS: ${{ secrets.FUNCTIONS_STAGING_MUMBAI_KEYS }} + + WASP_LOG_LEVEL: info + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Run E2E soak tests + run: | + cd integration-tests/load/functions + if [[ $SELECTED_TEST == mumbai_functions* ]]; then + go test -v -run TestFunctionsLoad/$SELECTED_TEST + elif [[ $SELECTED_TEST == gateway* ]]; then + go test -v -run TestGatewayLoad/$SELECTED_TEST + fi \ No newline at end of file diff --git a/integration-tests/load/functions/README.md b/integration-tests/load/functions/README.md index 6b80137cf48..d9eb9cc1ef3 100644 --- a/integration-tests/load/functions/README.md +++ b/integration-tests/load/functions/README.md @@ -13,21 +13,37 @@ See more config options in [config.toml](./config.toml) ## Usage -Soak `1 TX/sec - 40 requests per TX` -``` -go test -v -run TestFunctionsLoad/functions_soak_test -``` -Stress `1 TX/sec - 78 requests per TX` (max gas) -``` -go test -v -run TestFunctionsLoad/functions_stress_test -``` -Gateway `secrets_list` test +All tests are split by network and in 3 groups: +- HTTP payload only +- Secrets decoding payload only +- Realistic payload with args/http/secrets + +Load test client is [here](../../../contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol) + +Load is controlled with 2 params: +- RPS +- requests_per_call (generating more events in a loop in the contract) + +`Soak` is a stable workload for which there **must** be no issues + +`Stress` is a peak workload for which issues **must** be analyzed + +Load test client can execute `78 calls per request` at max (gas limit) + +Functions tests: ``` -go test -v -timeout 24h -run TestGatewayLoad/gateway_secrets_list_soak_test +go test -v -run TestFunctionsLoad/mumbai_functions_soak_test_http +go test -v -run TestFunctionsLoad/mumbai_functions_stress_test_http +go test -v -run TestFunctionsLoad/mumbai_functions_soak_test_only_secrets +go test -v -run TestFunctionsLoad/mumbai_functions_stress_test_only_secrets +go test -v -run TestFunctionsLoad/mumbai_functions_soak_test_real +go test -v -run TestFunctionsLoad/mumbai_functions_stress_test_real ``` -Gateway `secrets_set` test + +Gateway tests: ``` -go test -v -timeout 24h -run TestGatewayLoad/gateway_secrets_set_soak_test +go test -v -run TestGatewayLoad/gateway_secrets_list_soak_test +go test -v -run TestGatewayLoad/gateway_secrets_set_soak_test ``` Chaos suite can be combined with any test, can be found [here](../../chaos/functions/full.yaml) diff --git a/integration-tests/load/functions/config.go b/integration-tests/load/functions/config.go index b18549f460b..5c622401aba 100644 --- a/integration-tests/load/functions/config.go +++ b/integration-tests/load/functions/config.go @@ -18,7 +18,11 @@ const ( type PerformanceConfig struct { Soak *Soak `toml:"Soak"` + SecretsSoak *SecretsSoak `toml:"SecretsSoak"` + RealSoak *RealSoak `toml:"RealSoak"` Stress *Stress `toml:"Stress"` + SecretsStress *SecretsStress `toml:"SecretsStress"` + RealStress *RealStress `toml:"RealStress"` GatewayListSoak *GatewayListSoak `toml:"GatewayListSoak"` GatewaySetSoak *GatewaySetSoak `toml:"GatewaySetSoak"` Common *Common `toml:"Common"` @@ -27,18 +31,21 @@ type PerformanceConfig struct { type Common struct { Funding - LINKTokenAddr string `toml:"link_token_addr"` - Coordinator string `toml:"coordinator_addr"` - Router string `toml:"router_addr"` - LoadTestClient string `toml:"client_addr"` - SubscriptionID uint64 `toml:"subscription_id"` - DONID string `toml:"don_id"` - GatewayURL string `toml:"gateway_url"` - Receiver string `toml:"receiver"` - FunctionsCallPayload string `toml:"functions_call_payload"` - Secrets string `toml:"secrets"` - SecretsSlotID uint8 `toml:"secrets_slot_id"` - SecretsVersionID uint64 `toml:"secrets_version_id"` + LINKTokenAddr string `toml:"link_token_addr"` + Coordinator string `toml:"coordinator_addr"` + Router string `toml:"router_addr"` + LoadTestClient string `toml:"client_addr"` + SubscriptionID uint64 `toml:"subscription_id"` + DONID string `toml:"don_id"` + GatewayURL string `toml:"gateway_url"` + Receiver string `toml:"receiver"` + FunctionsCallPayloadHTTP string `toml:"functions_call_payload_http"` + FunctionsCallPayloadWithSecrets string `toml:"functions_call_payload_with_secrets"` + FunctionsCallPayloadReal string `toml:"functions_call_payload_real"` + SecretsSlotID uint8 `toml:"secrets_slot_id"` + SecretsVersionID uint64 `toml:"secrets_version_id"` + // Secrets these are for CI secrets + Secrets string `toml:"secrets"` } type Funding struct { @@ -52,12 +59,36 @@ type Soak struct { Duration *models.Duration `toml:"duration"` } +type SecretsSoak struct { + RPS int64 `toml:"rps"` + RequestsPerCall uint32 `toml:"requests_per_call"` + Duration *models.Duration `toml:"duration"` +} + +type RealSoak struct { + RPS int64 `toml:"rps"` + RequestsPerCall uint32 `toml:"requests_per_call"` + Duration *models.Duration `toml:"duration"` +} + type Stress struct { RPS int64 `toml:"rps"` RequestsPerCall uint32 `toml:"requests_per_call"` Duration *models.Duration `toml:"duration"` } +type SecretsStress struct { + RPS int64 `toml:"rps"` + RequestsPerCall uint32 `toml:"requests_per_call"` + Duration *models.Duration `toml:"duration"` +} + +type RealStress struct { + RPS int64 `toml:"rps"` + RequestsPerCall uint32 `toml:"requests_per_call"` + Duration *models.Duration `toml:"duration"` +} + type GatewayListSoak struct { RPS int64 `toml:"rps"` Duration *models.Duration `toml:"duration"` diff --git a/integration-tests/load/functions/config.toml b/integration-tests/load/functions/config.toml index f31342f0134..2de3ba9282c 100644 --- a/integration-tests/load/functions/config.toml +++ b/integration-tests/load/functions/config.toml @@ -8,6 +8,26 @@ rps = 1 requests_per_call = 78 duration = "10m" +[SecretsSoak] +rps = 1 +requests_per_call = 20 +duration = "10m" + +[SecretsStress] +rps = 1 +requests_per_call = 40 +duration = "10m" + +[RealSoak] +rps = 1 +requests_per_call = 20 +duration = "10m" + +[RealStress] +rps = 1 +requests_per_call = 40 +duration = "10m" + [GatewayListSoak] rps = 95 duration = "10m" @@ -20,18 +40,34 @@ duration = "10m" # Polygon Mumbai only for now receiver = "0x3098B6665589959711A48a6bAe5B7F2908f6a3bE" don_id = "fun-staging-mumbai-1" -gateway_url = "https://gateway-staging1.main.stage.cldev.sh" +gateway_url = "https://gateway-stg-one.main.stage.cldev.sh" link_token_addr = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB" coordinator_addr = "0x6D6a83BB356b7242E88C1A2b290102fde26590D0" router_addr = "0x2673266D3Cd08b53494B5a92B66DEec7F1408E7A" -# comment both client and sub to automatically create a new pair + +# comment "client_addr" and "subscription_id" and test will create a new pair +# get it from logs and save client_addr = "0x89D4b58D859a536D0B888ecD5093eF5FF9e4F977" subscription_id = 47 sub_funds = 10 -#functions_call_payload = "const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); return Functions.encodeUint256(response.data.id)" -functions_call_payload = "return Functions.encodeString(JSON.stringify(secrets))" +functions_call_payload_with_secrets = "return Functions.encodeString(JSON.stringify(secrets))" +functions_call_payload_http = """ +const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); +return Functions.encodeUint256(response.data.id); +""" +functions_call_payload_real = """ +const arg1 = args[0]; +const arg2 = args[1]; +const arg3 = args[2]; +const arg4 = args[3]; + +const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/${arg1}' }); +return Functions.encodeString(JSON.stringify(secrets)); +""" secrets_slot_id = 0 secrets_version = 1693945705 -# uncomment to upload new secrets to s4 -#secrets = "{\"ltsecret\": \"1\"}" \ No newline at end of file + +# uncomment to upload new secrets to s4 and use it in your run +# TODO: not working now +#secrets = "{\"secrets\": \"secretValue\"}" \ No newline at end of file diff --git a/integration-tests/load/functions/functions_test.go b/integration-tests/load/functions/functions_test.go index c178fcc5e21..7822035208e 100644 --- a/integration-tests/load/functions/functions_test.go +++ b/integration-tests/load/functions/functions_test.go @@ -21,7 +21,7 @@ func TestFunctionsLoad(t *testing.T) { MonitorLoadStats(t, ft, labels) - t.Run("functions soak test", func(t *testing.T) { + t.Run("mumbai functions soak test http", func(t *testing.T) { _, err := wasp.NewProfile(). Add(wasp.NewGenerator(&wasp.Config{ T: t, @@ -35,8 +35,9 @@ func TestFunctionsLoad(t *testing.T) { ), Gun: NewSingleFunctionCallGun( ft, + ModeHTTPPayload, cfg.Soak.RequestsPerCall, - cfg.Common.FunctionsCallPayload, + cfg.Common.FunctionsCallPayloadHTTP, cfg.Common.SecretsSlotID, cfg.Common.SecretsVersionID, []string{}, @@ -50,7 +51,7 @@ func TestFunctionsLoad(t *testing.T) { require.NoError(t, err) }) - t.Run("functions stress test", func(t *testing.T) { + t.Run("mumbai functions stress test http", func(t *testing.T) { _, err = wasp.NewProfile(). Add(wasp.NewGenerator(&wasp.Config{ T: t, @@ -64,8 +65,39 @@ func TestFunctionsLoad(t *testing.T) { ), Gun: NewSingleFunctionCallGun( ft, - cfg.Soak.RequestsPerCall, - cfg.Common.FunctionsCallPayload, + ModeHTTPPayload, + cfg.Stress.RequestsPerCall, + cfg.Common.FunctionsCallPayloadHTTP, + cfg.Common.SecretsSlotID, + cfg.Common.SecretsVersionID, + []string{}, + cfg.Common.SubscriptionID, + StringToByte32(cfg.Common.DONID), + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + })). + Run(true) + require.NoError(t, err) + }) + + t.Run("mumbai functions soak test only secrets", func(t *testing.T) { + _, err := wasp.NewProfile(). + Add(wasp.NewGenerator(&wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "functions_soak_gen", + RateLimitUnitDuration: 5 * time.Second, + CallTimeout: 3 * time.Minute, + Schedule: wasp.Plain( + cfg.SecretsSoak.RPS, + cfg.SecretsSoak.Duration.Duration(), + ), + Gun: NewSingleFunctionCallGun( + ft, + ModeSecretsOnlyPayload, + cfg.SecretsSoak.RequestsPerCall, + cfg.Common.FunctionsCallPayloadWithSecrets, cfg.Common.SecretsSlotID, cfg.Common.SecretsVersionID, []string{}, @@ -78,4 +110,94 @@ func TestFunctionsLoad(t *testing.T) { Run(true) require.NoError(t, err) }) + + t.Run("mumbai functions stress test only secrets", func(t *testing.T) { + _, err = wasp.NewProfile(). + Add(wasp.NewGenerator(&wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "functions_stress_gen", + RateLimitUnitDuration: 5 * time.Second, + CallTimeout: 3 * time.Minute, + Schedule: wasp.Plain( + cfg.SecretsStress.RPS, + cfg.SecretsStress.Duration.Duration(), + ), + Gun: NewSingleFunctionCallGun( + ft, + ModeSecretsOnlyPayload, + cfg.SecretsStress.RequestsPerCall, + cfg.Common.FunctionsCallPayloadWithSecrets, + cfg.Common.SecretsSlotID, + cfg.Common.SecretsVersionID, + []string{}, + cfg.Common.SubscriptionID, + StringToByte32(cfg.Common.DONID), + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + })). + Run(true) + require.NoError(t, err) + }) + + t.Run("mumbai functions soak test real", func(t *testing.T) { + _, err := wasp.NewProfile(). + Add(wasp.NewGenerator(&wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "functions_soak_gen", + RateLimitUnitDuration: 5 * time.Second, + CallTimeout: 3 * time.Minute, + Schedule: wasp.Plain( + cfg.RealSoak.RPS, + cfg.RealSoak.Duration.Duration(), + ), + Gun: NewSingleFunctionCallGun( + ft, + ModeReal, + cfg.RealSoak.RequestsPerCall, + cfg.Common.FunctionsCallPayloadReal, + cfg.Common.SecretsSlotID, + cfg.Common.SecretsVersionID, + []string{"1", "2", "3", "4"}, + cfg.Common.SubscriptionID, + StringToByte32(cfg.Common.DONID), + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + })). + Run(true) + require.NoError(t, err) + }) + + t.Run("mumbai functions stress test real", func(t *testing.T) { + _, err = wasp.NewProfile(). + Add(wasp.NewGenerator(&wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "functions_stress_gen", + RateLimitUnitDuration: 5 * time.Second, + CallTimeout: 3 * time.Minute, + Schedule: wasp.Plain( + cfg.RealStress.RPS, + cfg.RealStress.Duration.Duration(), + ), + Gun: NewSingleFunctionCallGun( + ft, + ModeReal, + cfg.RealStress.RequestsPerCall, + cfg.Common.FunctionsCallPayloadReal, + cfg.Common.SecretsSlotID, + cfg.Common.SecretsVersionID, + []string{"1", "2", "3", "4"}, + cfg.Common.SubscriptionID, + StringToByte32(cfg.Common.DONID), + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + })). + Run(true) + require.NoError(t, err) + }) } diff --git a/integration-tests/load/functions/gateway.go b/integration-tests/load/functions/gateway.go index 12406c79eb1..aefe4fbedc2 100644 --- a/integration-tests/load/functions/gateway.go +++ b/integration-tests/load/functions/gateway.go @@ -49,38 +49,36 @@ type RPCResponse struct { } `json:"result"` } -func UploadS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) error { +func UploadS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) (uint8, uint64, error) { key, err := crypto.HexToECDSA(s4Cfg.PrivateKey) if err != nil { - return err + return 0, 0, err } address := crypto.PubkeyToAddress(key.PublicKey) var payloadJSON []byte - if s4Cfg.Method == functions.MethodSecretsSet { - envelope := s4.Envelope{ - Address: address.Bytes(), - SlotID: s4Cfg.S4SetSlotID, - Version: s4Cfg.S4SetVersion, - Payload: []byte(s4Cfg.S4SetPayload), - Expiration: time.Now().UnixMilli() + s4Cfg.S4SetExpirationPeriod, - } - signature, err := envelope.Sign(key) - if err != nil { - return err - } + envelope := s4.Envelope{ + Address: address.Bytes(), + SlotID: s4Cfg.S4SetSlotID, + Version: s4Cfg.S4SetVersion, + Payload: []byte(s4Cfg.S4SetPayload), + Expiration: time.Now().UnixMilli() + s4Cfg.S4SetExpirationPeriod, + } + signature, err := envelope.Sign(key) + if err != nil { + return 0, 0, err + } - s4SetPayload := functions.SecretsSetRequest{ - SlotID: envelope.SlotID, - Version: envelope.Version, - Expiration: envelope.Expiration, - Payload: []byte(s4Cfg.S4SetPayload), - Signature: signature, - } + s4SetPayload := functions.SecretsSetRequest{ + SlotID: envelope.SlotID, + Version: envelope.Version, + Expiration: envelope.Expiration, + Payload: []byte(s4Cfg.S4SetPayload), + Signature: signature, + } - payloadJSON, err = json.Marshal(s4SetPayload) - if err != nil { - return err - } + payloadJSON, err = json.Marshal(s4SetPayload) + if err != nil { + return 0, 0, err } msg := &api.Message{ @@ -94,33 +92,33 @@ func UploadS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) error { err = msg.Sign(key) if err != nil { - return err + return 0, 0, err } codec := api.JsonRPCCodec{} rawMsg, err := codec.EncodeRequest(msg) if err != nil { - return err + return 0, 0, err } var result *RPCResponse resp, err := rc.R(). SetBody(rawMsg). Post(s4Cfg.GatewayURL) if err != nil { - return err + return 0, 0, err } if resp.StatusCode() != 200 { - return fmt.Errorf("status code was %d, expected 200", resp.StatusCode()) + return 0, 0, fmt.Errorf("status code was %d, expected 200", resp.StatusCode()) } if err := json.Unmarshal(resp.Body(), &result); err != nil { - return err + return 0, 0, err } log.Debug().Interface("Result", result).Msg("S4 secrets_set response result") for _, nodeResponse := range result.Result.Body.Payload.NodeResponses { if !nodeResponse.Body.Payload.Success { - return fmt.Errorf("node response was not succesful") + return 0, 0, fmt.Errorf("node response was not succesful") } } - return nil + return uint8(envelope.SlotID), envelope.Version, nil } func ListS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) error { diff --git a/integration-tests/load/functions/gateway_gun.go b/integration-tests/load/functions/gateway_gun.go index 5677e79b105..fd13922d0a7 100644 --- a/integration-tests/load/functions/gateway_gun.go +++ b/integration-tests/load/functions/gateway_gun.go @@ -36,7 +36,7 @@ func NewGatewaySecretsSetGun(cfg *PerformanceConfig, method string, pKey *ecdsa. } } -func callSetSecrets(m *GatewaySecretsSetGun) *wasp.CallResult { +func callSecretsSet(m *GatewaySecretsSetGun) *wasp.CallResult { randNum := strconv.Itoa(rand.Intn(100000)) randSlot := uint(rand.Intn(5)) version := uint64(time.Now().UnixNano()) @@ -58,8 +58,8 @@ func callSetSecrets(m *GatewaySecretsSetGun) *wasp.CallResult { if err != nil { return &wasp.CallResult{Error: err.Error(), Failed: true} } - if err := UploadS4Secrets(m.Resty, &S4SecretsCfg{ - GatewayURL: fmt.Sprintf("%s/user", m.Cfg.Common.GatewayURL), + _, _, err = UploadS4Secrets(m.Resty, &S4SecretsCfg{ + GatewayURL: m.Cfg.Common.GatewayURL, PrivateKey: os.Getenv("MUMBAI_KEYS"), MessageID: randNum, Method: "secrets_set", @@ -68,7 +68,8 @@ func callSetSecrets(m *GatewaySecretsSetGun) *wasp.CallResult { S4SetVersion: version, S4SetExpirationPeriod: expiration, S4SetPayload: secrets, - }); err != nil { + }) + if err != nil { return &wasp.CallResult{Error: err.Error(), Failed: true} } return &wasp.CallResult{} @@ -80,7 +81,7 @@ func callSecretsList(m *GatewaySecretsSetGun) *wasp.CallResult { version := uint64(time.Now().UnixNano()) expiration := int64(60 * 60 * 1000) if err := ListS4Secrets(m.Resty, &S4SecretsCfg{ - GatewayURL: fmt.Sprintf("%s/user", m.Cfg.Common.GatewayURL), + GatewayURL: fmt.Sprintf(m.Cfg.Common.GatewayURL), RecieverAddr: m.Cfg.Common.Receiver, PrivateKey: os.Getenv("MUMBAI_KEYS"), MessageID: randNum, @@ -100,7 +101,7 @@ func (m *GatewaySecretsSetGun) Call(_ *wasp.Generator) *wasp.CallResult { var res *wasp.CallResult switch m.Method { case "secrets_set": - res = callSetSecrets(m) + res = callSecretsSet(m) case "secrets_list": res = callSecretsList(m) default: diff --git a/integration-tests/load/functions/request_gun.go b/integration-tests/load/functions/request_gun.go index f939b2583ab..d9987eaa756 100644 --- a/integration-tests/load/functions/request_gun.go +++ b/integration-tests/load/functions/request_gun.go @@ -4,22 +4,41 @@ import ( "github.com/smartcontractkit/wasp" ) -/* SingleFunctionCallGun is a gun that constantly requests randomness for one feed */ +type TestMode int + +const ( + ModeHTTPPayload TestMode = iota + ModeSecretsOnlyPayload + ModeReal +) type SingleFunctionCallGun struct { - ft *FunctionsTest - times uint32 - source string - slotID uint8 - slotVersion uint64 - args []string - subscriptionId uint64 - jobId [32]byte + ft *FunctionsTest + mode TestMode + times uint32 + source string + slotID uint8 + slotVersion uint64 + encryptedSecrets []byte + args []string + subscriptionId uint64 + jobId [32]byte } -func NewSingleFunctionCallGun(ft *FunctionsTest, times uint32, source string, slotID uint8, slotVersion uint64, args []string, subscriptionId uint64, jobId [32]byte) *SingleFunctionCallGun { +func NewSingleFunctionCallGun( + ft *FunctionsTest, + mode TestMode, + times uint32, + source string, + slotID uint8, + slotVersion uint64, + args []string, + subscriptionId uint64, + jobId [32]byte, +) *SingleFunctionCallGun { return &SingleFunctionCallGun{ ft: ft, + mode: mode, times: times, source: source, slotID: slotID, @@ -30,8 +49,23 @@ func NewSingleFunctionCallGun(ft *FunctionsTest, times uint32, source string, sl } } -// Call implements example gun call, assertions on response bodies should be done here -func (m *SingleFunctionCallGun) Call(l *wasp.Generator) *wasp.CallResult { +func (m *SingleFunctionCallGun) callReal() *wasp.CallResult { + err := m.ft.LoadTestClient.SendRequestWithDONHostedSecrets( + m.times, + m.source, + m.slotID, + m.slotVersion, + m.args, + m.subscriptionId, + m.jobId, + ) + if err != nil { + return &wasp.CallResult{Error: err.Error(), Failed: true} + } + return &wasp.CallResult{} +} + +func (m *SingleFunctionCallGun) callWithSecrets() *wasp.CallResult { err := m.ft.LoadTestClient.SendRequestWithDONHostedSecrets( m.times, m.source, @@ -46,3 +80,32 @@ func (m *SingleFunctionCallGun) Call(l *wasp.Generator) *wasp.CallResult { } return &wasp.CallResult{} } + +func (m *SingleFunctionCallGun) callWithHttp() *wasp.CallResult { + err := m.ft.LoadTestClient.SendRequest( + m.times, + m.source, + []byte{}, + m.args, + m.subscriptionId, + m.jobId, + ) + if err != nil { + return &wasp.CallResult{Error: err.Error(), Failed: true} + } + return &wasp.CallResult{} +} + +// Call implements example gun call, assertions on response bodies should be done here +func (m *SingleFunctionCallGun) Call(_ *wasp.Generator) *wasp.CallResult { + switch m.mode { + case ModeSecretsOnlyPayload: + return m.callWithSecrets() + case ModeHTTPPayload: + return m.callWithHttp() + case ModeReal: + return m.callReal() + default: + panic("test mode must be ModeSecretsOnlyPayload, ModeHTTPPayload or ModeReal") + } +} diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go index 0433b5beb61..f30772c198c 100644 --- a/integration-tests/load/functions/setup.go +++ b/integration-tests/load/functions/setup.go @@ -2,7 +2,6 @@ package loadfunctions import ( "crypto/ecdsa" - "fmt" "github.com/ethereum/go-ethereum/crypto" "github.com/go-resty/resty/v2" "github.com/pkg/errors" @@ -115,7 +114,7 @@ func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*FunctionsTest, error) { if err != nil { return nil, errors.Wrap(err, "failed to get DON public key") } - log.Info().Hex("DONPublicKeyHex", donPubKey).Msg("Loaded coordinator keys") + log.Info().Hex("DONPublicKeyHex", donPubKey).Msg("Loaded DON key") tdh2pk, err := ParseTDH2Key(tpk) if err != nil { return nil, errors.Wrap(err, "failed to unmarshal tdh2 public key") @@ -126,8 +125,8 @@ func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*FunctionsTest, error) { if err != nil { return nil, errors.Wrap(err, "failed to generate tdh2 secrets") } - if err := UploadS4Secrets(resty.New(), &S4SecretsCfg{ - GatewayURL: fmt.Sprintf("%s/user", cfg.Common.GatewayURL), + slotID, slotVersion, err := UploadS4Secrets(resty.New(), &S4SecretsCfg{ + GatewayURL: cfg.Common.GatewayURL, PrivateKey: cfg.MumbaiPrivateKey, MessageID: strconv.Itoa(mrand.Intn(100000-1) + 1), Method: "secrets_set", @@ -136,9 +135,16 @@ func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*FunctionsTest, error) { S4SetVersion: uint64(time.Now().UnixNano()), S4SetExpirationPeriod: 60 * 60 * 1000, S4SetPayload: encryptedSecrets, - }); err != nil { + }) + if err != nil { return nil, errors.Wrap(err, "failed to upload secrets to S4") } + cfg.Common.SecretsSlotID = slotID + cfg.Common.SecretsVersionID = slotVersion + log.Info(). + Uint8("SlotID", slotID). + Uint64("SlotVersion", slotVersion). + Msg("Set new secret") } return &FunctionsTest{ EVMClient: bc, From 6daa8ff4b01f8adc0f4c37b9c298ec5dc18c926c Mon Sep 17 00:00:00 2001 From: Cedric Date: Fri, 8 Sep 2023 16:20:38 +0100 Subject: [PATCH 65/88] [BCF-2365] Consolidate *Provider Constructors into One (#10475) * [BCF-2365] Consolidate *Provider Constructors into One - Adapt the MercuryProvider so that it strictly extends the PluginProvider type. The additional functions in the MercuryTransmitter have moved to a separate MercuryServerFetcher component. - Introduce a wrapper relayerServerAdapter type which contains similar logic to the GRPC relayerServer, whose NewPluginProvider function returns a different provider type depending on the passed in ProviderType. - Replace uses of New{Mercury|Median|Functions}Provider with calls to NewPluginProvider with the correct ProviderType passed in. * Address review comment * Update go.mod/sum now that the commit has been merged --- core/chains/cosmos/relayer_adapter.go | 3 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/chainlink/relayer_factory.go | 6 +- core/services/job/job_orm_test.go | 3 +- core/services/job/models.go | 54 ++++-------- core/services/job/orm.go | 8 +- core/services/job/spawner_test.go | 2 +- core/services/ocr2/delegate.go | 28 +++--- core/services/ocr2/delegate_test.go | 11 +-- core/services/ocr2/plugins/median/services.go | 14 ++- core/services/ocr2/plugins/mercury/plugin.go | 6 +- .../plugins/ocr2keeper/integration_21_test.go | 5 +- .../plugins/ocr2keeper/integration_test.go | 6 +- .../ocr2vrf/coordinator/coordinator_test.go | 5 +- core/services/ocr2/validate/validate.go | 13 +-- core/services/ocrbootstrap/delegate.go | 3 +- core/services/relay/evm/loop_impl.go | 4 +- core/services/relay/evm/mercury_provider.go | 12 ++- .../relay/evm/mocks/loop_relay_adapter.go | 64 ++------------ core/services/relay/relay.go | 38 +++++++- core/services/relay/relay_test.go | 87 +++++++++++++++++++ core/store/migrate/migrate_test.go | 5 +- core/web/resolver/spec_test.go | 3 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- 28 files changed, 239 insertions(+), 159 deletions(-) diff --git a/core/chains/cosmos/relayer_adapter.go b/core/chains/cosmos/relayer_adapter.go index 899eae01951..ffe4181ceb0 100644 --- a/core/chains/cosmos/relayer_adapter.go +++ b/core/chains/cosmos/relayer_adapter.go @@ -37,8 +37,7 @@ type LoopRelayerChain struct { } func NewLoopRelayerChain(r *pkgcosmos.Relayer, s adapters.Chain) *LoopRelayerChain { - - ra := relay.NewRelayerAdapter(r, s) + ra := relay.NewRelayerServerAdapter(r, s) return &LoopRelayerChain{ Relayer: ra, chain: s, diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 7131bb1d437..68e623d4786 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -299,7 +299,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.20230831132059-42af68994512 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 641adcd89eb..7f3ed97110b 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1377,8 +1377,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-cosmos v0.4.1-0.20230831132059-42af68994512 h1:DojChlaudA1HAxwQPKmt/EDf36OUeFJ0LJBYClauMyU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 h1:yArUq/0t126bl8BRtjLCf2NuHK35CDIkhc3M5P46apc= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b h1:RrG9RuPfQi1Ak7/FdIEDlDpta2PSm5Dghmxpq2ZIO8M= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 6c09f5c4ab4..df7de835052 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -62,7 +62,7 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m if err != nil { return nil, err } - relayer := evmrelay.NewLoopRelayAdapter(evmrelay.NewRelayer(ccOpts.DB, chain, r.QConfig, ccOpts.Logger, config.CSAETHKeystore, ccOpts.EventBroadcaster), ext) + relayer := evmrelay.NewLoopRelayServerAdapter(evmrelay.NewRelayer(ccOpts.DB, chain, r.QConfig, ccOpts.Logger, config.CSAETHKeystore, ccOpts.EventBroadcaster), ext) relayers[relayID] = relayer } @@ -135,7 +135,7 @@ func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solana.SolanaCo if err != nil { return nil, err } - solanaRelayers[relayId] = relay.NewRelayerAdapter(pkgsolana.NewRelayer(solLggr, chain), chain) + solanaRelayers[relayId] = relay.NewRelayerServerAdapter(pkgsolana.NewRelayer(solLggr, chain), chain) } } return solanaRelayers, nil @@ -208,7 +208,7 @@ func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs starknet.St return nil, err } - starknetRelayers[relayId] = relay.NewRelayerAdapter(pkgstarknet.NewRelayer(starkLggr, chain), chain) + starknetRelayers[relayId] = relay.NewRelayerServerAdapter(pkgstarknet.NewRelayer(starkLggr, chain), chain) } } return starknetRelayers, nil diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index 1f5dba452fe..4fb8b767903 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/assets" @@ -911,7 +912,7 @@ func TestORM_ValidateKeyStoreMatch(t *testing.T) { }) t.Run("test Mercury ETH key validation", func(t *testing.T) { - jb.OCR2OracleSpec.PluginType = job.Mercury + jb.OCR2OracleSpec.PluginType = types.Mercury err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, "bad key") require.EqualError(t, err, "no CSA key matching: \"bad key\"") diff --git a/core/services/job/models.go b/core/services/job/models.go index d70afde12c2..8f9a2f529d3 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -14,6 +14,7 @@ import ( "github.com/pkg/errors" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/bridges" clnull "github.com/smartcontractkit/chainlink/v2/core/null" @@ -310,28 +311,7 @@ func (r JSONConfig) MercuryCredentialName() (string, error) { return name, nil } -var ForwardersSupportedPlugins = []OCR2PluginType{Median, DKG, OCR2VRF, OCR2Keeper, OCR2Functions} - -// OCR2PluginType defines supported OCR2 plugin types. -type OCR2PluginType string - -const ( - // Median refers to the median.Median type - Median OCR2PluginType = "median" - - DKG OCR2PluginType = "dkg" - - OCR2VRF OCR2PluginType = "ocr2vrf" - - // Keeper was rebranded to automation. For now the plugin type required in job spec points - // to the new name (automation) but in code we refer it to keepers - // TODO: sc-55296 to rename ocr2keeper to ocr2automation in code - OCR2Keeper OCR2PluginType = "ocr2automation" - - OCR2Functions OCR2PluginType = "functions" - - Mercury OCR2PluginType = "mercury" -) +var ForwardersSupportedPlugins = []types.OCR2PluginType{types.Median, types.DKG, types.OCR2VRF, types.OCR2Keeper, types.Functions} // OCR2OracleSpec defines the job spec for OCR2 jobs. // Relay config is chain specific config for a relay (chain adapter). @@ -341,21 +321,21 @@ type OCR2OracleSpec struct { FeedID *common.Hash `toml:"feedID"` Relay relay.Network `toml:"relay"` // TODO BCF-2442 implement ChainID as top level parameter rathe than buried in RelayConfig. - ChainID string `toml:"chainID"` - RelayConfig JSONConfig `toml:"relayConfig"` - P2PV2Bootstrappers pq.StringArray `toml:"p2pv2Bootstrappers"` - OCRKeyBundleID null.String `toml:"ocrKeyBundleID"` - MonitoringEndpoint null.String `toml:"monitoringEndpoint"` - TransmitterID null.String `toml:"transmitterID"` - BlockchainTimeout models.Interval `toml:"blockchainTimeout"` - ContractConfigTrackerPollInterval models.Interval `toml:"contractConfigTrackerPollInterval"` - ContractConfigConfirmations uint16 `toml:"contractConfigConfirmations"` - PluginConfig JSONConfig `toml:"pluginConfig"` - PluginType OCR2PluginType `toml:"pluginType"` - CreatedAt time.Time `toml:"-"` - UpdatedAt time.Time `toml:"-"` - CaptureEATelemetry bool `toml:"captureEATelemetry"` - CaptureAutomationCustomTelemetry bool `toml:"captureAutomationCustomTelemetry"` + ChainID string `toml:"chainID"` + RelayConfig JSONConfig `toml:"relayConfig"` + P2PV2Bootstrappers pq.StringArray `toml:"p2pv2Bootstrappers"` + OCRKeyBundleID null.String `toml:"ocrKeyBundleID"` + MonitoringEndpoint null.String `toml:"monitoringEndpoint"` + TransmitterID null.String `toml:"transmitterID"` + BlockchainTimeout models.Interval `toml:"blockchainTimeout"` + ContractConfigTrackerPollInterval models.Interval `toml:"contractConfigTrackerPollInterval"` + ContractConfigConfirmations uint16 `toml:"contractConfigConfirmations"` + PluginConfig JSONConfig `toml:"pluginConfig"` + PluginType types.OCR2PluginType `toml:"pluginType"` + CreatedAt time.Time `toml:"-"` + UpdatedAt time.Time `toml:"-"` + CaptureEATelemetry bool `toml:"captureEATelemetry"` + CaptureAutomationCustomTelemetry bool `toml:"captureAutomationCustomTelemetry"` } func (s *OCR2OracleSpec) RelayID() (relay.ID, error) { diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 277b03b24dd..d53452fa3bc 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -19,6 +19,8 @@ import ( "github.com/smartcontractkit/sqlx" + "github.com/smartcontractkit/chainlink-relay/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" @@ -268,7 +270,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { return errors.Errorf("forwarding is not currently supported for %s jobs", jb.OCR2OracleSpec.PluginType) } - if jb.OCR2OracleSpec.PluginType == Mercury { + if jb.OCR2OracleSpec.PluginType == types.Mercury { if jb.OCR2OracleSpec.FeedID == nil { return errors.New("feed ID is required for mercury plugin type") } @@ -278,7 +280,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } } - if jb.OCR2OracleSpec.PluginType == Median { + if jb.OCR2OracleSpec.PluginType == types.Median { var cfg medianconfig.PluginConfig err = json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &cfg) if err != nil { @@ -456,7 +458,7 @@ 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 == Mercury { + if spec.PluginType == types.Mercury { _, err := keyStore.CSA().Get(key) if err != nil { return errors.Errorf("no CSA key matching: %q", key) diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index f35aa50ba4d..efa252e4c4d 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -67,7 +67,7 @@ type relayGetter struct { } func (g *relayGetter) Get(id relay.ID) (loop.Relayer, error) { - return evmrelayer.NewLoopRelayAdapter(g.r, g.e), nil + return evmrelayer.NewLoopRelayServerAdapter(g.r, g.e), nil } func TestSpawner_CreateJobDeleteJob(t *testing.T) { diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 2a8fea38efe..6c7924e2fef 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -274,12 +274,12 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error var filters []string switch spec.PluginType { - case job.OCR2VRF: + case types.OCR2VRF: filters, err = ocr2coordinator.FilterNamesFromSpec(spec) if err != nil { d.lggr.Errorw("failed to derive ocr2vrf filter names from spec", "err", err, "spec", spec) } - case job.OCR2Keeper: + case types.OCR2Keeper: filters, err = ocr2keeper.FilterNamesFromSpec20(spec) if err != nil { d.lggr.Errorw("failed to derive ocr2keeper filter names from spec", "err", err, "spec", spec) @@ -405,22 +405,22 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC ctx := lggrCtx.ContextWithValues(context.Background()) switch spec.PluginType { - case job.Mercury: + case types.Mercury: return d.newServicesMercury(ctx, lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger) - case job.Median: + case types.Median: return d.newServicesMedian(ctx, lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger) - case job.DKG: + case types.DKG: return d.newServicesDKG(lggr, jb, bootstrapPeers, kb, ocrDB, lc, ocrLogger) - case job.OCR2VRF: + case types.OCR2VRF: return d.newServicesOCR2VRF(lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc) - case job.OCR2Keeper: + case types.OCR2Keeper: return d.newServicesOCR2Keepers(lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger) - case job.OCR2Functions: + case types.Functions: const ( _ int32 = iota thresholdPluginId @@ -437,7 +437,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC func GetEVMEffectiveTransmitterID(jb *job.Job, chain evm.Chain, lggr logger.SugaredLogger) (string, error) { spec := jb.OCR2OracleSpec - if spec.PluginType == job.Mercury { + if spec.PluginType == types.Mercury { return spec.TransmitterID.String, nil } @@ -448,7 +448,7 @@ func GetEVMEffectiveTransmitterID(jb *job.Job, chain evm.Chain, lggr logger.Suga if err != nil { return "", err } - if len(sendingKeys) > 1 && spec.PluginType != job.OCR2VRF { + if len(sendingKeys) > 1 && spec.PluginType != types.OCR2VRF { return "", errors.New("only ocr2 vrf should have more than 1 sending key") } spec.TransmitterID = null.StringFrom(sendingKeys[0]) @@ -514,13 +514,14 @@ func (d *Delegate) newServicesMercury( return nil, fmt.Errorf("mercury services: failed to get chain %s: %w", rid.ChainID, err) } - mercuryProvider, err2 := relayer.NewMercuryProvider(ctx, + provider, err2 := relayer.NewPluginProvider(ctx, types.RelayArgs{ ExternalJobID: jb.ExternalJobID, JobID: spec.ID, ContractID: spec.ContractID, New: d.isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(spec.PluginType), }, types.PluginArgs{ TransmitterID: transmitterID, PluginConfig: spec.PluginConfig.Bytes(), @@ -529,6 +530,11 @@ func (d *Delegate) newServicesMercury( return nil, err2 } + mercuryProvider, ok := provider.(types.MercuryProvider) + if !ok { + return nil, errors.New("could not coerce PluginProvider to MercuryProvider") + } + oracleArgsNoPlugin := libocr2.MercuryOracleArgs{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, diff --git a/core/services/ocr2/delegate_test.go b/core/services/ocr2/delegate_test.go index e78af2e19b4..97c9faa44d4 100644 --- a/core/services/ocr2/delegate_test.go +++ b/core/services/ocr2/delegate_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-relay/pkg/types" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -49,7 +50,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { type testCase struct { name string - pluginType job.OCR2PluginType + pluginType types.OCR2PluginType transmitterID null.String sendingKeys []any expectedError bool @@ -75,7 +76,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { testCases := []testCase{ { name: "mercury plugin should just return transmitterID", - pluginType: job.Mercury, + pluginType: types.Mercury, transmitterID: null.StringFrom("Mercury transmitterID"), expectedTransmitterID: "Mercury transmitterID", }, @@ -91,7 +92,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { }, { name: "when transmitterID is not defined and plugin is ocr2vrf, it should allow>1 sendingKeys and set transmitterID to the first one", - pluginType: job.OCR2VRF, + pluginType: types.OCR2VRF, sendingKeys: []any{"0x7e57000000000000000000000000000000000000", "0x7e57000000000000000000000000000000000001", "0x7e57000000000000000000000000000000000002"}, expectedTransmitterID: "0x7e57000000000000000000000000000000000000", }, @@ -109,7 +110,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { }, { name: "when forwarders are enabled and when transmitterID is not defined, it should use first sendingKey to retrieve forwarder address", - pluginType: job.OCR2VRF, + pluginType: types.OCR2VRF, forwardingEnabled: true, sendingKeys: []any{"0x7e57000000000000000000000000000000000001", "0x7e57000000000000000000000000000000000002"}, getForwarderForEOAArg: common.HexToAddress("0x7e57000000000000000000000000000000000001"), @@ -117,7 +118,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { }, { name: "when forwarders are enabled but forwarder address fails to be retrieved and when transmitterID is not defined, it should default to using first sendingKey", - pluginType: job.OCR2VRF, + pluginType: types.OCR2VRF, forwardingEnabled: true, sendingKeys: []any{"0x7e57000000000000000000000000000000000001", "0x7e57000000000000000000000000000000000002"}, getForwarderForEOAArg: common.HexToAddress("0x7e57000000000000000000000000000000000001"), diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go index 8ff97c2cc56..e435ee747f5 100644 --- a/core/services/ocr2/plugins/median/services.go +++ b/core/services/ocr2/plugins/median/services.go @@ -3,6 +3,7 @@ package median import ( "context" "encoding/json" + "errors" "fmt" "time" @@ -67,12 +68,13 @@ func NewMedianServices(ctx context.Context, } spec := jb.OCR2OracleSpec - provider, err := relayer.NewMedianProvider(ctx, types.RelayArgs{ + provider, err := relayer.NewPluginProvider(ctx, types.RelayArgs{ ExternalJobID: jb.ExternalJobID, JobID: spec.ID, ContractID: spec.ContractID, New: isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(spec.PluginType), }, types.PluginArgs{ TransmitterID: spec.TransmitterID.String, PluginConfig: spec.PluginConfig.Bytes(), @@ -80,6 +82,12 @@ func NewMedianServices(ctx context.Context, if err != nil { return } + + medianProvider, ok := provider.(types.MedianProvider) + if !ok { + return nil, errors.New("could not coerce PluginProvider to MedianProvider") + } + srvs = append(srvs, provider) argsNoPlugin.ContractTransmitter = provider.ContractTransmitter() argsNoPlugin.ContractConfigTracker = provider.ContractConfigTracker() @@ -113,11 +121,11 @@ func NewMedianServices(ctx context.Context, abort() return } - median := loop.NewMedianService(lggr, telem, cmdFn, provider, dataSource, juelsPerFeeCoinSource, errorLog) + median := loop.NewMedianService(lggr, telem, cmdFn, medianProvider, dataSource, juelsPerFeeCoinSource, errorLog) argsNoPlugin.ReportingPluginFactory = median srvs = append(srvs, median) } else { - argsNoPlugin.ReportingPluginFactory, err = NewPlugin(lggr).NewMedianFactory(ctx, provider, dataSource, juelsPerFeeCoinSource, errorLog) + argsNoPlugin.ReportingPluginFactory, err = NewPlugin(lggr).NewMedianFactory(ctx, medianProvider, dataSource, juelsPerFeeCoinSource, errorLog) if err != nil { err = fmt.Errorf("failed to create median factory: %w", err) abort() diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index 64336548a1e..05e7e968f8b 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -67,7 +67,7 @@ func NewServices( runResults, chEnhancedTelem, chainHeadTracker, - ocr2Provider.ContractTransmitter(), + ocr2Provider.MercuryServerFetcher(), pluginConfig.InitialBlockNumber.Ptr(), feedID, ) @@ -87,7 +87,7 @@ func NewServices( lggr, runResults, chEnhancedTelem, - ocr2Provider.ContractTransmitter(), + ocr2Provider.MercuryServerFetcher(), *pluginConfig.LinkFeedID, *pluginConfig.NativeFeedID, ) @@ -107,7 +107,7 @@ func NewServices( lggr, runResults, chEnhancedTelem, - ocr2Provider.ContractTransmitter(), + ocr2Provider.MercuryServerFetcher(), *pluginConfig.LinkFeedID, *pluginConfig.NativeFeedID, ) diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go index 6ce8b0aa8cf..7d69ea6522d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go @@ -29,6 +29,7 @@ import ( "github.com/stretchr/testify/require" "github.com/umbracle/ethgo/abi" + relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic" @@ -57,7 +58,7 @@ func TestFilterNamesFromSpec21(t *testing.T) { address := common.HexToAddress(hexutil.Encode(b)) spec := &job.OCR2OracleSpec{ - PluginType: job.OCR2Keeper, + PluginType: relaytypes.OCR2Keeper, ContractID: address.String(), // valid contract addr } @@ -69,7 +70,7 @@ func TestFilterNamesFromSpec21(t *testing.T) { assert.Equal(t, logpoller.FilterName("KeeperRegistry Events", address), names[1]) spec = &job.OCR2OracleSpec{ - PluginType: job.OCR2Keeper, + PluginType: relaytypes.OCR2Keeper, ContractID: "0x5431", // invalid contract addr } _, err = ocr2keeper.FilterNamesFromSpec21(spec) diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_test.go index 8b7e92c40fe..9d53b4cab32 100644 --- a/core/services/ocr2/plugins/ocr2keeper/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/integration_test.go @@ -56,6 +56,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" + + relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" ) const ( @@ -705,7 +707,7 @@ func TestFilterNamesFromSpec20(t *testing.T) { address := common.HexToAddress(hexutil.Encode(b)) spec := &job.OCR2OracleSpec{ - PluginType: job.OCR2Keeper, + PluginType: relaytypes.OCR2Keeper, ContractID: address.String(), // valid contract addr } @@ -717,7 +719,7 @@ func TestFilterNamesFromSpec20(t *testing.T) { assert.Equal(t, logpoller.FilterName("EvmRegistry - Upkeep events for", address), names[1]) spec = &job.OCR2OracleSpec{ - PluginType: job.OCR2Keeper, + PluginType: relaytypes.OCR2Keeper, ContractID: "0x5431", // invalid contract addr } _, err = ocr2keeper.FilterNamesFromSpec20(spec) diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go index 5a32644d0ee..1222ab7b2a4 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go @@ -25,6 +25,7 @@ import ( "github.com/smartcontractkit/ocr2vrf/ocr2vrf" ocr2vrftypes "github.com/smartcontractkit/ocr2vrf/types" + relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" lp_mocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" @@ -1761,7 +1762,7 @@ func TestFilterNamesFromSpec(t *testing.T) { spec := &job.OCR2OracleSpec{ ContractID: beaconAddress.String(), - PluginType: job.OCR2VRF, + PluginType: relaytypes.OCR2VRF, PluginConfig: job.JSONConfig{ "VRFCoordinatorAddress": coordinatorAddress.String(), "DKGContractAddress": dkgAddress.String(), @@ -1775,7 +1776,7 @@ func TestFilterNamesFromSpec(t *testing.T) { assert.Equal(t, logpoller.FilterName("VRF Coordinator", beaconAddress, coordinatorAddress, dkgAddress), names[0]) spec = &job.OCR2OracleSpec{ - PluginType: job.OCR2VRF, + PluginType: relaytypes.OCR2VRF, ContractID: beaconAddress.String(), PluginConfig: nil, // missing coordinator & dkg addresses } diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index ca1ab60deb9..cde1a1f9276 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -12,6 +12,7 @@ import ( libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" + "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/job" dkgconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/config" mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" @@ -98,20 +99,20 @@ func validateSpec(tree *toml.Tree, spec job.Job) error { } switch spec.OCR2OracleSpec.PluginType { - case job.Median: + case types.Median: if spec.Pipeline.Source == "" { return errors.New("no pipeline specified") } - case job.DKG: + case types.DKG: return validateDKGSpec(spec.OCR2OracleSpec.PluginConfig) - case job.OCR2VRF: + case types.OCR2VRF: return validateOCR2VRFSpec(spec.OCR2OracleSpec.PluginConfig) - case job.OCR2Keeper: + case types.OCR2Keeper: return validateOCR2KeeperSpec(spec.OCR2OracleSpec.PluginConfig) - case job.OCR2Functions: + case types.Functions: // TODO validator for DR-OCR spec: https://app.shortcut.com/chainlinklabs/story/54054/ocr-plugin-for-directrequest-ocr return nil - case job.Mercury: + case types.Mercury: return validateOCR2MercurySpec(spec.OCR2OracleSpec.PluginConfig, *spec.OCR2OracleSpec.FeedID) case "": return errors.New("no plugin specified") diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index b39f9eec6ec..d530797367f 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -118,7 +118,7 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services if routerFields.ContractVersion != 1 || routerFields.ContractUpdateCheckFrequencySec == 0 { return nil, errors.New("invalid router contract config") } - configProvider, err = relayer.NewFunctionsProvider( + configProvider, err = relayer.NewPluginProvider( ctx, types.RelayArgs{ ExternalJobID: jobSpec.ExternalJobID, @@ -126,6 +126,7 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services ContractID: spec.ContractID, RelayConfig: spec.RelayConfig.Bytes(), New: d.isNewlyCreatedJob, + ProviderType: string(types.Functions), }, types.PluginArgs{ PluginConfig: spec.RelayConfig.Bytes(), // contains all necessary fields for config provider diff --git a/core/services/relay/evm/loop_impl.go b/core/services/relay/evm/loop_impl.go index 02a9194b380..87f7aed1a55 100644 --- a/core/services/relay/evm/loop_impl.go +++ b/core/services/relay/evm/loop_impl.go @@ -19,8 +19,8 @@ type LoopRelayer struct { var _ loop.Relayer = &LoopRelayer{} -func NewLoopRelayAdapter(r *Relayer, cs EVMChainRelayerExtender) *LoopRelayer { - ra := relay.NewRelayerAdapter(r, cs) +func NewLoopRelayServerAdapter(r *Relayer, cs EVMChainRelayerExtender) *LoopRelayer { + ra := relay.NewRelayerServerAdapter(r, cs) return &LoopRelayer{ Relayer: ra, ext: cs, diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go index ee32b8d99be..74072167061 100644 --- a/core/services/relay/evm/mercury_provider.go +++ b/core/services/relay/evm/mercury_provider.go @@ -4,13 +4,15 @@ import ( "context" "errors" + "golang.org/x/exp/maps" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" relaymercuryv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2" relaymercuryv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "golang.org/x/exp/maps" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" @@ -96,6 +98,10 @@ func (p *mercuryProvider) ReportCodecV3() relaymercuryv3.ReportCodec { return p.reportCodecV3 } -func (p *mercuryProvider) ContractTransmitter() relaymercury.Transmitter { +func (p *mercuryProvider) ContractTransmitter() ocrtypes.ContractTransmitter { + return p.transmitter +} + +func (p *mercuryProvider) MercuryServerFetcher() relaymercury.MercuryServerFetcher { return p.transmitter } diff --git a/core/services/relay/evm/mocks/loop_relay_adapter.go b/core/services/relay/evm/mocks/loop_relay_adapter.go index 7ed28ac4b11..02064c2ea9f 100644 --- a/core/services/relay/evm/mocks/loop_relay_adapter.go +++ b/core/services/relay/evm/mocks/loop_relay_adapter.go @@ -181,72 +181,20 @@ func (_m *LoopRelayAdapter) NewConfigProvider(_a0 context.Context, _a1 types.Rel return r0, r1 } -// NewFunctionsProvider provides a mock function with given fields: _a0, _a1, _a2 -func (_m *LoopRelayAdapter) NewFunctionsProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.FunctionsProvider, error) { +// NewPluginProvider provides a mock function with given fields: _a0, _a1, _a2 +func (_m *LoopRelayAdapter) NewPluginProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.PluginProvider, error) { ret := _m.Called(_a0, _a1, _a2) - var r0 types.FunctionsProvider + var r0 types.PluginProvider var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.FunctionsProvider, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.PluginProvider, error)); ok { return rf(_a0, _a1, _a2) } - if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.FunctionsProvider); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.PluginProvider); ok { r0 = rf(_a0, _a1, _a2) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.FunctionsProvider) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs, types.PluginArgs) error); ok { - r1 = rf(_a0, _a1, _a2) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewMedianProvider provides a mock function with given fields: _a0, _a1, _a2 -func (_m *LoopRelayAdapter) NewMedianProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.MedianProvider, error) { - ret := _m.Called(_a0, _a1, _a2) - - var r0 types.MedianProvider - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.MedianProvider, error)); ok { - return rf(_a0, _a1, _a2) - } - if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.MedianProvider); ok { - r0 = rf(_a0, _a1, _a2) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(types.MedianProvider) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs, types.PluginArgs) error); ok { - r1 = rf(_a0, _a1, _a2) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewMercuryProvider provides a mock function with given fields: _a0, _a1, _a2 -func (_m *LoopRelayAdapter) NewMercuryProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.MercuryProvider, error) { - ret := _m.Called(_a0, _a1, _a2) - - var r0 types.MercuryProvider - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.MercuryProvider, error)); ok { - return rf(_a0, _a1, _a2) - } - if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.MercuryProvider); ok { - r0 = rf(_a0, _a1, _a2) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(types.MercuryProvider) + r0 = ret.Get(0).(types.PluginProvider) } } diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go index fccd69c411e..5e8f065f289 100644 --- a/core/services/relay/relay.go +++ b/core/services/relay/relay.go @@ -112,12 +112,12 @@ var _ loop.Relayer = (*relayerAdapter)(nil) // relayerAdapter adapts a [types.Relayer] and [RelayerExt] to implement [loop.Relayer]. type relayerAdapter struct { types.Relayer - // TODO we can un-embedded `ext` once BFC-2441 is merged. Right now that's not possible - // because this are conflicting definitions of SendTx RelayerExt } // NewRelayerAdapter returns a [loop.Relayer] adapted from a [types.Relayer] and [RelayerExt]. +// Unlike NewRelayerServerAdapter which is used to adapt non-LOOPP relayers, this is used to adapt +// LOOPP-based relayer which are then server over GRPC (by the relayerServer). func NewRelayerAdapter(r types.Relayer, e RelayerExt) loop.Relayer { return &relayerAdapter{Relayer: r, RelayerExt: e} } @@ -138,6 +138,10 @@ func (r *relayerAdapter) NewFunctionsProvider(ctx context.Context, rargs types.R return r.Relayer.NewFunctionsProvider(rargs, pargs) } +func (r *relayerAdapter) NewPluginProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) { + return nil, fmt.Errorf("unexpected call to NewPluginProvider: did you forget to wrap relayerAdapter in a relayerServerAdapter?") +} + func (r *relayerAdapter) Start(ctx context.Context) error { var ms services.MultiStart return ms.Start(ctx, r.RelayerExt, r.Relayer) @@ -184,3 +188,33 @@ func (r *relayerAdapter) NodeStatuses(ctx context.Context, offset, limit int, ch } return nodes[offset:limit], total, nil } + +type relayerServerAdapter struct { + *relayerAdapter +} + +func (r *relayerServerAdapter) NewPluginProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) { + switch types.OCR2PluginType(rargs.ProviderType) { + case types.Median: + return r.NewMedianProvider(ctx, rargs, pargs) + case types.Functions: + return r.NewFunctionsProvider(ctx, rargs, pargs) + case types.Mercury: + return r.NewMercuryProvider(ctx, rargs, pargs) + case types.DKG, types.OCR2VRF, types.OCR2Keeper, types.GenericPlugin: + return r.relayerAdapter.NewPluginProvider(ctx, rargs, pargs) + } + + return nil, fmt.Errorf("provider type not supported: %s", rargs.ProviderType) +} + +// NewRelayerServerAdapter returns a [loop.Relayer] adapted from a [types.Relayer] and [RelayerExt]. +// Unlike NewRelayerAdapter, this behaves like the loop `RelayerServer` and dispatches calls +// to `NewPluginProvider` according to the passed in `RelayArgs.ProviderType`. +// This should only be used to adapt relayers not running via GRPC in a LOOPP. +// +// nolint:staticcheck // SA1019 +func NewRelayerServerAdapter(r types.Relayer, e RelayerExt) loop.Relayer { + ra := &relayerAdapter{Relayer: r, RelayerExt: e} + return &relayerServerAdapter{relayerAdapter: ra} +} diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go index 0ed14b6c5b7..1180379677e 100644 --- a/core/services/relay/relay_test.go +++ b/core/services/relay/relay_test.go @@ -1,9 +1,12 @@ package relay import ( + "context" "testing" "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-relay/pkg/types" ) func TestIdentifier_UnmarshalString(t *testing.T) { @@ -79,3 +82,87 @@ func TestNewID(t *testing.T) { }) } } + +type staticMedianProvider struct { + types.MedianProvider +} + +type staticFunctionsProvider struct { + types.FunctionsProvider +} + +type staticMercuryProvider struct { + types.MercuryProvider +} + +type mockRelayer struct { + types.Relayer +} + +func (m *mockRelayer) NewMedianProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MedianProvider, error) { + return staticMedianProvider{}, nil +} + +func (m *mockRelayer) NewFunctionsProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.FunctionsProvider, error) { + return staticFunctionsProvider{}, nil +} + +func (m *mockRelayer) NewMercuryProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MercuryProvider, error) { + return staticMercuryProvider{}, nil +} + +type mockRelayerExt struct { + RelayerExt +} + +func isType[T any](p any) bool { + _, ok := p.(T) + return ok +} + +func TestRelayerServerAdapter(t *testing.T) { + r := &mockRelayer{} + sa := NewRelayerServerAdapter(r, mockRelayerExt{}) + + testCases := []struct { + ProviderType string + Test func(p any) bool + Error string + }{ + { + ProviderType: string(types.Median), + Test: isType[types.MedianProvider], + }, + { + ProviderType: string(types.Functions), + Test: isType[types.FunctionsProvider], + }, + { + ProviderType: string(types.Mercury), + Test: isType[types.MercuryProvider], + }, + { + ProviderType: "unknown", + Error: "provider type not supported", + }, + { + ProviderType: string(types.GenericPlugin), + Error: "unexpected call to NewPluginProvider", + }, + } + + for _, tc := range testCases { + pp, err := sa.NewPluginProvider( + context.Background(), + types.RelayArgs{ProviderType: tc.ProviderType}, + types.PluginArgs{}, + ) + + if tc.Error != "" { + assert.ErrorContains(t, err, tc.Error) + } else { + assert.NoError(t, err) + assert.True(t, tc.Test(pp)) + } + } +} diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go index 97d0ec5b182..66764a266f0 100644 --- a/core/store/migrate/migrate_test.go +++ b/core/store/migrate/migrate_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -350,7 +351,7 @@ func TestMigrate_101_GenericOCR2(t *testing.T) { require.NoError(t, err) type PluginValues struct { - PluginType job.OCR2PluginType + PluginType types.OCR2PluginType PluginConfig job.JSONConfig } @@ -360,7 +361,7 @@ func TestMigrate_101_GenericOCR2(t *testing.T) { err = db.Get(&pluginValues, sql) require.NoError(t, err) - require.Equal(t, job.Median, pluginValues.PluginType) + require.Equal(t, types.Median, pluginValues.PluginType) require.Equal(t, job.JSONConfig{"juelsPerFeeCoinSource": spec.JuelsPerFeeCoinPipeline}, pluginValues.PluginConfig) err = goose.Down(db.DB, migrationDir) diff --git a/core/web/resolver/spec_test.go b/core/web/resolver/spec_test.go index 8c6dadc880e..c4efbb65825 100644 --- a/core/web/resolver/spec_test.go +++ b/core/web/resolver/spec_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/assets" clnull "github.com/smartcontractkit/chainlink/v2/core/null" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -515,7 +516,7 @@ func TestResolver_OCR2Spec(t *testing.T) { Relay: relay.EVM, RelayConfig: relayConfig, TransmitterID: null.StringFrom(transmitterAddress.String()), - PluginType: job.Median, + PluginType: types.Median, PluginConfig: pluginConfig, }, }, nil) diff --git a/go.mod b/go.mod index 19efff0277c..64560eb08fe 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-cosmos v0.4.1-0.20230831132059-42af68994512 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 diff --git a/go.sum b/go.sum index 57938ebab7d..f434c6fc492 100644 --- a/go.sum +++ b/go.sum @@ -1377,8 +1377,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-cosmos v0.4.1-0.20230831132059-42af68994512 h1:DojChlaudA1HAxwQPKmt/EDf36OUeFJ0LJBYClauMyU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 h1:yArUq/0t126bl8BRtjLCf2NuHK35CDIkhc3M5P46apc= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b h1:RrG9RuPfQi1Ak7/FdIEDlDpta2PSm5Dghmxpq2ZIO8M= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 1b1b3940ccf..8fda4ca62dd 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -384,7 +384,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.20230831132059-42af68994512 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 2e77b16fe09..4d57db530fc 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2252,8 +2252,8 @@ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af6899451 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= github.com/smartcontractkit/chainlink-env v0.36.0 h1:CFOjs0c0y3lrHi/fl5qseCH9EQa5W/6CFyOvmhe2VnA= github.com/smartcontractkit/chainlink-env v0.36.0/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4 h1:yArUq/0t126bl8BRtjLCf2NuHK35CDIkhc3M5P46apc= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230905185157-da01915913a4/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b h1:RrG9RuPfQi1Ak7/FdIEDlDpta2PSm5Dghmxpq2ZIO8M= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= From 47ef2265c1228d50e890ef7c0706c6da4bd3302d Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 8 Sep 2023 11:51:16 -0400 Subject: [PATCH 66/88] Retrieve native/LINK fee directly from report (#10539) * Retrieve native/LINK fee directly from report - Fixes: MERC-1635 * Fix lint --- .../ocr2/plugins/mercury/helpers_test.go | 38 ++++++----- .../ocr2/plugins/mercury/integration_test.go | 31 +++++++-- core/services/relay/evm/evm.go | 30 ++++++--- .../services/relay/evm/mercury/transmitter.go | 27 +++++--- .../relay/evm/mercury/transmitter_test.go | 66 +++++++++++++------ .../services/relay/evm/mercury/types/types.go | 7 ++ .../mercury/v1/reportcodec/report_codec.go | 9 +++ .../v1/reportcodec/report_codec_test.go | 19 ++++++ .../mercury/v2/reportcodec/report_codec.go | 8 +++ .../v2/reportcodec/report_codec_test.go | 18 +++++ .../mercury/v3/reportcodec/report_codec.go | 8 +++ .../v3/reportcodec/report_codec_test.go | 18 +++++ 12 files changed, 222 insertions(+), 57 deletions(-) diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go index e93f161916a..ddb521ff9ca 100644 --- a/core/services/ocr2/plugins/mercury/helpers_test.go +++ b/core/services/ocr2/plugins/mercury/helpers_test.go @@ -22,7 +22,14 @@ import ( "go.uber.org/zap/zaptest/observer" "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "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" @@ -30,17 +37,10 @@ import ( "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/utils" - - relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" - - "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/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) var _ pb.MercuryServer = &mercuryServer{} @@ -51,13 +51,14 @@ type request struct { } type mercuryServer struct { - privKey ed25519.PrivateKey - reqsCh chan request - t *testing.T + privKey ed25519.PrivateKey + reqsCh chan request + t *testing.T + buildReport func() []byte } -func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request) *mercuryServer { - return &mercuryServer{privKey, reqsCh, t} +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) { @@ -85,9 +86,12 @@ func (s *mercuryServer) LatestReport(ctx context.Context, lrr *pb.LatestReportRe out.Report = new(pb.Report) out.Report.FeedId = lrr.FeedId - price := big.NewInt(123456789) - encodedPrice, _ := relaymercury.EncodeValueInt192(price) - out.Report.Price = encodedPrice + report := s.buildReport() + payload, err := mercury.PayloadTypes.Pack(evmutil.RawReportContext(ocrtypes.ReportContext{}), report, [][32]byte{}, [][32]byte{}, [32]byte{}) + if err != nil { + panic(err) + } + out.Report.Payload = payload return out, nil } diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index b75855b8db5..be82e21a6fb 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -34,6 +34,9 @@ import ( "go.uber.org/zap/zaptest/observer" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaycodecv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" + relaycodecv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2" + relaycodecv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -149,7 +152,13 @@ func TestIntegration_MercuryV1(t *testing.T) { reqs := make(chan request) serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) serverPubKey := serverKey.PublicKey - srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs) + srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs, func() []byte { + report, err := (&reportcodecv1.ReportCodec{}).BuildReport(relaycodecv1.ReportFields{BenchmarkPrice: big.NewInt(234567), Bid: big.NewInt(1), Ask: big.NewInt(1), CurrentBlockHash: make([]byte, 32)}) + if err != nil { + panic(err) + } + return report + }) clientCSAKeys := make([]csakey.KeyV2, n+1) clientPubKeys := make([]ed25519.PublicKey, n+1) for i := 0; i < n+1; i++ { @@ -494,7 +503,13 @@ func TestIntegration_MercuryV2(t *testing.T) { reqs := make(chan request) serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) serverPubKey := serverKey.PublicKey - srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs) + srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs, func() []byte { + report, err := (&reportcodecv2.ReportCodec{}).BuildReport(relaycodecv2.ReportFields{BenchmarkPrice: big.NewInt(234567), LinkFee: big.NewInt(1), NativeFee: big.NewInt(1)}) + if err != nil { + panic(err) + } + return report + }) clientCSAKeys := make([]csakey.KeyV2, n+1) clientPubKeys := make([]ed25519.PublicKey, n+1) for i := 0; i < n+1; i++ { @@ -686,7 +701,7 @@ func TestIntegration_MercuryV2(t *testing.T) { continue // already saw all oracles for this feed } - expectedFee := relaymercury.CalculateFee(big.NewInt(123456789), rawReportingPluginConfig.BaseUSDFeeCents) + expectedFee := relaymercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFeeCents) expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) @@ -766,7 +781,13 @@ func TestIntegration_MercuryV3(t *testing.T) { reqs := make(chan request) serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) serverPubKey := serverKey.PublicKey - srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs) + srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs, func() []byte { + report, err := (&reportcodecv3.ReportCodec{}).BuildReport(relaycodecv3.ReportFields{BenchmarkPrice: big.NewInt(234567), Bid: big.NewInt(1), Ask: big.NewInt(1), LinkFee: big.NewInt(1), NativeFee: big.NewInt(1)}) + if err != nil { + panic(err) + } + return report + }) clientCSAKeys := make([]csakey.KeyV2, n+1) clientPubKeys := make([]ed25519.PublicKey, n+1) for i := 0; i < n+1; i++ { @@ -962,7 +983,7 @@ func TestIntegration_MercuryV3(t *testing.T) { continue // already saw all oracles for this feed } - expectedFee := relaymercury.CalculateFee(big.NewInt(123456789), rawReportingPluginConfig.BaseUSDFeeCents) + expectedFee := relaymercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFeeCents) expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 9578d4e0b0f..1ce68f2d944 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -35,6 +35,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" @@ -112,6 +113,7 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype if relayConfig.FeedID == nil { return nil, errors.New("FeedID must be specified") } + feedID := mercuryutils.FeedID(*relayConfig.FeedID) 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()) @@ -121,13 +123,6 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype return nil, errors.WithStack(err) } - // FIXME: We actually know the version here since it's in the feed ID, can - // we use generics to avoid passing three of this? - // https://smartcontract-it.atlassian.net/browse/MERC-1414 - reportCodecV1 := reportcodecv1.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV1")) - reportCodecV2 := reportcodecv2.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV2")) - reportCodecV3 := reportcodecv3.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV3")) - if !relayConfig.EffectiveTransmitterID.Valid { return nil, errors.New("EffectiveTransmitterID must be specified") } @@ -140,7 +135,26 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype if err != nil { return nil, err } - transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.db, r.pgCfg) + + // FIXME: We actually know the version here since it's in the feed ID, can + // we use generics to avoid passing three of this? + // https://smartcontract-it.atlassian.net/browse/MERC-1414 + reportCodecV1 := reportcodecv1.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV1")) + reportCodecV2 := reportcodecv2.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV2")) + reportCodecV3 := reportcodecv3.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV3")) + + var transmitterCodec mercury.TransmitterReportDecoder + switch feedID.Version() { + case 1: + transmitterCodec = reportCodecV1 + case 2: + transmitterCodec = reportCodecV2 + case 3: + transmitterCodec = reportCodecV3 + default: + return nil, fmt.Errorf("invalid feed version %d", feedID.Version()) + } + transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.db, r.pgCfg, transmitterCodec) return NewMercuryProvider(configWatcher, transmitter, reportCodecV1, reportCodecV2, reportCodecV3, r.lggr), nil } diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go index d259ab7a0ff..199dbfcdf88 100644 --- a/core/services/relay/evm/mercury/transmitter.go +++ b/core/services/relay/evm/mercury/transmitter.go @@ -76,7 +76,11 @@ type ConfigTracker interface { LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) } -var _ Transmitter = &mercuryTransmitter{} +type TransmitterReportDecoder interface { + BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) +} + +var _ Transmitter = (*mercuryTransmitter)(nil) type mercuryTransmitter struct { utils.StartStopOnce @@ -84,6 +88,7 @@ type mercuryTransmitter struct { rpcClient wsrpc.Client cfgTracker ConfigTracker persistenceManager *PersistenceManager + codec TransmitterReportDecoder feedID mercuryutils.FeedID jobID int32 @@ -117,7 +122,7 @@ 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) *mercuryTransmitter { +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 { feedIDHex := fmt.Sprintf("0x%x", feedID[:]) persistenceManager := NewPersistenceManager(lggr, NewORM(db, lggr, cfg), jobID, maxTransmitQueueSize, flushDeletesFrequency, pruneFrequency) return &mercuryTransmitter{ @@ -126,6 +131,7 @@ func NewTransmitter(lggr logger.Logger, cfgTracker ConfigTracker, rpcClient wsrp rpcClient, cfgTracker, persistenceManager, + codec, feedID, jobID, fmt.Sprintf("%x", fromAccount), @@ -322,18 +328,23 @@ func (mt *mercuryTransmitter) FetchInitialMaxFinalizedBlockNumber(ctx context.Co func (mt *mercuryTransmitter) LatestPrice(ctx context.Context, feedID [32]byte) (*big.Int, error) { mt.lggr.Trace("LatestPrice") - report, err := mt.latestReport(ctx, feedID) + fullReport, err := mt.latestReport(ctx, feedID) if err != nil { return nil, err } - if report == nil { + if fullReport == nil { return nil, nil } - price, err := relaymercury.DecodeValueInt192(report.Price) - if err != nil { - return nil, pkgerrors.Wrap(err, "failed to decode report.Price as *big.Int") + payload := fullReport.Payload + m := make(map[string]interface{}) + if err := PayloadTypes.UnpackIntoMap(m, payload); err != nil { + return nil, err + } + report, is := m["report"].([]byte) + if !is { + return nil, fmt.Errorf("expected report to be []byte, but it was %T", m["report"]) } - return price, nil + return mt.codec.BenchmarkPriceFromReport(report) } // LatestTimestamp will return -1, nil if the feed is missing diff --git a/core/services/relay/evm/mercury/transmitter_test.go b/core/services/relay/evm/mercury/transmitter_test.go index 247959609f9..6723ffcbcac 100644 --- a/core/services/relay/evm/mercury/transmitter_test.go +++ b/core/services/relay/evm/mercury/transmitter_test.go @@ -10,11 +10,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" + mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" mocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) @@ -38,7 +39,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil) err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) require.NoError(t, err) @@ -55,7 +56,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil) err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) require.NoError(t, err) @@ -72,7 +73,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil) err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) require.NoError(t, err) @@ -96,7 +97,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) ts, err := mt.LatestTimestamp(testutils.Context(t)) require.NoError(t, err) @@ -111,7 +112,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) ts, err := mt.LatestTimestamp(testutils.Context(t)) require.NoError(t, err) @@ -124,21 +125,33 @@ 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)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) _, err := mt.LatestTimestamp(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") }) } +type mockCodec struct { + val *big.Int + err error +} + +var _ mercurytypes.ReportCodec = &mockCodec{} + +func (m *mockCodec) BenchmarkPriceFromReport(_ ocrtypes.Report) (*big.Int, error) { + return m.val, m.err +} + func Test_MercuryTransmitter_LatestPrice(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) db := pgtest.NewSqlxDB(t) + codec := new(mockCodec) + t.Run("successful query", func(t *testing.T) { originalPrice := big.NewInt(123456789) - encodedPrice, _ := relaymercury.EncodeValueInt192(originalPrice) c := mocks.MockWSRPCClient{ LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { require.NotNil(t, in) @@ -146,15 +159,30 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { out = new(pb.LatestReportResponse) out.Report = new(pb.Report) out.Report.FeedId = sampleFeedID[:] - out.Report.Price = encodedPrice + out.Report.Payload = buildSamplePayload([]byte("doesn't matter")) return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true)) - price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) - require.NoError(t, err) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), codec) + + t.Run("BenchmarkPriceFromReport succeeds", func(t *testing.T) { + codec.val = originalPrice + codec.err = nil + + price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) + require.NoError(t, err) + + assert.Equal(t, originalPrice, price) + }) + t.Run("BenchmarkPriceFromReport fails", func(t *testing.T) { + codec.val = nil + codec.err = errors.New("something exploded") + + _, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) + require.Error(t, err) - assert.Equal(t, price, originalPrice) + assert.EqualError(t, err, "something exploded") + }) }) t.Run("successful query returning nil report (new feed)", func(t *testing.T) { @@ -165,7 +193,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) require.NoError(t, err) @@ -178,7 +206,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)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) _, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -203,7 +231,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) @@ -218,7 +246,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) @@ -230,7 +258,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)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -247,7 +275,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil) _, 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/types/types.go b/core/services/relay/evm/mercury/types/types.go index 6affba58169..4c606ed9eae 100644 --- a/core/services/relay/evm/mercury/types/types.go +++ b/core/services/relay/evm/mercury/types/types.go @@ -2,6 +2,9 @@ package types import ( "context" + "math/big" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" @@ -17,3 +20,7 @@ type ChainHeadTracker interface { type DataSourceORM interface { LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) } + +type ReportCodec interface { + BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) +} diff --git a/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go index a28186cce9c..fefddd6395b 100644 --- a/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "math" + "math/big" "github.com/ethereum/go-ethereum/common" pkgerrors "github.com/pkg/errors" @@ -89,3 +90,11 @@ func (r *ReportCodec) ValidFromBlockNumFromReport(report ocrtypes.Report) (int64 func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) { return reporttypes.Decode(report) } + +func (r *ReportCodec) BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) { + decoded, err := r.Decode(report) + if err != nil { + return nil, err + } + return decoded.BenchmarkPrice, nil +} diff --git a/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go index 6e6a58af4ca..3f4838c3e7c 100644 --- a/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go +++ b/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go @@ -161,3 +161,22 @@ func Test_ReportCodec_ValidFromBlockNumFromReport(t *testing.T) { assert.Contains(t, err.Error(), "ValidFromBlockNum=18446744073709551615 overflows max int64") }) } + +func Test_ReportCodec_BenchmarkPriceFromReport(t *testing.T) { + r := ReportCodec{} + feedID := utils.NewHash() + + t.Run("BenchmarkPriceFromReport extracts the benchmark price from valid report", func(t *testing.T) { + report := buildSampleReport(42, 999, feedID) + + bp, err := r.BenchmarkPriceFromReport(report) + require.NoError(t, err) + + assert.Equal(t, big.NewInt(242), bp) + }) + t.Run("BenchmarkPriceFromReport errors on invalid report", func(t *testing.T) { + _, err := r.BenchmarkPriceFromReport([]byte{1, 2, 3}) + require.Error(t, err) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + }) +} diff --git a/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go index 60dde81f1cb..0e1dfe9c46f 100644 --- a/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go @@ -67,3 +67,11 @@ func (r *ReportCodec) ObservationTimestampFromReport(report ocrtypes.Report) (ui func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) { return reporttypes.Decode(report) } + +func (r *ReportCodec) BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) { + decoded, err := r.Decode(report) + if err != nil { + return nil, err + } + return decoded.BenchmarkPrice, nil +} diff --git a/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go index c0c931dfe3a..8cf16a5dab4 100644 --- a/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go +++ b/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go @@ -132,3 +132,21 @@ func Test_ReportCodec_ObservationTimestampFromReport(t *testing.T) { assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") }) } + +func Test_ReportCodec_BenchmarkPriceFromReport(t *testing.T) { + r := ReportCodec{} + + t.Run("BenchmarkPriceFromReport extracts the benchmark price from valid report", func(t *testing.T) { + report := buildSampleReport(123) + + bp, err := r.BenchmarkPriceFromReport(report) + require.NoError(t, err) + + assert.Equal(t, big.NewInt(242), bp) + }) + t.Run("BenchmarkPriceFromReport errors on invalid report", func(t *testing.T) { + _, err := r.BenchmarkPriceFromReport([]byte{1, 2, 3}) + require.Error(t, err) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + }) +} diff --git a/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go index 66995e74ea7..4c0b3756d7b 100644 --- a/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go @@ -74,3 +74,11 @@ func (r *ReportCodec) ObservationTimestampFromReport(report ocrtypes.Report) (ui func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) { return reporttypes.Decode(report) } + +func (r *ReportCodec) BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) { + decoded, err := r.Decode(report) + if err != nil { + return nil, err + } + return decoded.BenchmarkPrice, nil +} diff --git a/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go index 80cf4c9665b..98b81edb002 100644 --- a/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go +++ b/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go @@ -140,3 +140,21 @@ func Test_ReportCodec_ObservationTimestampFromReport(t *testing.T) { assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") }) } + +func Test_ReportCodec_BenchmarkPriceFromReport(t *testing.T) { + r := ReportCodec{} + + t.Run("BenchmarkPriceFromReport extracts the benchmark price from valid report", func(t *testing.T) { + report := buildSampleReport(123) + + bp, err := r.BenchmarkPriceFromReport(report) + require.NoError(t, err) + + assert.Equal(t, big.NewInt(242), bp) + }) + t.Run("BenchmarkPriceFromReport errors on invalid report", func(t *testing.T) { + _, err := r.BenchmarkPriceFromReport([]byte{1, 2, 3}) + require.Error(t, err) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + }) +} From ebc6a02c4e3993430f27713d680bf4d1495eaf91 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Fri, 8 Sep 2023 12:09:23 -0400 Subject: [PATCH 67/88] finalize mercury 0.3 integration details (#10538) * add pprof to auto 2.1 * use uint32 for timestamp * add 0x prefix to decode full report * decode full report as byte slice * introduce a delay for timestamp * remove log * update URL * update * update * update * remove url encoding * add a TODO --- .../ocr2keeper/evm21/encoding/interface.go | 1 + .../ocr2keeper/evm21/streams_lookup.go | 77 ++++---- .../ocr2keeper/evm21/streams_lookup_test.go | 165 ++++++++++-------- 3 files changed, 131 insertions(+), 112 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go index 58e82134bdf..cbdb3358446 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go @@ -42,6 +42,7 @@ const ( MercuryUnmarshalError PipelineExecutionState = 6 InvalidMercuryRequest PipelineExecutionState = 7 InvalidMercuryResponse PipelineExecutionState = 8 // this will only happen if Mercury server sends bad responses + UpkeepNotAuthorized PipelineExecutionState = 9 ) type UpkeepInfo = iregistry21.KeeperRegistryBase21UpkeepInfo diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go index 80ad68cdca1..2c8f6ce1fea 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go @@ -66,10 +66,10 @@ type MercuryV03Response struct { } type MercuryV03Report struct { - FeedID string `json:"feedID"` // feed id in hex - ValidFromTimestamp string `json:"validFromTimestamp"` - ObservationsTimestamp string `json:"observationsTimestamp"` - FullReport string `json:"fullReport"` // the actual mercury report of this feed, can be sent to verifier + FeedID []byte `json:"feedID"` // feed id in hex + ValidFromTimestamp uint32 `json:"validFromTimestamp"` + ObservationsTimestamp uint32 `json:"observationsTimestamp"` + FullReport []byte `json:"fullReport"` // the actual mercury report of this feed, can be sent to verifier } type MercuryData struct { @@ -163,7 +163,7 @@ func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup * state, reason, values, retryable, err := r.doMercuryRequest(ctx, lookup, lggr) if err != nil { - lggr.Errorf("upkeep %s retryable %v doMercuryRequest: %v", lookup.upkeepId, retryable, err) + lggr.Errorf("upkeep %s retryable %v doMercuryRequest: %s", lookup.upkeepId, retryable, err.Error()) checkResults[i].Retryable = retryable checkResults[i].PipelineExecutionState = uint8(state) checkResults[i].IneligibilityReason = uint8(reason) @@ -176,7 +176,7 @@ func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup * state, retryable, mercuryBytes, err := r.checkCallback(ctx, values, lookup) if err != nil { - lggr.Errorf("at block %d upkeep %s checkCallback err: %v", lookup.block, lookup.upkeepId, err) + lggr.Errorf("at block %d upkeep %s checkCallback err: %s", lookup.block, lookup.upkeepId, err.Error()) checkResults[i].Retryable = retryable checkResults[i].PipelineExecutionState = uint8(state) return @@ -185,7 +185,7 @@ func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup * state, needed, performData, failureReason, _, err := r.packer.UnpackCheckCallbackResult(mercuryBytes) if err != nil { - lggr.Errorf("at block %d upkeep %s UnpackCheckCallbackResult err: %v", lookup.block, lookup.upkeepId, err) + lggr.Errorf("at block %d upkeep %s UnpackCheckCallbackResult err: %s", lookup.block, lookup.upkeepId, err.Error()) checkResults[i].PipelineExecutionState = uint8(state) return } @@ -318,7 +318,6 @@ func (r *EvmRegistry) doMercuryRequest(ctx context.Context, sl *StreamsLookup, l results[m.Index] = m.Bytes[0] } } - lggr.Debugf("upkeep %s retryable %t reqErr %w", sl.upkeepId.String(), retryable && !allSuccess, reqErr) // only retry when not all successful AND none are not retryable return state, encoding.UpkeepFailureReasonNone, results, retryable && !allSuccess, reqErr } @@ -431,13 +430,14 @@ func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryDa // multiFeedsRequest sends a Mercury v0.3 request for a multi-feed report func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryData, sl *StreamsLookup, lggr logger.Logger) { - q := url.Values{ - feedIDs: {strings.Join(sl.feeds, ",")}, - timestamp: {sl.time.String()}, - } - - reqUrl := fmt.Sprintf("%s%s%s", r.mercury.cred.URL, mercuryBatchPathV03, q.Encode()) - lggr.Debugf("request URL for upkeep %s feed %s: %s", sl.upkeepId.String(), strings.Join(sl.feeds, ","), reqUrl) + // this won't work bc q.Encode() will encode commas as '%2C' but the server is strictly expecting a comma separated list + //q := url.Values{ + // feedIDs: {strings.Join(sl.feeds, ",")}, + // timestamp: {sl.time.String()}, + //} + params := fmt.Sprintf("%s=%s&%s=%s", feedIDs, strings.Join(sl.feeds, ","), timestamp, sl.time.String()) + reqUrl := fmt.Sprintf("%s%s%s", r.mercury.cred.URL, mercuryBatchPathV03, params) + lggr.Debugf("request URL for upkeep %s userId %s: %s", sl.upkeepId.String(), r.mercury.cred.Username, reqUrl) req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqUrl, nil) if err != nil { @@ -446,7 +446,7 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa } ts := time.Now().UTC().UnixMilli() - signature := r.generateHMAC(http.MethodGet, mercuryBatchPathV03+q.Encode(), []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts) + signature := r.generateHMAC(http.MethodGet, mercuryBatchPathV03+params, []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts) req.Header.Set(headerContentType, applicationJson) // username here is often referred to as user id req.Header.Set(headerAuthorization, r.mercury.cred.Username) @@ -465,7 +465,7 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa retryable = false resp, err1 := r.hc.Do(req) if err1 != nil { - lggr.Warnf("at block %s upkeep %s GET request fails from mercury v0.3: %v", sl.time.String(), sl.upkeepId.String(), err1) + lggr.Warnf("at timestamp %s upkeep %s GET request fails from mercury v0.3: %v", sl.time.String(), sl.upkeepId.String(), err1) retryable = true state = encoding.MercuryFlakyFailure return err1 @@ -484,43 +484,48 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa return err1 } - if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusInternalServerError { - lggr.Warnf("at block %s upkeep %s received status code %d from mercury v0.3", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) + lggr.Infof("at timestamp %s upkeep %s received status code %d from mercury v0.3", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) + if resp.StatusCode == http.StatusUnauthorized { + retryable = false + state = encoding.UpkeepNotAuthorized + return fmt.Errorf("at timestamp %s upkeep %s received status code %d from mercury v0.3, most likely this is caused by unauthorized upkeep", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) + } else if resp.StatusCode == http.StatusBadRequest { + retryable = false + state = encoding.InvalidMercuryRequest + return fmt.Errorf("at timestamp %s upkeep %s received status code %d from mercury v0.3, most likely this is caused by invalid format of timestamp", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) + } else if resp.StatusCode == http.StatusInternalServerError { retryable = true state = encoding.MercuryFlakyFailure - return errors.New(strconv.FormatInt(int64(resp.StatusCode), 10)) + return fmt.Errorf("%d", http.StatusInternalServerError) + } else if resp.StatusCode == 420 { + // in 0.3, this will happen when missing/malformed query args, missing or bad required headers, non-existent feeds, or no permissions for feeds + retryable = false + return fmt.Errorf("at timestamp %s upkeep %s received status code %d from mercury v0.3, most likely this is caused by missing/malformed query args, missing or bad required headers, non-existent feeds, or no permissions for feeds", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) } else if resp.StatusCode != http.StatusOK { retryable = false state = encoding.InvalidMercuryRequest - return fmt.Errorf("at block %s upkeep %s received status code %d from mercury v0.3", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) + return fmt.Errorf("at timestamp %s upkeep %s received status code %d from mercury v0.3", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) } var response MercuryV03Response err1 = json.Unmarshal(body, &response) if err1 != nil { - lggr.Warnf("at block %s upkeep %s failed to unmarshal body to MercuryV03Response from mercury v0.3: %v", sl.time.String(), sl.upkeepId.String(), err1) + lggr.Warnf("at timestamp %s upkeep %s failed to unmarshal body to MercuryV03Response from mercury v0.3: %v", sl.time.String(), sl.upkeepId.String(), err1) retryable = false state = encoding.MercuryUnmarshalError return err1 } + // in v0.3, if some feeds are not available, the server will only return available feeds, but we need to make sure ALL feeds are retrieved before calling user contract + // hence, retry in this case. retry will help when we send a very new timestamp and reports are not yet generated if len(response.Reports) != len(sl.feeds) { - // this should never happen. if this upkeep does not have permission for any feeds it requests, or if certain feeds are - // missing in mercury server, the mercury server v0.3 should respond with 400s, rather than returning partial results - retryable = false - state = encoding.InvalidMercuryResponse - return fmt.Errorf("at block %s upkeep %s requested %d feeds but received %d reports from mercury v0.3", sl.time.String(), sl.upkeepId.String(), len(sl.feeds), len(response.Reports)) + // TODO: AUTO-5044: calculate what reports are missing and log a warning + retryable = true + state = encoding.MercuryFlakyFailure + return fmt.Errorf("%d", http.StatusNotFound) } var reportBytes [][]byte - var b []byte for _, rsp := range response.Reports { - b, err1 = hexutil.Decode(rsp.FullReport) - if err1 != nil { - lggr.Warnf("upkeep %s block %s failed to decode fullReport %s from mercury v0.3: %v", sl.upkeepId.String(), sl.time.String(), rsp.FullReport, err1) - retryable = false - state = encoding.InvalidMercuryResponse - return err1 - } - reportBytes = append(reportBytes, b) + reportBytes = append(reportBytes, rsp.FullReport) } ch <- MercuryData{ Index: 0, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go index a860f633512..56d0de8f542 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go @@ -665,7 +665,8 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { retryNumber int retryable bool errorMessage string - response MercuryV03Response + firstResponse *MercuryV03Response + response *MercuryV03Response }{ { name: "success - mercury responds in the first try", @@ -676,53 +677,24 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { time: big.NewInt(123456), upkeepId: upkeepId, }, - response: MercuryV03Response{ + response: &MercuryV03Response{ Reports: []MercuryV03Report{ { - FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", - ValidFromTimestamp: "123456", - ObservationsTimestamp: "123456", - FullReport: "0xab2123dc00000012", + FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + ValidFromTimestamp: 123456, + ObservationsTimestamp: 123456, + FullReport: hexutil.MustDecode("0xab2123dc00000012"), }, { - FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", - ValidFromTimestamp: "123458", - ObservationsTimestamp: "123458", - FullReport: "0xab2123dc00000016", + FeedID: hexutil.MustDecode("0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"), + ValidFromTimestamp: 123458, + ObservationsTimestamp: 123458, + FullReport: hexutil.MustDecode("0xab2123dc00000016"), }, }, }, statusCode: http.StatusOK, }, - { - name: "success - retry for 404", - lookup: &StreamsLookup{ - feedParamKey: feedIDs, - feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: timestamp, - time: big.NewInt(123456), - upkeepId: upkeepId, - }, - retryNumber: 1, - statusCode: http.StatusNotFound, - lastStatusCode: http.StatusOK, - response: MercuryV03Response{ - Reports: []MercuryV03Report{ - { - FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", - ValidFromTimestamp: "123456", - ObservationsTimestamp: "123456", - FullReport: "0xab2123dc00000012", - }, - { - FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", - ValidFromTimestamp: "123458", - ObservationsTimestamp: "123458", - FullReport: "0xab2123dc00000012", - }, - }, - }, - }, { name: "success - retry for 500", lookup: &StreamsLookup{ @@ -735,19 +707,19 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { retryNumber: 2, statusCode: http.StatusInternalServerError, lastStatusCode: http.StatusOK, - response: MercuryV03Response{ + response: &MercuryV03Response{ Reports: []MercuryV03Report{ { - FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", - ValidFromTimestamp: "123456", - ObservationsTimestamp: "123456", - FullReport: "0xab2123dc00000012", + FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + ValidFromTimestamp: 123456, + ObservationsTimestamp: 123456, + FullReport: hexutil.MustDecode("0xab2123dc00000012"), }, { - FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", - ValidFromTimestamp: "123458", - ObservationsTimestamp: "123458", - FullReport: "0xab2123dc00000019", + FeedID: hexutil.MustDecode("0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"), + ValidFromTimestamp: 123458, + ObservationsTimestamp: 123458, + FullReport: hexutil.MustDecode("0xab2123dc00000019"), }, }, }, @@ -762,9 +734,9 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { upkeepId: upkeepId, }, retryNumber: totalAttempt, - statusCode: http.StatusNotFound, + statusCode: http.StatusInternalServerError, retryable: true, - errorMessage: "All attempts fail:\n#1: 404\n#2: 404\n#3: 404", + errorMessage: "All attempts fail:\n#1: 500\n#2: 500\n#3: 500", }, { name: "failure - returns retryable and then non-retryable", @@ -776,12 +748,24 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { upkeepId: upkeepId, }, retryNumber: 1, - statusCode: http.StatusNotFound, - lastStatusCode: http.StatusBadGateway, - errorMessage: "All attempts fail:\n#1: 404\n#2: at block 123456 upkeep 123456789 received status code 502 from mercury v0.3", + statusCode: http.StatusInternalServerError, + lastStatusCode: http.StatusUnauthorized, + errorMessage: "All attempts fail:\n#1: 500\n#2: at timestamp 123456 upkeep 123456789 received status code 401 from mercury v0.3, most likely this is caused by unauthorized upkeep", + }, + { + name: "failure - returns status code 420 not retryable", + lookup: &StreamsLookup{ + feedParamKey: feedIDs, + feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, + timeParamKey: timestamp, + time: big.NewInt(123456), + upkeepId: upkeepId, + }, + statusCode: 420, + errorMessage: "All attempts fail:\n#1: at timestamp 123456 upkeep 123456789 received status code 420 from mercury v0.3, most likely this is caused by missing/malformed query args, missing or bad required headers, non-existent feeds, or no permissions for feeds", }, { - name: "failure - returns not retryable", + name: "failure - returns status code 502 not retryable", lookup: &StreamsLookup{ feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, @@ -790,10 +774,10 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { upkeepId: upkeepId, }, statusCode: http.StatusBadGateway, - errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 received status code 502 from mercury v0.3", + errorMessage: "All attempts fail:\n#1: at timestamp 123456 upkeep 123456789 received status code 502 from mercury v0.3", }, { - name: "failure - reports length does not match feeds length", + name: "success - retry when reports length does not match feeds length", lookup: &StreamsLookup{ feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, @@ -801,18 +785,34 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { time: big.NewInt(123456), upkeepId: upkeepId, }, - response: MercuryV03Response{ + firstResponse: &MercuryV03Response{ Reports: []MercuryV03Report{ { - FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", - ValidFromTimestamp: "123456", - ObservationsTimestamp: "123456", - FullReport: "0xab2123dc00000012", + FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + ValidFromTimestamp: 123456, + ObservationsTimestamp: 123456, + FullReport: hexutil.MustDecode("0xab2123dc00000012"), }, }, }, - statusCode: http.StatusOK, - errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 requested 2 feeds but received 1 reports from mercury v0.3", + response: &MercuryV03Response{ + Reports: []MercuryV03Report{ + { + FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + ValidFromTimestamp: 123456, + ObservationsTimestamp: 123456, + FullReport: hexutil.MustDecode("0xab2123dc00000012"), + }, + { + FeedID: hexutil.MustDecode("0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"), + ValidFromTimestamp: 123458, + ObservationsTimestamp: 123458, + FullReport: hexutil.MustDecode("0xab2123dc00000019"), + }, + }, + }, + retryNumber: 1, + statusCode: http.StatusOK, }, } @@ -830,17 +830,33 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { } hc.On("Do", mock.Anything).Return(resp, nil).Once() } else if tt.retryNumber < totalAttempt { - retryResp := &http.Response{ - StatusCode: tt.statusCode, - Body: io.NopCloser(bytes.NewReader(b)), - } - hc.On("Do", mock.Anything).Return(retryResp, nil).Times(tt.retryNumber) + if tt.firstResponse != nil && tt.response != nil { + b0, err := json.Marshal(tt.firstResponse) + assert.Nil(t, err) + resp0 := &http.Response{ + StatusCode: tt.statusCode, + Body: io.NopCloser(bytes.NewReader(b0)), + } + b1, err := json.Marshal(tt.response) + assert.Nil(t, err) + resp1 := &http.Response{ + StatusCode: tt.statusCode, + Body: io.NopCloser(bytes.NewReader(b1)), + } + hc.On("Do", mock.Anything).Return(resp0, nil).Once().On("Do", mock.Anything).Return(resp1, nil).Once() + } else { + retryResp := &http.Response{ + StatusCode: tt.statusCode, + Body: io.NopCloser(bytes.NewReader(b)), + } + hc.On("Do", mock.Anything).Return(retryResp, nil).Times(tt.retryNumber) - resp := &http.Response{ - StatusCode: tt.lastStatusCode, - Body: io.NopCloser(bytes.NewReader(b)), + resp := &http.Response{ + StatusCode: tt.lastStatusCode, + Body: io.NopCloser(bytes.NewReader(b)), + } + hc.On("Do", mock.Anything).Return(resp, nil).Once() } - hc.On("Do", mock.Anything).Return(resp, nil).Once() } else { resp := &http.Response{ StatusCode: tt.statusCode, @@ -862,11 +878,8 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { } else { assert.Nil(t, m.Error) var reports [][]byte - var report []byte for _, rsp := range tt.response.Reports { - report, err = hexutil.Decode(rsp.FullReport) - assert.Nil(t, err) - reports = append(reports, report) + reports = append(reports, rsp.FullReport) } assert.Equal(t, reports, m.Bytes) } From fda3b1b582a3e722d7dbed779ace6beafe5b2e97 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Fri, 8 Sep 2023 19:41:18 +0300 Subject: [PATCH 68/88] raise timeouts (#10563) --- .github/workflows/integration-staging-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-staging-tests.yml b/.github/workflows/integration-staging-tests.yml index 7d2d0b66bdc..a6fda178d50 100644 --- a/.github/workflows/integration-staging-tests.yml +++ b/.github/workflows/integration-staging-tests.yml @@ -57,7 +57,7 @@ jobs: run: | cd integration-tests/load/functions if [[ $SELECTED_TEST == mumbai_functions* ]]; then - go test -v -run TestFunctionsLoad/$SELECTED_TEST + go test -v -timeout 6h -run TestFunctionsLoad/$SELECTED_TEST elif [[ $SELECTED_TEST == gateway* ]]; then - go test -v -run TestGatewayLoad/$SELECTED_TEST + go test -v -timeout 6h -run TestGatewayLoad/$SELECTED_TEST fi \ No newline at end of file From 70c360ec6034eb862cf61eb7fd7205067c373add Mon Sep 17 00:00:00 2001 From: Chris Cushman <104409744+vreff@users.noreply.github.com> Date: Fri, 8 Sep 2023 13:01:39 -0400 Subject: [PATCH 69/88] [Automation] Fixes to chaincli for Automation v2.1 (#10540) --- core/scripts/chaincli/handler/keeper_deployer.go | 6 ++++-- core/scripts/chaincli/handler/keeper_launch.go | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/core/scripts/chaincli/handler/keeper_deployer.go b/core/scripts/chaincli/handler/keeper_deployer.go index 089b176695c..eae8c68d332 100644 --- a/core/scripts/chaincli/handler/keeper_deployer.go +++ b/core/scripts/chaincli/handler/keeper_deployer.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ocr2config "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocr3confighelper "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/umbracle/ethgo/abi" @@ -297,11 +298,13 @@ func (d *v21KeeperDeployer) SetKeepers(opts *bind.TransactOpts, cls []cmd.HTTPCl panic(err) } - signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err := ocr2config.ContractSetConfigArgsForTests( + signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( 5*time.Second, // deltaProgress time.Duration, 10*time.Second, // deltaResend time.Duration, + 400*time.Millisecond, // deltaInitial time.Duration, 2500*time.Millisecond, // deltaRound time.Duration, 40*time.Millisecond, // deltaGrace time.Duration, + 300*time.Millisecond, // deltaCertifiedCommitRequest time.Duration, 30*time.Second, // deltaStage time.Duration, 50, // rMax uint8, S, // s []int, @@ -309,7 +312,6 @@ func (d *v21KeeperDeployer) SetKeepers(opts *bind.TransactOpts, cls []cmd.HTTPCl offC, // reportingPluginConfig []byte, 20*time.Millisecond, // maxDurationQuery time.Duration, 1600*time.Millisecond, // maxDurationObservation time.Duration, - 800*time.Millisecond, // maxDurationReport time.Duration, 20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration, 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, 1, // f int, diff --git a/core/scripts/chaincli/handler/keeper_launch.go b/core/scripts/chaincli/handler/keeper_launch.go index fb975b48369..83ee6a77129 100644 --- a/core/scripts/chaincli/handler/keeper_launch.go +++ b/core/scripts/chaincli/handler/keeper_launch.go @@ -347,6 +347,7 @@ name = "ocr2-automation" forwardingAllowed = false schemaVersion = 1 contractID = "%s" +contractConfigTrackerPollInterval = "15s" ocrKeyBundleID = "%s" transmitterID = "%s" p2pv2Bootstrappers = [ @@ -358,6 +359,8 @@ chainID = %d [pluginConfig] maxServiceWorkers = 100 +cacheEvictionInterval = "1s" +contractVersion = "%s" mercuryCredentialName = "%s"` // createOCR2KeeperJob creates an ocr2keeper job in the chainlink node by the given address @@ -367,6 +370,12 @@ func (k *Keeper) createOCR2KeeperJob(client cmd.HTTPClient, contractAddr, nodeAd return fmt.Errorf("failed to get node OCR2 key bundle ID: %s", err) } + // Correctly assign contract version in OCR job spec. + var contractVersion string = "v2.0" + if k.cfg.RegistryVersion == keeper.RegistryVersion_2_1 { + contractVersion = "v2.1" + } + request, err := json.Marshal(web.CreateJobRequest{ TOML: fmt.Sprintf(ocr2keeperJobTemplate, contractAddr, // contractID @@ -374,6 +383,7 @@ func (k *Keeper) createOCR2KeeperJob(client cmd.HTTPClient, contractAddr, nodeAd nodeAddr, // transmitterID - node wallet address k.cfg.BootstrapNodeAddr, // bootstrap node key and address k.cfg.ChainID, // chainID + contractVersion, // contractVersion k.cfg.MercuryCredName, // mercury credential name ), }) From 52b1b8cf5bd2ab2dabffad78ca43038e0b8fdabb Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 8 Sep 2023 13:30:53 -0400 Subject: [PATCH 70/88] Bump chainlink-relay to e2f9fcf758d81e9d8882610470f06aeb379938f8 (#10566) --- 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 68e623d4786..9e493f84df7 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -299,7 +299,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.20230831132059-42af68994512 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 7f3ed97110b..afae317ebbc 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1377,8 +1377,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-cosmos v0.4.1-0.20230831132059-42af68994512 h1:DojChlaudA1HAxwQPKmt/EDf36OUeFJ0LJBYClauMyU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b h1:RrG9RuPfQi1Ak7/FdIEDlDpta2PSm5Dghmxpq2ZIO8M= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8 h1:JRXkI/eE1S0E3VatXVc24vD5e8Zu+YwSV6uSvOh23xU= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= diff --git a/go.mod b/go.mod index 64560eb08fe..ebacf922178 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-cosmos v0.4.1-0.20230831132059-42af68994512 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 diff --git a/go.sum b/go.sum index f434c6fc492..85a7b18f8b5 100644 --- a/go.sum +++ b/go.sum @@ -1377,8 +1377,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-cosmos v0.4.1-0.20230831132059-42af68994512 h1:DojChlaudA1HAxwQPKmt/EDf36OUeFJ0LJBYClauMyU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b h1:RrG9RuPfQi1Ak7/FdIEDlDpta2PSm5Dghmxpq2ZIO8M= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8 h1:JRXkI/eE1S0E3VatXVc24vD5e8Zu+YwSV6uSvOh23xU= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 8fda4ca62dd..e4f61c32b7d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -384,7 +384,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.20230831132059-42af68994512 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 4d57db530fc..cd3f8b20a2c 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2252,8 +2252,8 @@ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af6899451 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230831132059-42af68994512/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= github.com/smartcontractkit/chainlink-env v0.36.0 h1:CFOjs0c0y3lrHi/fl5qseCH9EQa5W/6CFyOvmhe2VnA= github.com/smartcontractkit/chainlink-env v0.36.0/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b h1:RrG9RuPfQi1Ak7/FdIEDlDpta2PSm5Dghmxpq2ZIO8M= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908130052-16ce8fa4a45b/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8 h1:JRXkI/eE1S0E3VatXVc24vD5e8Zu+YwSV6uSvOh23xU= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230908162043-e2f9fcf758d8/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= From 3dd25235212ba93515011763d580995db9ac66fd Mon Sep 17 00:00:00 2001 From: Lei Date: Fri, 8 Sep 2023 11:36:11 -0700 Subject: [PATCH 71/88] smoke test for setUpkeepTriggerConfig (#10530) * smoke test for setUpkeepTriggerConfig * add test to json --- .../contracts/ethereum_keeper_contracts.go | 21 +++ integration-tests/smoke/automation_test.go | 171 ++++++++++++++++++ .../smoke/automation_test.go_test_list.json | 3 + 3 files changed, 195 insertions(+) diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go index e4279c8bceb..67d26960585 100644 --- a/integration-tests/contracts/ethereum_keeper_contracts.go +++ b/integration-tests/contracts/ethereum_keeper_contracts.go @@ -76,6 +76,7 @@ type KeeperRegistry interface { PauseUpkeep(id *big.Int) error UnpauseUpkeep(id *big.Int) error UpdateCheckData(id *big.Int, newCheckData []byte) error + SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) error } type KeeperConsumer interface { @@ -903,6 +904,26 @@ func (v *EthereumKeeperRegistry) UpdateCheckData(id *big.Int, newCheckData []byt } } +// SetUpkeepTriggerConfig updates the trigger config of an upkeep (only for version 2.1) +func (v *EthereumKeeperRegistry) SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) error { + + switch v.version { + case ethereum.RegistryVersion_2_1: + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + + tx, err := v.registry2_1.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) + } +} + // PauseUpkeep stops an upkeep from an upkeep func (v *EthereumKeeperRegistry) PauseUpkeep(id *big.Int) error { switch v.version { diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 109f681ea81..368b833a683 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/common" "github.com/onsi/gomega" "github.com/stretchr/testify/require" @@ -24,9 +25,13 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils" + 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/store/models" ) +var utilsABI = cltypes.MustGetABI(automation_utils_2_1.AutomationUtilsABI) + const ( automationDefaultUpkeepGasLimit = uint32(2500000) automationDefaultLinkFunds = int64(9e18) @@ -206,6 +211,172 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { } } +func TestSetUpkeepTriggerConfig(t *testing.T) { + t.Parallel() + l := utils.GetTestLogger(t) + + chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker( + t, "set-trigger-config", ethereum.RegistryVersion_2_1, defaultOCRRegistryConfig, false, + ) + + consumers, upkeepIDs := actions.DeployConsumers( + t, + registry, + registrar, + linkToken, + contractDeployer, + chainClient, + defaultAmountOfUpkeeps, + big.NewInt(automationDefaultLinkFunds), + automationDefaultUpkeepGasLimit, + true, + ) + + // 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(context.Background()) + 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 + } + + err = registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig) + require.NoError(t, err, "Could not set upkeep trigger config at index %d", i) + } + + err := chainClient.WaitForEvents() + require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps") + + var countersAfterSetNoMatch = make([]*big.Int, len(upkeepIDs)) + + // 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(context.Background()) + 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(context.Background()) + 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 + } + + err = registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig) + require.NoError(t, err, "Could not set upkeep trigger config at index %d", i) + } + + err = chainClient.WaitForEvents() + require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps") + + var countersAfterSetMatch = make([]*big.Int, len(upkeepIDs)) + + 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(context.Background()) + 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(context.Background()) + 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) { t.Parallel() registryVersions := map[string]ethereum.KeeperRegistryVersion{ diff --git a/integration-tests/smoke/automation_test.go_test_list.json b/integration-tests/smoke/automation_test.go_test_list.json index badb7d6b3eb..515e1632701 100644 --- a/integration-tests/smoke/automation_test.go_test_list.json +++ b/integration-tests/smoke/automation_test.go_test_list.json @@ -101,6 +101,9 @@ "name": "registry_2_1" } ] + }, + { + "name": "TestSetUpkeepTriggerConfig" } ] } From d13f1790c7477bfbc651e791f7ab5932486723d4 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Fri, 8 Sep 2023 15:09:03 -0400 Subject: [PATCH 72/88] clean up shadows, logs, typos etc (#10533) * clean up some shadows and logs * fix typos and adhere to go convention * fix tests --- .../plugins/ocr2keeper/evm21/core/trigger.go | 2 +- .../plugins/ocr2keeper/evm21/core/utils.go | 6 ++-- .../ocr2keeper/evm21/encoding/encoder.go | 2 +- .../ocr2keeper/evm21/encoding/interface.go | 1 - .../ocr2keeper/evm21/encoding/packer.go | 16 ---------- .../ocr2keeper/evm21/logprovider/factory.go | 4 +-- .../ocr2keeper/evm21/logprovider/filter.go | 6 ++-- .../evm21/logprovider/log_packer.go | 2 +- .../evm21/logprovider/provider_life_cycle.go | 3 +- .../ocr2keeper/evm21/logprovider/recoverer.go | 4 +-- .../ocr2keeper/evm21/payload_builder.go | 2 +- .../ocr2keeper/evm21/payload_builder_test.go | 1 - .../ocr2/plugins/ocr2keeper/evm21/registry.go | 13 ++++---- .../evm21/registry_check_pipeline.go | 2 +- .../ocr2/plugins/ocr2keeper/evm21/services.go | 6 ++-- .../evm21/transmit/event_provider.go | 30 +++++++++---------- .../ocr2keeper/evm21/upkeep_provider.go | 4 +-- .../ocr2keeper/evm21/upkeepstate/scanner.go | 2 +- core/services/ocr2/plugins/ocr2keeper/util.go | 2 +- 19 files changed, 46 insertions(+), 62 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go index ea0c4a31f37..79273479596 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go @@ -16,7 +16,7 @@ type triggerWrapper = automation_utils_2_1.KeeperRegistryBase21LogTrigger var ErrABINotParsable = fmt.Errorf("error parsing abi") -// according to the upkeep type of the given id. +// PackTrigger packs the trigger data according to the upkeep type of the given id. it will remove the first 4 bytes of function selector. func PackTrigger(id *big.Int, trig triggerWrapper) ([]byte, error) { var trigger []byte var err error diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils.go index 25003055a3b..6a31b938fc6 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils.go @@ -19,14 +19,14 @@ func GetTxBlock(ctx context.Context, client client.Client, txHash common.Hash) ( if strings.Contains(err.Error(), "not yet been implemented") { // workaround for simulated chains // Exploratory: fix this properly (e.g. in the simulated backend) - receipt, err1 := client.TransactionReceipt(ctx, txHash) + r, err1 := client.TransactionReceipt(ctx, txHash) if err1 != nil { return nil, common.Hash{}, err1 } - if receipt.Status != 1 { + if r.Status != 1 { return nil, common.Hash{}, nil } - return receipt.BlockNumber, receipt.BlockHash, nil + return r.BlockNumber, r.BlockHash, nil } return nil, common.Hash{}, err } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go index f68289044ec..239de099c01 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go @@ -87,7 +87,7 @@ func (e reportEncoder) Encode(results ...ocr2keepers.CheckResult) ([]byte, error return e.packer.PackReport(report) } -// Extract the plugin will call this function to accept/transmit reports +// Extract extracts a slice of reported upkeeps (upkeep id, trigger, and work id) from raw bytes. the plugin will call this function to accept/transmit reports. func (e reportEncoder) Extract(raw []byte) ([]ocr2keepers.ReportedUpkeep, error) { report, err := e.packer.UnpackReport(raw) if err != nil { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go index cbdb3358446..ee7074faf08 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go @@ -51,7 +51,6 @@ type Packer interface { UnpackCheckResult(payload ocr2keepers.UpkeepPayload, raw string) (ocr2keepers.CheckResult, error) UnpackCheckCallbackResult(callbackResp []byte) (PipelineExecutionState, bool, []byte, uint8, *big.Int, error) UnpackPerformResult(raw string) (PipelineExecutionState, bool, error) - UnpackUpkeepInfo(id *big.Int, raw string) (UpkeepInfo, error) UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) PackReport(report automation_utils_2_1.KeeperRegistryBase21Report) ([]byte, error) UnpackReport(raw []byte) (automation_utils_2_1.KeeperRegistryBase21Report, error) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go index c710b31291f..45d5736cb72 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go @@ -94,22 +94,6 @@ func (p *abiPacker) UnpackPerformResult(raw string) (PipelineExecutionState, boo return NoPipelineError, *abi.ConvertType(out[0], new(bool)).(*bool), nil } -func (p *abiPacker) UnpackUpkeepInfo(id *big.Int, raw string) (UpkeepInfo, error) { - b, err := hexutil.Decode(raw) - if err != nil { - return UpkeepInfo{}, err - } - - out, err := p.abi.Methods["getUpkeep"].Outputs.UnpackValues(b) - if err != nil { - return UpkeepInfo{}, fmt.Errorf("%w: unpack getUpkeep return: %s", err, raw) - } - - info := *abi.ConvertType(out[0], new(UpkeepInfo)).(*UpkeepInfo) - - return info, nil -} - // UnpackLogTriggerConfig unpacks the log trigger config from the given raw data func (p *abiPacker) UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) { var cfg automation_utils_2_1.LogTriggerConfig diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go index 0db15da0f32..121c6036ddd 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go @@ -49,8 +49,8 @@ func NewOptions(finalityDepth int64) LogTriggersOptions { func (o *LogTriggersOptions) Defaults(finalityDepth int64) { if o.LookbackBlocks == 0 { lookbackBlocks := int64(200) - if lookbackBlocks < int64(finalityDepth) { - lookbackBlocks = int64(finalityDepth) + if lookbackBlocks < finalityDepth { + lookbackBlocks = finalityDepth } o.LookbackBlocks = lookbackBlocks } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter.go index db1cb43d2c3..44780cbc4b1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter.go @@ -46,6 +46,7 @@ func (f upkeepFilter) Clone() upkeepFilter { } } +// Select returns a slice of logs which match the upkeep filter. func (f upkeepFilter) Select(logs ...logpoller.Log) []logpoller.Log { var selected []logpoller.Log for _, log := range logs { @@ -56,6 +57,7 @@ func (f upkeepFilter) Select(logs ...logpoller.Log) []logpoller.Log { return selected } +// match returns a bool indicating if the log's topics data matches selector and indexed topics in upkeep filter. func (f upkeepFilter) match(log logpoller.Log) bool { filters := f.topics[1:] selector := f.selector @@ -65,7 +67,7 @@ func (f upkeepFilter) match(log logpoller.Log) bool { return true } - for i, f := range filters { + for i, filter := range filters { // bitwise AND the selector with the index to check // if the filter is needed mask := uint8(1 << uint8(i)) @@ -76,7 +78,7 @@ func (f upkeepFilter) match(log logpoller.Log) bool { // log doesn't have enough topics return false } - if !bytes.Equal(f.Bytes(), log.Topics[i+1]) { + if !bytes.Equal(filter.Bytes(), log.Topics[i+1]) { return false } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go index 363f06ffa5d..49bc9b19d4f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go @@ -22,7 +22,7 @@ func NewLogEventsPacker(utilsABI abi.ABI) *logEventsPacker { } func (p *logEventsPacker) PackLogData(log logpoller.Log) ([]byte, error) { - topics := [][32]byte{} + var topics [][32]byte for _, topic := range log.GetTopics() { topics = append(topics, topic) } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go index 52acb392e0e..ab816adb1b3 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go @@ -18,8 +18,7 @@ import ( var ( // LogRetention is the amount of time to retain logs for. LogRetention = 24 * time.Hour - // When adding a filter in log poller, backfill is done for this number of blocks - // from latest + // LogBackfillBuffer is the number of blocks from the latest block for which backfill is done when adding a filter in log poller LogBackfillBuffer = 100 ) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go index b1be71aad19..c1065b7e870 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -104,7 +104,7 @@ func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client clie return rec } -func (r *logRecoverer) Start(pctx context.Context) error { +func (r *logRecoverer) Start(_ context.Context) error { ctx, cancel := context.WithCancel(context.Background()) r.lock.Lock() @@ -441,7 +441,7 @@ func (r *logRecoverer) populatePending(f upkeepFilter, filteredLogs []logpoller. } // filterFinalizedStates filters out the log upkeeps that have already been completed (performed or ineligible). -func (r *logRecoverer) filterFinalizedStates(f upkeepFilter, logs []logpoller.Log, states []ocr2keepers.UpkeepState) []logpoller.Log { +func (r *logRecoverer) filterFinalizedStates(_ upkeepFilter, logs []logpoller.Log, states []ocr2keepers.UpkeepState) []logpoller.Log { filtered := make([]logpoller.Log, 0) for i, log := range logs { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go index 9351aa71d65..b14e687b5d1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go @@ -33,7 +33,7 @@ func (b *payloadBuilder) BuildPayloads(ctx context.Context, proposals ...ocr2kee var payload ocr2keepers.UpkeepPayload if b.upkeepList.IsActive(proposal.UpkeepID.BigInt()) { b.lggr.Debugf("building payload for coordinated block proposal %+v", proposal) - checkData := []byte{} + var checkData []byte var err error switch core.GetUpkeepType(proposal.UpkeepID) { case ocr2keepers.LogTrigger: diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go index 6c0ef78bbc4..e75084ff968 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go @@ -184,7 +184,6 @@ func TestNewPayloadBuilder(t *testing.T) { BlockNumber: 1, BlockHash: [32]byte{1}, }, - CheckData: make([]byte, 0), }, }, }, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go index ee0dfb7b252..751b94bde5c 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go @@ -155,7 +155,7 @@ func (r *EvmRegistry) Name() string { return r.lggr.Name() } -func (r *EvmRegistry) Start(ctx context.Context) error { +func (r *EvmRegistry) Start(_ context.Context) error { return r.sync.StartOnce("AutomationRegistry", func() error { r.mu.Lock() defer r.mu.Unlock() @@ -484,9 +484,9 @@ func RegistryUpkeepFilterName(addr common.Address) string { return logpoller.FilterName("KeeperRegistry Events", addr.String()) } -func (r *EvmRegistry) registerEvents(chainID uint64, addr common.Address) error { - // Add log filters for the log poller so that it can poll and find the logs that - // we need +// registerEvents registers upkeep state events from keeper registry on log poller +func (r *EvmRegistry) registerEvents(_ uint64, addr common.Address) error { + // Add log filters for the log poller so that it can poll and find the logs that we need return r.poller.RegisterFilter(logpoller.Filter{ Name: RegistryUpkeepFilterName(addr), EventSigs: upkeepStateEvents, @@ -494,7 +494,7 @@ func (r *EvmRegistry) registerEvents(chainID uint64, addr common.Address) error }) } -// Removes an upkeepID from active list and unregisters the log filter for log upkeeps +// removeFromActive removes an upkeepID from active list and unregisters the log filter for log upkeeps func (r *EvmRegistry) removeFromActive(id *big.Int) { r.active.Remove(id) @@ -565,6 +565,7 @@ func (r *EvmRegistry) getLatestIDsFromContract(ctx context.Context) ([]*big.Int, return ids, nil } +// updateTriggerConfig updates the trigger config for an upkeep. it will re-register a filter for this upkeep. func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint64) error { uid := &ocr2keepers.UpkeepIdentifier{} uid.FromBigInt(id) @@ -596,7 +597,7 @@ func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint return nil } -// updateTriggerConfig gets invoked upon changes in the trigger config of an upkeep. +// fetchTriggerConfig fetches trigger config in raw bytes for an upkeep. func (r *EvmRegistry) fetchTriggerConfig(id *big.Int) ([]byte, error) { opts := r.buildCallOpts(r.ctx, nil) cfg, err := r.registry.GetUpkeepTriggerConfig(opts, id) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go index 7a8991193c4..b9b04fabe43 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go @@ -98,7 +98,7 @@ func (r *EvmRegistry) getBlockHash(blockNumber *big.Int) (common.Hash, error) { } // verifyCheckBlock checks that the check block and hash are valid, returns the pipeline execution state and retryable -func (r *EvmRegistry) verifyCheckBlock(ctx context.Context, checkBlock, upkeepId *big.Int, checkHash common.Hash) (state encoding.PipelineExecutionState, retryable bool) { +func (r *EvmRegistry) verifyCheckBlock(_ context.Context, checkBlock, upkeepId *big.Int, checkHash common.Hash) (state encoding.PipelineExecutionState, retryable bool) { var h string var ok bool // verify check block number and hash are valid diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/services.go b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go index 1c666dc7cac..91479b5e619 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/services.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go @@ -28,7 +28,7 @@ import ( type AutomationServices interface { Registry() *EvmRegistry Encoder() ocr2keepers.Encoder - TransmitEventProvider() *transmit.TransmitEventProvider + TransmitEventProvider() *transmit.EventProvider BlockSubscriber() *BlockSubscriber PayloadBuilder() ocr2keepers.PayloadBuilder UpkeepStateStore() upkeepstate.UpkeepStateStore @@ -97,7 +97,7 @@ func New(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, k type automationServices struct { reg *EvmRegistry encoder ocr2keepers.Encoder - transmitEventProvider *transmit.TransmitEventProvider + transmitEventProvider *transmit.EventProvider blockSub *BlockSubscriber payloadBuilder ocr2keepers.PayloadBuilder upkeepState upkeepstate.UpkeepStateStore @@ -117,7 +117,7 @@ func (f *automationServices) Encoder() ocr2keepers.Encoder { return f.encoder } -func (f *automationServices) TransmitEventProvider() *transmit.TransmitEventProvider { +func (f *automationServices) TransmitEventProvider() *transmit.EventProvider { return f.transmitEventProvider } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go index a8c4ce93ad8..b0ae2a7bf63 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go @@ -18,11 +18,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -var _ ocr2keepers.TransmitEventProvider = &TransmitEventProvider{} +var _ ocr2keepers.TransmitEventProvider = &EventProvider{} type logParser func(registry *iregistry21.IKeeperRegistryMaster, log logpoller.Log) (transmitEventLog, error) -type TransmitEventProvider struct { +type EventProvider struct { sync utils.StartStopOnce mu sync.RWMutex runState int @@ -40,7 +40,7 @@ type TransmitEventProvider struct { cache transmitEventCache } -func TransmitEventProviderFilterName(addr common.Address) string { +func EventProviderFilterName(addr common.Address) string { return logpoller.FilterName("KeepersRegistry TransmitEventProvider", addr) } @@ -50,7 +50,7 @@ func NewTransmitEventProvider( registryAddress common.Address, client evmclient.Client, lookbackBlocks int64, -) (*TransmitEventProvider, error) { +) (*EventProvider, error) { var err error contract, err := iregistry21.NewIKeeperRegistryMaster(registryAddress, client) @@ -58,7 +58,7 @@ func NewTransmitEventProvider( return nil, err } err = logPoller.RegisterFilter(logpoller.Filter{ - Name: TransmitEventProviderFilterName(contract.Address()), + Name: EventProviderFilterName(contract.Address()), EventSigs: []common.Hash{ // These are the events that are emitted when a node transmits a report iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(), // Happy path: report performed the upkeep @@ -74,7 +74,7 @@ func NewTransmitEventProvider( return nil, err } - return &TransmitEventProvider{ + return &EventProvider{ logger: logger, logPoller: logPoller, registryAddress: registryAddress, @@ -86,11 +86,11 @@ func NewTransmitEventProvider( }, nil } -func (c *TransmitEventProvider) Name() string { +func (c *EventProvider) Name() string { return c.logger.Name() } -func (c *TransmitEventProvider) Start(ctx context.Context) error { +func (c *EventProvider) Start(_ context.Context) error { return c.sync.StartOnce("AutomationTransmitEventProvider", func() error { c.mu.Lock() defer c.mu.Unlock() @@ -100,7 +100,7 @@ func (c *TransmitEventProvider) Start(ctx context.Context) error { }) } -func (c *TransmitEventProvider) Close() error { +func (c *EventProvider) Close() error { return c.sync.StopOnce("AutomationRegistry", func() error { c.mu.Lock() defer c.mu.Unlock() @@ -111,7 +111,7 @@ func (c *TransmitEventProvider) Close() error { }) } -func (c *TransmitEventProvider) Ready() error { +func (c *EventProvider) Ready() error { c.mu.RLock() defer c.mu.RUnlock() @@ -121,7 +121,7 @@ func (c *TransmitEventProvider) Ready() error { return c.sync.Ready() } -func (c *TransmitEventProvider) HealthReport() map[string]error { +func (c *EventProvider) HealthReport() map[string]error { c.mu.RLock() defer c.mu.RUnlock() @@ -131,7 +131,7 @@ func (c *TransmitEventProvider) HealthReport() map[string]error { return map[string]error{c.Name(): c.sync.Healthy()} } -func (c *TransmitEventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.TransmitEvent, error) { +func (c *EventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.TransmitEvent, error) { end, err := c.logPoller.LatestBlock(pg.WithParentCtx(ctx)) if err != nil { return nil, fmt.Errorf("%w: failed to get latest block from log poller", err) @@ -159,8 +159,8 @@ func (c *TransmitEventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keep } // processLogs will parse the unseen logs and return the corresponding transmit events. -func (c *TransmitEventProvider) processLogs(latestBlock int64, logs ...logpoller.Log) ([]ocr2keepers.TransmitEvent, error) { - vals := []ocr2keepers.TransmitEvent{} +func (c *EventProvider) processLogs(latestBlock int64, logs ...logpoller.Log) ([]ocr2keepers.TransmitEvent, error) { + var vals []ocr2keepers.TransmitEvent for _, log := range logs { k := c.logKey(log) @@ -214,7 +214,7 @@ func (c *TransmitEventProvider) processLogs(latestBlock int64, logs ...logpoller return vals, nil } -func (c *TransmitEventProvider) logKey(log logpoller.Log) string { +func (c *EventProvider) logKey(log logpoller.Log) string { logExt := ocr2keepers.LogTriggerExtension{ TxHash: log.TxHash, Index: uint32(log.LogIndex), diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go index 8e08008eca4..5cb60d5dc1d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go @@ -26,7 +26,7 @@ func NewUpkeepProvider(activeUpkeeps ActiveUpkeepList, bs *BlockSubscriber, lp l } } -func (p *upkeepProvider) GetActiveUpkeeps(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { +func (p *upkeepProvider) GetActiveUpkeeps(_ context.Context) ([]ocr2keepers.UpkeepPayload, error) { latestBlock := p.bs.latestBlock.Load() if latestBlock == nil { return nil, fmt.Errorf("no latest block found when fetching active upkeeps") @@ -35,7 +35,7 @@ func (p *upkeepProvider) GetActiveUpkeeps(ctx context.Context) ([]ocr2keepers.Up for _, uid := range p.activeUpkeeps.View(ocr2keepers.ConditionTrigger) { payload, err := core.NewUpkeepPayload( uid, - ocr2keepers.NewTrigger(ocr2keepers.BlockNumber(latestBlock.Number), latestBlock.Hash), + ocr2keepers.NewTrigger(latestBlock.Number, latestBlock.Hash), nil, ) if err != nil { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go index 11a498d63cd..9ce9a10ac73 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go @@ -62,7 +62,7 @@ func (s *performedEventsScanner) Start(_ context.Context) error { }) } -// implements io.Closer, does nothing upon close +// Close implements io.Closer and does nothing func (s *performedEventsScanner) Close() error { return nil } diff --git a/core/services/ocr2/plugins/ocr2keeper/util.go b/core/services/ocr2/plugins/ocr2keeper/util.go index ff1cd0940dd..132afd0d29d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/util.go +++ b/core/services/ocr2/plugins/ocr2keeper/util.go @@ -140,5 +140,5 @@ func FilterNamesFromSpec21(spec *job.OCR2OracleSpec) (names []string, err error) if err != nil { return nil, err } - return []string{kevm21transmit.TransmitEventProviderFilterName(addr.Address()), kevm21.RegistryUpkeepFilterName(addr.Address())}, err + return []string{kevm21transmit.EventProviderFilterName(addr.Address()), kevm21.RegistryUpkeepFilterName(addr.Address())}, err } From 0b26676a0ee0f7d13c831bc88aee6984be953a1e Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 8 Sep 2023 21:29:58 +0200 Subject: [PATCH 73/88] bump prettier, solhint & eslint (#10569) * bump prettier 2.8.8 -> 3.0.3 * bump solhint 3.4.1 -> 3.6.2 * bump eslint deps --- contracts/package.json | 14 +- contracts/pnpm-lock.yaml | 579 +++++++++++++----- contracts/test/v0.7/Operator.test.ts | 20 +- .../test/v0.8/automation/CronUpkeep.test.ts | 10 +- .../v0.8/automation/KeeperRegistry2_1.test.ts | 5 +- .../automation/UpkeepTranscoder3_0.test.ts | 5 +- .../automation/UpkeepTranscoder4_0.test.ts | 5 +- .../dev/OptimismCrossDomainForwarder.test.ts | 5 +- .../dev/OptimismCrossDomainGovernor.test.ts | 5 +- .../v0.8/functions/v0/FunctionsOracle.test.ts | 10 +- 10 files changed, 448 insertions(+), 210 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 5f7a8c3d325..2683b49cc02 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -51,15 +51,15 @@ "@types/deep-equal-in-any-order": "^1.0.1", "@types/mocha": "^8.2.2", "@types/node": "^15.12.2", - "@typescript-eslint/eslint-plugin": "^5.59.5", - "@typescript-eslint/parser": "^5.59.5", + "@typescript-eslint/eslint-plugin": "^6.6.0", + "@typescript-eslint/parser": "^6.6.0", "abi-to-sol": "^0.6.6", "chai": "^4.3.4", "debug": "^4.3.2", - "eslint": "^8.40.0", - "eslint-config-prettier": "^8.8.0", + "eslint": "^8.48.0", + "eslint-config-prettier": "^9.0.0", "deep-equal-in-any-order": "^2.0.6", - "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-prettier": "^5.0.0", "ethereum-waffle": "^3.3.0", "ethers": "~5.6.0", "hardhat": "~2.12.7", @@ -69,10 +69,10 @@ "hardhat-ignore-warnings": "^0.2.6", "istanbul": "^0.4.5", "moment": "^2.29.4", - "prettier": "^2.8.8", + "prettier": "^3.0.3", "prettier-plugin-solidity": "1.1.3", "rlp": "^2.0.0", - "solhint": "^3.4.1", + "solhint": "^3.6.2", "solhint-plugin-prettier": "^0.0.5", "solidity-coverage": "^0.8.4", "ts-node": "^10.0.0", diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index da673532152..fde49eb9fdc 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -83,11 +83,11 @@ devDependencies: specifier: ^15.12.2 version: 15.14.9 '@typescript-eslint/eslint-plugin': - specifier: ^5.59.5 - version: 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@4.9.5) + specifier: ^6.6.0 + version: 6.6.0(@typescript-eslint/parser@6.6.0)(eslint@8.48.0)(typescript@4.9.5) '@typescript-eslint/parser': - specifier: ^5.59.5 - version: 5.59.8(eslint@8.42.0)(typescript@4.9.5) + specifier: ^6.6.0 + version: 6.6.0(eslint@8.48.0)(typescript@4.9.5) abi-to-sol: specifier: ^0.6.6 version: 0.6.6 @@ -101,14 +101,14 @@ devDependencies: specifier: ^2.0.6 version: 2.0.6 eslint: - specifier: ^8.40.0 - version: 8.42.0 + specifier: ^8.48.0 + version: 8.48.0 eslint-config-prettier: - specifier: ^8.8.0 - version: 8.8.0(eslint@8.42.0) + specifier: ^9.0.0 + version: 9.0.0(eslint@8.48.0) eslint-plugin-prettier: - specifier: ^4.2.1 - version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8) + specifier: ^5.0.0 + version: 5.0.0(eslint-config-prettier@9.0.0)(eslint@8.48.0)(prettier@3.0.3) ethereum-waffle: specifier: ^3.3.0 version: 3.3.0(typescript@4.9.5) @@ -137,20 +137,20 @@ devDependencies: specifier: ^2.29.4 version: 2.29.4 prettier: - specifier: ^2.8.8 - version: 2.8.8 + specifier: ^3.0.3 + version: 3.0.3 prettier-plugin-solidity: specifier: 1.1.3 - version: 1.1.3(prettier@2.8.8) + version: 1.1.3(prettier@3.0.3) rlp: specifier: ^2.0.0 version: 2.2.7 solhint: - specifier: ^3.4.1 - version: 3.4.1 + specifier: ^3.6.2 + version: 3.6.2 solhint-plugin-prettier: specifier: ^0.0.5 - version: 0.0.5(prettier-plugin-solidity@1.1.3)(prettier@2.8.8) + version: 0.0.5(prettier-plugin-solidity@1.1.3)(prettier@3.0.3) solidity-coverage: specifier: ^0.8.4 version: 0.8.4(hardhat@2.12.7) @@ -169,6 +169,11 @@ devDependencies: packages: + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + /@babel/code-frame@7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -248,14 +253,14 @@ packages: deprecated: Please use @ensdomains/ens-contracts dev: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.48.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.42.0 - eslint-visitor-keys: 3.4.1 + eslint: 8.48.0 + eslint-visitor-keys: 3.4.3 dev: true /@eslint-community/regexpp@4.5.1: @@ -263,13 +268,18 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.0.3: - resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==} + /@eslint-community/regexpp@4.8.0: + resolution: {integrity: sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4(supports-color@8.1.1) - espree: 9.5.2 + espree: 9.6.1 globals: 13.20.0 ignore: 5.2.4 import-fresh: 3.3.0 @@ -280,8 +290,8 @@ packages: - supports-color dev: true - /@eslint/js@8.42.0: - resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==} + /@eslint/js@8.48.0: + resolution: {integrity: sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -1440,6 +1450,18 @@ packages: - supports-color dev: true + /@pkgr/utils@2.4.2: + resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==} + 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 + /@resolver-engine/core@0.3.3: resolution: {integrity: sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==} dependencies: @@ -1850,8 +1872,8 @@ packages: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true - /@types/json-schema@7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + /@types/json-schema@7.0.12: + resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} dev: true /@types/keyv@3.1.4: @@ -1969,133 +1991,134 @@ packages: '@types/underscore': 1.11.4 dev: true - /@typescript-eslint/eslint-plugin@5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@4.9.5): - resolution: {integrity: sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/eslint-plugin@6.6.0(@typescript-eslint/parser@6.6.0)(eslint@8.48.0)(typescript@4.9.5): + resolution: {integrity: sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/type-utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5) + '@typescript-eslint/parser': 6.6.0(eslint@8.48.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 6.6.0 + '@typescript-eslint/type-utils': 6.6.0(eslint@8.48.0)(typescript@4.9.5) + '@typescript-eslint/utils': 6.6.0(eslint@8.48.0)(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 6.6.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.42.0 - grapheme-splitter: 1.0.4 + eslint: 8.48.0 + graphemer: 1.4.0 ignore: 5.2.4 - natural-compare-lite: 1.4.0 - semver: 7.5.0 - tsutils: 3.21.0(typescript@4.9.5) + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@5.59.8(eslint@8.42.0)(typescript@4.9.5): - resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/parser@6.6.0(eslint@8.48.0)(typescript@4.9.5): + resolution: {integrity: sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) + '@typescript-eslint/scope-manager': 6.6.0 + '@typescript-eslint/types': 6.6.0 + '@typescript-eslint/typescript-estree': 6.6.0(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 6.6.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.42.0 + eslint: 8.48.0 typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@5.59.8: - resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/scope-manager@6.6.0: + resolution: {integrity: sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==} + engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 + '@typescript-eslint/types': 6.6.0 + '@typescript-eslint/visitor-keys': 6.6.0 dev: true - /@typescript-eslint/type-utils@5.59.8(eslint@8.42.0)(typescript@4.9.5): - resolution: {integrity: sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/type-utils@6.6.0(eslint@8.48.0)(typescript@4.9.5): + resolution: {integrity: sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: '*' + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 6.6.0(typescript@4.9.5) + '@typescript-eslint/utils': 6.6.0(eslint@8.48.0)(typescript@4.9.5) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.42.0 - tsutils: 3.21.0(typescript@4.9.5) + eslint: 8.48.0 + ts-api-utils: 1.0.3(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@5.59.8: - resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/types@6.6.0: + resolution: {integrity: sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==} + engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@5.59.8(typescript@4.9.5): - resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/typescript-estree@6.6.0(typescript@4.9.5): + resolution: {integrity: sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 + '@typescript-eslint/types': 6.6.0 + '@typescript-eslint/visitor-keys': 6.6.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.0 - tsutils: 3.21.0(typescript@4.9.5) + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.59.8(eslint@8.42.0)(typescript@4.9.5): - resolution: {integrity: sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/utils@6.6.0(eslint@8.48.0)(typescript@4.9.5): + resolution: {integrity: sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) - '@types/json-schema': 7.0.11 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) + '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - eslint: 8.42.0 - eslint-scope: 5.1.1 - semver: 7.5.0 + '@typescript-eslint/scope-manager': 6.6.0 + '@typescript-eslint/types': 6.6.0 + '@typescript-eslint/typescript-estree': 6.6.0(typescript@4.9.5) + eslint: 8.48.0 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@5.59.8: - resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/visitor-keys@6.6.0: + resolution: {integrity: sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==} + engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 5.59.8 + '@typescript-eslint/types': 6.6.0 eslint-visitor-keys: 3.4.1 dev: true @@ -2187,16 +2210,16 @@ packages: negotiator: 0.6.2 dev: true - /acorn-jsx@5.3.2(acorn@8.8.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 dependencies: - acorn: 8.8.0 + acorn: 8.10.0 dev: true - /acorn@8.8.0: - resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -3109,6 +3132,11 @@ 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 @@ -3200,6 +3228,13 @@ 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: @@ -3375,6 +3410,13 @@ 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'} @@ -3880,7 +3922,7 @@ packages: dev: true /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} dev: true /concat-stream@1.6.2: @@ -4242,6 +4284,24 @@ 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==} requiresBuild: true @@ -4266,6 +4326,11 @@ packages: inherits: 2.0.4 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'} @@ -4645,42 +4710,38 @@ packages: source-map: 0.2.0 dev: true - /eslint-config-prettier@8.8.0(eslint@8.42.0): - resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + /eslint-config-prettier@9.0.0(eslint@8.48.0): + resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.42.0 + eslint: 8.48.0 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8): - resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} - engines: {node: '>=12.0.0'} + /eslint-plugin-prettier@5.0.0(eslint-config-prettier@9.0.0)(eslint@8.48.0)(prettier@3.0.3): + resolution: {integrity: sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==} + engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - eslint: '>=7.28.0' + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' eslint-config-prettier: '*' - prettier: '>=2.0.0' + prettier: '>=3.0.0' peerDependenciesMeta: + '@types/eslint': + optional: true eslint-config-prettier: optional: true dependencies: - eslint: 8.42.0 - eslint-config-prettier: 8.8.0(eslint@8.42.0) - prettier: 2.8.8 + eslint: 8.48.0 + eslint-config-prettier: 9.0.0(eslint@8.48.0) + prettier: 3.0.3 prettier-linter-helpers: 1.0.0 + synckit: 0.8.5 dev: true - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true - - /eslint-scope@7.2.0: - resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} + /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: esrecurse: 4.3.0 @@ -4692,15 +4753,20 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.42.0: - resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==} + /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.48.0: + resolution: {integrity: sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) - '@eslint-community/regexpp': 4.5.1 - '@eslint/eslintrc': 2.0.3 - '@eslint/js': 8.42.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) + '@eslint-community/regexpp': 4.8.0 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.48.0 '@humanwhocodes/config-array': 0.11.10 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -4710,9 +4776,9 @@ packages: debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.0 - eslint-visitor-keys: 3.4.1 - espree: 9.5.2 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -4721,8 +4787,7 @@ packages: glob-parent: 6.0.2 globals: 13.20.0 graphemer: 1.4.0 - ignore: 5.2.0 - import-fresh: 3.3.0 + ignore: 5.2.4 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -4732,21 +4797,20 @@ packages: lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.1 + optionator: 0.9.3 strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 text-table: 0.2.0 transitivePeerDependencies: - supports-color dev: true - /espree@9.5.2: - resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==} + /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.8.0 - acorn-jsx: 5.3.2(acorn@8.8.0) - eslint-visitor-keys: 3.4.1 + 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: @@ -4780,11 +4844,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -5300,6 +5359,36 @@ 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'} @@ -5436,6 +5525,17 @@ packages: micromatch: 4.0.5 dev: true + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true @@ -6494,6 +6594,16 @@ 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'} @@ -6519,11 +6629,6 @@ packages: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true - /ignore@5.2.0: - resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} - engines: {node: '>= 4'} - dev: true - /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} @@ -6727,6 +6832,12 @@ 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'} @@ -6792,6 +6903,14 @@ 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: @@ -6872,6 +6991,16 @@ 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'} @@ -7664,6 +7793,10 @@ 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'} @@ -7754,6 +7887,16 @@ 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'} @@ -8064,10 +8207,6 @@ packages: resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} dev: true - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true - /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true @@ -8191,6 +8330,20 @@ 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: @@ -8324,6 +8477,20 @@ 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'} @@ -8332,6 +8499,16 @@ 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'} @@ -8344,16 +8521,16 @@ packages: word-wrap: 1.2.3 dev: true - /optionator@0.9.1: - resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 - word-wrap: 1.2.3 dev: true /os-homedir@1.0.2: @@ -8629,6 +8806,11 @@ 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 @@ -8669,6 +8851,10 @@ 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'} @@ -8755,6 +8941,19 @@ packages: semver: 7.5.0 solidity-comments-extractor: 0.0.7 dev: true + optional: true + + /prettier-plugin-solidity@1.1.3(prettier@3.0.3): + resolution: {integrity: sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==} + engines: {node: '>=12'} + peerDependencies: + prettier: '>=2.3.0 || >=3.0.0-alpha.0' + dependencies: + '@solidity-parser/parser': 0.16.0 + prettier: 3.0.3 + semver: 7.5.0 + solidity-comments-extractor: 0.0.7 + dev: true /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} @@ -8762,6 +8961,12 @@ packages: hasBin: true dev: true + /prettier@3.0.3: + resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} + engines: {node: '>=14'} + hasBin: true + dev: true + /private@0.1.8: resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} engines: {node: '>= 0.6'} @@ -9319,6 +9524,13 @@ 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: @@ -9466,6 +9678,14 @@ packages: lru-cache: 6.0.0 dev: true + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /send@0.17.1: resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==} engines: {node: '>= 0.8.0'} @@ -9756,19 +9976,19 @@ packages: - debug dev: true - /solhint-plugin-prettier@0.0.5(prettier-plugin-solidity@1.1.3)(prettier@2.8.8): + /solhint-plugin-prettier@0.0.5(prettier-plugin-solidity@1.1.3)(prettier@3.0.3): resolution: {integrity: sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA==} peerDependencies: prettier: ^1.15.0 || ^2.0.0 prettier-plugin-solidity: ^1.0.0-alpha.14 dependencies: - prettier: 2.8.8 + prettier: 3.0.3 prettier-linter-helpers: 1.0.0 - prettier-plugin-solidity: 1.1.3(prettier@2.8.8) + prettier-plugin-solidity: 1.1.3(prettier@3.0.3) dev: true - /solhint@3.4.1: - resolution: {integrity: sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==} + /solhint@3.6.2: + resolution: {integrity: sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ==} hasBin: true dependencies: '@solidity-parser/parser': 0.16.0 @@ -9784,7 +10004,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 pluralize: 8.0.0 - semver: 6.3.0 + semver: 7.5.4 strip-ansi: 6.0.1 table: 6.8.1 text-table: 0.2.0 @@ -10209,6 +10429,16 @@ 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'} @@ -10318,6 +10548,14 @@ packages: get-port: 3.2.0 dev: true + /synckit@0.8.5: + resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} + engines: {node: ^14.18.0 || >=16.0.0} + dependencies: + '@pkgr/utils': 2.4.2 + tslib: 2.6.2 + dev: true + /table-layout@1.0.2: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} @@ -10441,6 +10679,11 @@ 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'} @@ -10525,6 +10768,15 @@ packages: engines: {node: '>=0.10.0'} dev: true + /ts-api-utils@1.0.3(typescript@4.9.5): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 4.9.5 + dev: true + /ts-command-line-args@2.5.1: resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} hasBin: true @@ -10607,18 +10859,12 @@ packages: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: true - /tsort@0.0.1: - resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: true - /tsutils@3.21.0(typescript@4.9.5): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 4.9.5 + /tsort@0.0.1: + resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} dev: true /tunnel-agent@0.6.0: @@ -10846,6 +11092,11 @@ 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: diff --git a/contracts/test/v0.7/Operator.test.ts b/contracts/test/v0.7/Operator.test.ts index 251ee65a7ae..4af846576b3 100644 --- a/contracts/test/v0.7/Operator.test.ts +++ b/contracts/test/v0.7/Operator.test.ts @@ -1024,9 +1024,8 @@ describe('Operator', () => { .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) - const tx = await gasGuzzlingConsumer.gassyRequestEthereumPrice( - paymentAmount, - ) + const tx = + await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) @@ -1480,9 +1479,8 @@ describe('Operator', () => { .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) - const tx = await gasGuzzlingConsumer.gassyRequestEthereumPrice( - paymentAmount, - ) + const tx = + await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) @@ -2087,9 +2085,8 @@ describe('Operator', () => { .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) - const tx = await gasGuzzlingConsumer.gassyMultiWordRequest( - paymentAmount, - ) + const tx = + await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) @@ -2604,9 +2601,8 @@ describe('Operator', () => { .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) - const tx = await gasGuzzlingConsumer.gassyMultiWordRequest( - paymentAmount, - ) + const tx = + await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) diff --git a/contracts/test/v0.8/automation/CronUpkeep.test.ts b/contracts/test/v0.8/automation/CronUpkeep.test.ts index 755b4494c81..f153345b570 100644 --- a/contracts/test/v0.8/automation/CronUpkeep.test.ts +++ b/contracts/test/v0.8/automation/CronUpkeep.test.ts @@ -321,12 +321,10 @@ describe('CronUpkeep', () => { it('creates jobs with sequential IDs', async () => { const cronString1 = '0 * * * *' const cronString2 = '0 1,2,3 */4 5-6 1-2' - const encodedSpec1 = await cronFactoryContract.encodeCronString( - cronString1, - ) - const encodedSpec2 = await cronFactoryContract.encodeCronString( - cronString2, - ) + const encodedSpec1 = + await cronFactoryContract.encodeCronString(cronString1) + const encodedSpec2 = + await cronFactoryContract.encodeCronString(cronString2) const nextTick1 = ( await cronTestHelper.calculateNextTick(cronString1) ).toNumber() diff --git a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts index b65f2faea50..2f83c133705 100644 --- a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts +++ b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts @@ -474,9 +474,8 @@ describe('KeeperRegistry2_1', () => { 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', )) as unknown as MockV3AggregatorFactory upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') - upkeepAutoFunderFactory = await ethers.getContractFactory( - 'UpkeepAutoFunder', - ) + upkeepAutoFunderFactory = + await ethers.getContractFactory('UpkeepAutoFunder') mockArbGasInfoFactory = await ethers.getContractFactory('MockArbGasInfo') mockOVMGasPriceOracleFactory = await ethers.getContractFactory( 'MockOVMGasPriceOracle', diff --git a/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts b/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts index 8bad7f63873..2f0f169ab1f 100644 --- a/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts +++ b/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts @@ -164,9 +164,8 @@ async function deployLegacyRegistry1_2( ) { const mock = await upkeepMockFactory.deploy() // @ts-ignore bug in autogen file - const keeperRegistryFactory = await ethers.getContractFactory( - 'KeeperRegistry1_2', - ) + const keeperRegistryFactory = + await ethers.getContractFactory('KeeperRegistry1_2') transcoder = await upkeepTranscoderFactory.connect(owner).deploy() const legacyRegistry = await keeperRegistryFactory .connect(owner) diff --git a/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts b/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts index e6b74d41bd9..970054893d2 100644 --- a/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts +++ b/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts @@ -140,9 +140,8 @@ const encodeUpkeepV12 = (ids: number[], upkeeps: any[], checkDatas: any[]) => { } async function deployRegistry1_2(): Promise<[BigNumber, KeeperRegistry1_2]> { - const keeperRegistryFactory = await ethers.getContractFactory( - 'KeeperRegistry1_2', - ) + const keeperRegistryFactory = + await ethers.getContractFactory('KeeperRegistry1_2') const registry12 = await keeperRegistryFactory .connect(owner) .deploy(linkToken.address, linkEthFeed.address, gasPriceFeed.address, { diff --git a/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts b/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts index 76f0e6ddf0a..3b75b412bfd 100644 --- a/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts +++ b/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts @@ -40,9 +40,8 @@ before(async () => { describe('OptimismCrossDomainForwarder', () => { beforeEach(async () => { - crossDomainMessenger = await crossDomainMessengerFactory.deploy( - l1OwnerAddress, - ) + crossDomainMessenger = + await crossDomainMessengerFactory.deploy(l1OwnerAddress) forwarder = await forwarderFactory.deploy( crossDomainMessenger.address, l1OwnerAddress, diff --git a/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts b/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts index cedc90ab9a9..9ea425bb995 100644 --- a/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts +++ b/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts @@ -46,9 +46,8 @@ before(async () => { describe('OptimismCrossDomainGovernor', () => { beforeEach(async () => { - crossDomainMessenger = await crossDomainMessengerFactory.deploy( - l1OwnerAddress, - ) + crossDomainMessenger = + await crossDomainMessengerFactory.deploy(l1OwnerAddress) governor = await governorFactory.deploy( crossDomainMessenger.address, l1OwnerAddress, diff --git a/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts b/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts index ae44e1b037e..921c60bfc8f 100644 --- a/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts +++ b/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts @@ -351,9 +351,8 @@ describe('FunctionsOracle', () => { }) it('#estimateCost correctly estimates cost [ @skip-coverage ]', async () => { - const [subscriptionBalanceBefore] = await registry.getSubscription( - subscriptionId, - ) + const [subscriptionBalanceBefore] = + await registry.getSubscription(subscriptionId) const request = await client .connect(roles.oracleNode) @@ -376,9 +375,8 @@ describe('FunctionsOracle', () => { .withArgs(requestId, transmitter) .to.emit(registry, 'BillingEnd') - const [subscriptionBalanceAfter] = await registry.getSubscription( - subscriptionId, - ) + const [subscriptionBalanceAfter] = + await registry.getSubscription(subscriptionId) const feeData = await ethers.provider.getFeeData() const estimatedCost = await client.estimateJuelCost( From 4620df0ff6d3d21a7291dcd6997594587a04b646 Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal <71980293+infiloop2@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:20:51 +0100 Subject: [PATCH 74/88] Update to ocr2keepers 0.7.22 (#10568) --- 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 9e493f84df7..76c1711d093 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,7 +19,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.21 + github.com/smartcontractkit/ocr2keepers v0.7.22 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/spf13/cobra v1.6.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index afae317ebbc..663fe3e046a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.21 h1:64CNFoUYVpoJqhQ39WTPIEKVKB5Z/wderX0pIsv/tbA= -github.com/smartcontractkit/ocr2keepers v0.7.21/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.22 h1:qMWy1/j7k3dA1NAxEyRF4iPrhH2gmricbBEXSlxRTSk= +github.com/smartcontractkit/ocr2keepers v0.7.22/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/go.mod b/go.mod index ebacf922178..d458408b70d 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.21 + github.com/smartcontractkit/ocr2keepers v0.7.22 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e diff --git a/go.sum b/go.sum index 85a7b18f8b5..36f20b94961 100644 --- a/go.sum +++ b/go.sum @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.21 h1:64CNFoUYVpoJqhQ39WTPIEKVKB5Z/wderX0pIsv/tbA= -github.com/smartcontractkit/ocr2keepers v0.7.21/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.22 h1:qMWy1/j7k3dA1NAxEyRF4iPrhH2gmricbBEXSlxRTSk= +github.com/smartcontractkit/ocr2keepers v0.7.22/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e4f61c32b7d..553b73e9473 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -23,7 +23,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.21 + github.com/smartcontractkit/ocr2keepers v0.7.22 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230829114801-14bf715f805e github.com/smartcontractkit/wasp v0.3.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index cd3f8b20a2c..e11b633b636 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2266,8 +2266,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.21 h1:64CNFoUYVpoJqhQ39WTPIEKVKB5Z/wderX0pIsv/tbA= -github.com/smartcontractkit/ocr2keepers v0.7.21/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.22 h1:qMWy1/j7k3dA1NAxEyRF4iPrhH2gmricbBEXSlxRTSk= +github.com/smartcontractkit/ocr2keepers v0.7.22/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= From a4ae3d48c46d7c55152b70ae4fe96d838753f846 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Fri, 8 Sep 2023 17:27:32 -0400 Subject: [PATCH 75/88] [Functions] Subscription deposit (#10513) * (feat): Add Functions subscription deposit * Reduce FunctionsRouter.sol contract size * Changes from review, cut more contract size, & add getSubscriptionsInRange method * Add tests & changes from review * Changes from review * Additional changes * checkDepositRefundability logic reflects name * Requested changes * Update gas snapshot & natspec comments * More changes from code review * (fix): amend unreachable code * (test): Amend hardhat test * (test): Amend go integration test SubscriptionDepositMinimumRequests naming --- .../gas-snapshots/functions.gas-snapshot | 223 +++++++++--------- .../functions/dev/1_0_0/FunctionsBilling.sol | 15 +- .../functions/dev/1_0_0/FunctionsRouter.sol | 69 +++--- .../dev/1_0_0/FunctionsSubscriptions.sol | 114 +++++---- .../1_0_0/interfaces/IFunctionsBilling.sol | 2 +- .../interfaces/IFunctionsSubscriptions.sol | 9 + .../tests/1_0_0/FunctionsRouter.t.sol | 7 +- .../tests/1_0_0/FunctionsSubscriptions.t.sol | 221 ++++++++++++++++- .../v0.8/functions/tests/1_0_0/Setup.t.sol | 6 +- .../v1/FunctionsSubscriptions.test.ts | 11 +- contracts/test/v0.8/functions/v1/utils.ts | 4 + .../functions_coordinator.go | 4 +- .../functions_router/functions_router.go | 42 +++- ...rapper-dependency-versions-do-not-edit.txt | 4 +- .../v1/internal/testutils.go | 12 +- 15 files changed, 523 insertions(+), 220 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 9a1ebe16603..da2a8f49583 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,7 +1,7 @@ FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32391) -FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 52979) +FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 53002) FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13274) -FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 147058) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 146635) FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13452) FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974) FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255) @@ -13,138 +13,143 @@ FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35791) FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987) FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12073) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 48277) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 38808) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 36217) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35161) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 48079) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 38613) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 36022) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35147) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 210) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28015) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 33206) -FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 93612) -FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 103408) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 1762929) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 206005) -FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17842) -FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12883) -FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 31332) -FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13893) -FunctionsRouter_GetContractById:test_GetContractById_SuccessIfRouteExists() (gas: 17417) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 27993) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 33184) +FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 93416) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 103212) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 1762498) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 205574) +FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 18005) +FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12926) +FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 37136) +FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13871) +FunctionsRouter_GetContractById:test_GetContractById_SuccessIfRouteExists() (gas: 17395) FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16382) FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 23934) -FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 25935) -FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 25509) +FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 25958) +FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 28034) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41004) -FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 22027) +FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24551) FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13315) -FunctionsRouter_Pause:test_Pause_Success() (gas: 20254) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14790) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 22683) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengthMismatch() (gas: 14669) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19047) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23348) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118768) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 58977) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 192424) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29382) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57929) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186033) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 48353) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25038) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29088) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34224) -FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 197881) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65518) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36013) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29876) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 54984) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27504) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35718) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40788) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 204484) -FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192597) -FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30666) -FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13402) -FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13294) -FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77334) -FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21909) -FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 51123) -FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13315) -FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 38715) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60355) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 60984) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94703) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62713) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 59611) +FunctionsRouter_Pause:test_Pause_Success() (gas: 20298) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14768) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 22661) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengthMismatch() (gas: 14647) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19025) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23326) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118413) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59304) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 192143) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29405) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57926) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 185987) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50902) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25061) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29111) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34247) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 197669) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65800) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 35991) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29897) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 57488) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27482) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35696) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40766) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 204227) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192506) +FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30687) +FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13380) +FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13337) +FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77421) +FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24437) +FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 60653) +FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13293) +FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 38716) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60333) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 60962) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94681) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62691) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 59679) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137833) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 161337) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164777) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12926) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57789) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87166) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18051) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95391) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15041) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57863) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89296) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20103) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193411) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_Success() (gas: 67209) -FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7609) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28659) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17970) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 371776) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95481) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15085) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57929) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89340) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20191) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193277) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114636) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 125891) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessRecieveDeposit() (gas: 312021) +FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7654) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28637) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17948) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 371980) FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 16225) -FunctionsSubscriptions_GetFlags:test_GetFlags_Success() (gas: 40880) -FunctionsSubscriptions_GetSubscription:test_GetSubscription_Success() (gas: 30869) +FunctionsSubscriptions_GetFlags:test_GetFlags_Success() (gas: 40858) +FunctionsSubscriptions_GetSubscription:test_GetSubscription_Success() (gas: 30959) FunctionsSubscriptions_GetSubscriptionCount:test_GetSubscriptionCount_Success() (gas: 12967) +FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 16523) +FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfStartIsAfterEnd() (gas: 13436) +FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 59568) FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15032) -FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCalldata() (gas: 27616) -FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 30093) -FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13424) -FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 35022) -FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 56121) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCalldata() (gas: 27594) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 30071) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13402) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 35000) +FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 56279) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20745) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfBalanceInvariant() (gas: 189) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15638) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfPaused() (gas: 20833) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 59873) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessSetsBalanceToZero() (gas: 57842) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 59732) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessSetsBalanceToZero() (gas: 57701) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12818) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15549) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 52817) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 47539) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 48847) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 162049) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17946) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 54867) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 49624) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 50896) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 163911) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17924) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 165) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15577) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 37559) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54598) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37975) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14980) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175601) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27632) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57751) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15022) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 75152) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17981) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20126) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68148) -FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15554) -FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41111) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 29946) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 37396) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54435) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 15025) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175411) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27610) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57707) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15000) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 75130) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17959) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20104) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68216) +FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15532) +FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41093) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30238) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 14997) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57778) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87210) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18004) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190639) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 41585) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190701) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 41979) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12847) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15640) -FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35571) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25881) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25210) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28164) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57759) +FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35549) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25859) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25188) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28142) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57634) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26368) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15714) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152510) @@ -153,7 +158,7 @@ FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_ FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23615) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1458273) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26021) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1538361) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1538382) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 94702) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 50442) diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol index b0d83c5e061..5518bad1513 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol @@ -260,14 +260,14 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { ) internal returns (FunctionsResponse.FulfillResult) { FunctionsResponse.Commitment memory commitment = abi.decode(onchainMetadata, (FunctionsResponse.Commitment)); - if (s_requestCommitments[requestId] != keccak256(abi.encode(commitment))) { - return FunctionsResponse.FulfillResult.INVALID_COMMITMENT; - } - if (s_requestCommitments[requestId] == bytes32(0)) { return FunctionsResponse.FulfillResult.INVALID_REQUEST_ID; } + if (s_requestCommitments[requestId] != keccak256(abi.encode(commitment))) { + return FunctionsResponse.FulfillResult.INVALID_COMMITMENT; + } + uint96 juelsPerGas = _getJuelsPerGas(tx.gasprice); // Gas overhead without callback uint96 gasOverheadJuels = juelsPerGas * @@ -308,15 +308,10 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // @inheritdoc IFunctionsBilling // @dev Only callable by the Router // @dev Used by FunctionsRouter.sol during timeout of a request - function deleteCommitment(bytes32 requestId) external override onlyRouter returns (bool) { - // Ensure that commitment exists - if (s_requestCommitments[requestId] == bytes32(0)) { - return false; - } + function deleteCommitment(bytes32 requestId) external override onlyRouter { // Delete commitment delete s_requestCommitments[requestId]; emit CommitmentDeleted(requestId); - return true; } // ================================================================ diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol index abc3921fb0c..1d09b1e6739 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol @@ -85,11 +85,13 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // | Configuration state | // ================================================================ struct Config { - uint16 maxConsumersPerSubscription; // ══════╗ Maximum number of consumers which can be added to a single subscription. This bound ensures we are able to loop over all subscription consumers as needed, without exceeding gas limits. Should a user require more consumers, they can use multiple subscriptions. - uint72 adminFee; // ║ Flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network - bytes4 handleOracleFulfillmentSelector; // ║ The function selector that is used when calling back to the Client contract - uint16 gasForCallExactCheck; // ═════════════╝ Used during calling back to the client. Ensures we have at least enough gas to be able to revert if gasAmount > 63//64*gas available. - uint32[] maxCallbackGasLimits; // ═══════════╸ List of max callback gas limits used by flag with GAS_FLAG_INDEX + uint16 maxConsumersPerSubscription; // ═════════╗ Maximum number of consumers which can be added to a single subscription. This bound ensures we are able to loop over all subscription consumers as needed, without exceeding gas limits. Should a user require more consumers, they can use multiple subscriptions. + uint72 adminFee; // ║ Flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network + bytes4 handleOracleFulfillmentSelector; // ║ The function selector that is used when calling back to the Client contract + uint16 gasForCallExactCheck; // ════════════════╝ Used during calling back to the client. Ensures we have at least enough gas to be able to revert if gasAmount > 63//64*gas available. + uint32[] maxCallbackGasLimits; // ══════════════╸ List of max callback gas limits used by flag with GAS_FLAG_INDEX + uint16 subscriptionDepositMinimumRequests; //═══╗ Amount of requests that must be completed before the full subscription balance will be released when closing a subscription account. + uint72 subscriptionDepositJuels; // ════════════╝ Amount of subscription funds that are held as a deposit until Config.subscriptionDepositMinimumRequests are made using the subscription. } Config private s_config; @@ -180,6 +182,11 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, return s_config.maxConsumersPerSubscription; } + /// @dev Used within FunctionsSubscriptions.sol + function _getSubscriptionDepositDetails() internal view override returns (uint16, uint72) { + return (s_config.subscriptionDepositMinimumRequests, s_config.subscriptionDepositJuels); + } + // ================================================================ // | Requests | // ================================================================ @@ -227,6 +234,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, Subscription memory subscription = getSubscription(subscriptionId); Consumer memory consumer = getConsumer(msg.sender, subscriptionId); + uint72 adminFee = s_config.adminFee; // Forward request to DON FunctionsResponse.Commitment memory commitment = coordinator.startRequest( @@ -237,7 +245,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, dataVersion: dataVersion, flags: getFlags(subscriptionId), callbackGasLimit: callbackGasLimit, - adminFee: s_config.adminFee, + adminFee: adminFee, initiatedRequests: consumer.initiatedRequests, completedRequests: consumer.completedRequests, availableBalance: subscription.balance - subscription.blockedBalance, @@ -254,7 +262,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, s_requestCommitments[commitment.requestId] = keccak256( abi.encode( FunctionsResponse.Commitment({ - adminFee: s_config.adminFee, + adminFee: adminFee, coordinator: address(coordinator), client: msg.sender, subscriptionId: subscriptionId, @@ -306,23 +314,27 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, revert OnlyCallableFromCoordinator(); } - if (s_requestCommitments[commitment.requestId] == bytes32(0)) { - resultCode = FunctionsResponse.FulfillResult.INVALID_REQUEST_ID; - emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); - return (resultCode, 0); - } + { + bytes32 commitmentHash = s_requestCommitments[commitment.requestId]; - if (keccak256(abi.encode(commitment)) != s_requestCommitments[commitment.requestId]) { - resultCode = FunctionsResponse.FulfillResult.INVALID_COMMITMENT; - emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); - return (resultCode, 0); - } + if (commitmentHash == bytes32(0)) { + resultCode = FunctionsResponse.FulfillResult.INVALID_REQUEST_ID; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); + } - // Check that the transmitter has supplied enough gas for the callback to succeed - if (gasleft() < commitment.callbackGasLimit + commitment.gasOverheadAfterCallback) { - resultCode = FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED; - emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); - return (resultCode, 0); + if (keccak256(abi.encode(commitment)) != commitmentHash) { + resultCode = FunctionsResponse.FulfillResult.INVALID_COMMITMENT; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); + } + + // Check that the transmitter has supplied enough gas for the callback to succeed + if (gasleft() < commitment.callbackGasLimit + commitment.gasOverheadAfterCallback) { + resultCode = FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); + } } { @@ -512,18 +524,15 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, ) { revert InvalidProposal(); } - } - s_proposedContractSet = ContractProposalSet({ids: proposedContractSetIds, to: proposedContractSetAddresses}); - - // NOTE: iterations of this loop will not exceed MAX_PROPOSAL_SET_LENGTH - for (uint256 i = 0; i < proposedContractSetIds.length; ++i) { emit ContractProposed({ - proposedContractSetId: proposedContractSetIds[i], - proposedContractSetFromAddress: s_route[proposedContractSetIds[i]], - proposedContractSetToAddress: proposedContractSetAddresses[i] + proposedContractSetId: id, + proposedContractSetFromAddress: s_route[id], + proposedContractSetToAddress: proposedContract }); } + + s_proposedContractSet = ContractProposalSet({ids: proposedContractSetIds, to: proposedContractSetAddresses}); } // @inheritdoc IRouterBase diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol index dbcf97081bb..cab8e2b0803 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol @@ -24,7 +24,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // | Balance state | // ================================================================ // link token address - address internal immutable i_linkToken; + IERC20 internal immutable i_linkToken; // s_totalLinkBalance tracks the total LINK sent to/from // this contract through onTokenTransfer, cancelSubscription and oracleWithdraw. @@ -42,7 +42,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // loop through all the current subscriptions via .getSubscription(). uint64 private s_currentSubscriptionId; - mapping(uint64 subscriptionId => IFunctionsSubscriptions.Subscription) private s_subscriptions; + mapping(uint64 subscriptionId => Subscription) private s_subscriptions; // Maintains the list of keys in s_consumers. // We do this for 2 reasons: @@ -50,7 +50,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // 2. To be able to return the list of all consumers in getSubscription. // Note that we need the s_consumers map to be able to directly check if a // consumer is valid without reading all the consumers from storage. - mapping(address consumer => mapping(uint64 subscriptionId => IFunctionsSubscriptions.Consumer)) private s_consumers; + mapping(address consumer => mapping(uint64 subscriptionId => Consumer)) private s_consumers; event SubscriptionCreated(uint64 indexed subscriptionId, address owner); event SubscriptionFunded(uint64 indexed subscriptionId, uint256 oldBalance, uint256 newBalance); @@ -70,7 +70,6 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece error MustBeSubscriptionOwner(); error TimeoutNotExceeded(); error MustBeProposedOwner(address proposedOwner); - error TotalBalanceInvariantViolated(uint256 totalBalance, uint256 deductionAttempt); // Should never happen event FundsRecovered(address to, uint256 amount); // ================================================================ @@ -90,7 +89,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // | Initialization | // ================================================================ constructor(address link) { - i_linkToken = link; + i_linkToken = IERC20(link); } // ================================================================ @@ -121,16 +120,17 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece uint96 callbackGasCostJuels = juelsPerGas * gasUsed; uint96 totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels; - // Charge the subscription - if (s_subscriptions[subscriptionId].balance < totalCostJuels) { + if ( + s_subscriptions[subscriptionId].balance < totalCostJuels || + s_subscriptions[subscriptionId].blockedBalance < estimatedTotalCostJuels + ) { revert InsufficientBalance(s_subscriptions[subscriptionId].balance); } + + // Charge the subscription s_subscriptions[subscriptionId].balance -= totalCostJuels; // Unblock earmarked funds - if (s_subscriptions[subscriptionId].blockedBalance < estimatedTotalCostJuels) { - revert InsufficientBalance(s_subscriptions[subscriptionId].balance); - } s_subscriptions[subscriptionId].blockedBalance -= estimatedTotalCostJuels; // Pay the DON's fees and gas reimbursement @@ -153,17 +153,17 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece function ownerCancelSubscription(uint64 subscriptionId) external override { _onlyRouterOwner(); _isExistingSubscription(subscriptionId); - _cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner); + _cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner, false); } // @inheritdoc IFunctionsSubscriptions function recoverFunds(address to) external override { _onlyRouterOwner(); - uint256 externalBalance = IERC20(i_linkToken).balanceOf(address(this)); + uint256 externalBalance = i_linkToken.balanceOf(address(this)); uint256 internalBalance = uint256(s_totalLinkBalance); if (internalBalance < externalBalance) { uint256 amount = externalBalance - internalBalance; - IERC20(i_linkToken).safeTransfer(to, amount); + i_linkToken.safeTransfer(to, amount); emit FundsRecovered(to, amount); } // If the balances are equal, nothing to be done. @@ -184,12 +184,9 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece if (currentBalance < amount) { revert InsufficientBalance(currentBalance); } - if (s_totalLinkBalance < amount) { - revert TotalBalanceInvariantViolated(s_totalLinkBalance, amount); - } s_withdrawableTokens[msg.sender] -= amount; s_totalLinkBalance -= amount; - IERC20(i_linkToken).safeTransfer(recipient, amount); + i_linkToken.safeTransfer(recipient, amount); } // @notice Owner withdraw LINK earned through admin fees @@ -205,13 +202,10 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece if (currentBalance < amount) { revert InsufficientBalance(currentBalance); } - if (s_totalLinkBalance < amount) { - revert TotalBalanceInvariantViolated(s_totalLinkBalance, amount); - } s_withdrawableTokens[address(this)] -= amount; s_totalLinkBalance -= amount; - IERC20(i_linkToken).safeTransfer(recipient, amount); + i_linkToken.safeTransfer(recipient, amount); } // ================================================================ @@ -264,6 +258,27 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece return s_subscriptions[subscriptionId]; } + /// @inheritdoc IFunctionsSubscriptions + function getSubscriptionsInRange( + uint64 subscriptionIdStart, + uint64 subscriptionIdEnd + ) external view override returns (Subscription[] memory subscriptions) { + if ( + subscriptionIdStart > subscriptionIdEnd || + subscriptionIdEnd > s_currentSubscriptionId || + s_currentSubscriptionId == 0 + ) { + revert InvalidCalldata(); + } + + subscriptions = new Subscription[]((subscriptionIdEnd - subscriptionIdStart) + 1); + for (uint256 i = 0; i <= subscriptionIdEnd - subscriptionIdStart; ++i) { + subscriptions[i] = s_subscriptions[uint64(subscriptionIdStart + i)]; + } + + return subscriptions; + } + // @inheritdoc IFunctionsSubscriptions function getConsumer(address client, uint64 subscriptionId) public view override returns (Consumer memory) { return s_consumers[client][subscriptionId]; @@ -363,9 +378,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece _onlySenderThatAcceptedToS(); Consumer memory consumerData = s_consumers[consumer][subscriptionId]; - if (!consumerData.allowed) { - revert InvalidConsumer(); - } + _isAllowedConsumer(consumer, subscriptionId); if (consumerData.initiatedRequests != consumerData.completedRequests) { revert CannotRemoveWithPendingRequests(); } @@ -410,33 +423,52 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece emit SubscriptionConsumerAdded(subscriptionId, consumer); } - // @inheritdoc IFunctionsSubscriptions - function cancelSubscription(uint64 subscriptionId, address to) external override { - _whenNotPaused(); - _onlySubscriptionOwner(subscriptionId); - _onlySenderThatAcceptedToS(); + /// @dev Overriden in FunctionsRouter.sol + function _getSubscriptionDepositDetails() internal virtual returns (uint16, uint72); - if (pendingRequestExists(subscriptionId)) { - revert CannotRemoveWithPendingRequests(); - } - - _cancelSubscriptionHelper(subscriptionId, to); - } - - function _cancelSubscriptionHelper(uint64 subscriptionId, address to) private { + function _cancelSubscriptionHelper(uint64 subscriptionId, address toAddress, bool checkDepositRefundability) private { Subscription memory subscription = s_subscriptions[subscriptionId]; uint96 balance = subscription.balance; + uint64 completedRequests = 0; + // NOTE: loop iterations are bounded by config.maxConsumers // If no consumers, does nothing. for (uint256 i = 0; i < subscription.consumers.length; ++i) { - delete s_consumers[subscription.consumers[i]][subscriptionId]; + address consumer = subscription.consumers[i]; + completedRequests += s_consumers[consumer][subscriptionId].completedRequests; + delete s_consumers[consumer][subscriptionId]; } delete s_subscriptions[subscriptionId]; - s_totalLinkBalance -= balance; - IERC20(i_linkToken).safeTransfer(to, uint256(balance)); + (uint16 subscriptionDepositMinimumRequests, uint72 subscriptionDepositJuels) = _getSubscriptionDepositDetails(); + + // If subscription has not made enough requests, deposit will be forfeited + if (checkDepositRefundability && completedRequests < subscriptionDepositMinimumRequests) { + uint96 deposit = subscriptionDepositJuels > balance ? balance : subscriptionDepositJuels; + if (deposit > 0) { + s_withdrawableTokens[address(this)] += deposit; + balance -= deposit; + } + } + + if (balance > 0) { + s_totalLinkBalance -= balance; + i_linkToken.safeTransfer(toAddress, uint256(balance)); + } + emit SubscriptionCanceled(subscriptionId, toAddress, balance); + } + + /// @inheritdoc IFunctionsSubscriptions + function cancelSubscription(uint64 subscriptionId, address to) external override { + _whenNotPaused(); + _onlySubscriptionOwner(subscriptionId); + _onlySenderThatAcceptedToS(); + + if (pendingRequestExists(subscriptionId)) { + revert CannotRemoveWithPendingRequests(); + } - emit SubscriptionCanceled(subscriptionId, to, balance); + _cancelSubscriptionHelper(subscriptionId, to, true); } // @inheritdoc IFunctionsSubscriptions diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol index 44f4c62da81..c9730da899b 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol @@ -31,7 +31,7 @@ interface IFunctionsBilling { // @notice Remove a request commitment that the Router has determined to be stale // @param requestId - The request ID to remove - function deleteCommitment(bytes32 requestId) external returns (bool); + function deleteCommitment(bytes32 requestId) external; // @notice Oracle withdraw LINK earned through fulfilling requests // @notice If amount is 0 the full balance will be withdrawn diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol index 4072307edb8..dacd0f13e62 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol @@ -25,6 +25,15 @@ interface IFunctionsSubscriptions { // @return subscription - see IFunctionsSubscriptions.Subscription for more information on the structure function getSubscription(uint64 subscriptionId) external view returns (Subscription memory); + /// @notice Retrieve details about multiple subscriptions using an inclusive range + /// @param subscriptionIdStart - the ID of the subscription to start the range at + /// @param subscriptionIdEnd - the ID of the subscription to end the range at + /// @return subscriptions - see IFunctionsSubscriptions.Subscription for more information on the structure + function getSubscriptionsInRange( + uint64 subscriptionIdStart, + uint64 subscriptionIdEnd + ) external view returns (Subscription[] memory); + // @notice Get details about a consumer of a subscription. // @param client - the consumer contract address // @param subscriptionId - the ID of the subscription diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol index 9b9637e2711..4d6e5a1fe0e 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol @@ -13,7 +13,6 @@ import {FunctionsClientTestHelper} from "./testhelpers/FunctionsClientTestHelper import {FunctionsRouterSetup, FunctionsRoutesSetup, FunctionsSubscriptionSetup, FunctionsClientRequestSetup} from "./Setup.t.sol"; import "forge-std/Vm.sol"; -import "forge-std/console.sol"; // ================================================================ // | Functions Router | @@ -42,6 +41,8 @@ contract FunctionsRouter_GetConfig is FunctionsRouterSetup { assertEq(config.maxCallbackGasLimits[1], getRouterConfig().maxCallbackGasLimits[1]); assertEq(config.maxCallbackGasLimits[2], getRouterConfig().maxCallbackGasLimits[2]); assertEq(config.gasForCallExactCheck, getRouterConfig().gasForCallExactCheck); + assertEq(config.subscriptionDepositMinimumRequests, getRouterConfig().subscriptionDepositMinimumRequests); + assertEq(config.subscriptionDepositJuels, getRouterConfig().subscriptionDepositJuels); } } @@ -63,7 +64,9 @@ contract FunctionsRouter_UpdateConfig is FunctionsRouterSetup { adminFee: s_adminFee, handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector, maxCallbackGasLimits: maxCallbackGasLimits, - gasForCallExactCheck: 5000 + gasForCallExactCheck: 5000, + subscriptionDepositMinimumRequests: 10, + subscriptionDepositJuels: 5 * 1e18 }); } diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol index 4f6cb600d2b..928ede95bf2 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol @@ -6,8 +6,12 @@ import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol"; import {FunctionsResponse} from "../../dev/1_0_0/libraries/FunctionsResponse.sol"; +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; + import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfServiceSetup, FunctionsClientSetup, FunctionsSubscriptionSetup, FunctionsClientRequestSetup, FunctionsFulfillmentSetup} from "./Setup.t.sol"; +import "forge-std/Vm.sol"; + // ================================================================ // | Functions Subscriptions | // ================================================================ @@ -15,8 +19,8 @@ import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfServiceSetup, Functions contract FunctionsSubscriptions_Constructor_Helper is FunctionsSubscriptions { constructor(address link) FunctionsSubscriptions(link) {} - function getLinkToken() public view returns (address) { - return i_linkToken; + function getLinkToken() public view returns (IERC20) { + return IERC20(i_linkToken); } // overrides @@ -24,6 +28,10 @@ contract FunctionsSubscriptions_Constructor_Helper is FunctionsSubscriptions { return 0; } + function _getSubscriptionDepositDetails() internal pure override returns (uint16, uint72) { + return (0, 0); + } + function _onlySenderThatAcceptedToS() internal override {} function _onlyRouterOwner() internal override {} @@ -42,7 +50,7 @@ contract FunctionsSubscriptions_Constructor is BaseTest { } function test_Constructor_Success() public { - assertEq(s_linkToken, s_subscriptionsHelper.getLinkToken()); + assertEq(address(s_linkToken), address(s_subscriptionsHelper.getLinkToken())); } } @@ -93,6 +101,7 @@ contract FunctionsSubscriptions_OwnerCancelSubscription is FunctionsSubscription function test_OwnerCancelSubscription_SuccessDeletesSubscription() public { s_functionsRouter.ownerCancelSubscription(s_subscriptionId); + // Subscription should no longer exist vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); s_functionsRouter.getSubscription(s_subscriptionId); } @@ -349,6 +358,79 @@ contract FunctionsSubscriptions_GetSubscriptionCount is FunctionsSubscriptionSet } } +/// @notice #getSubscriptionsInRange +contract FunctionsSubscriptions_GetSubscriptionsInRange is FunctionsSubscriptionSetup { + function setUp() public virtual override { + FunctionsSubscriptionSetup.setUp(); + + // Create 2 more subscriptions + /* uint64 subscriptionId2 = */ s_functionsRouter.createSubscription(); + uint64 subscriptionId3 = s_functionsRouter.createSubscription(); + + // Give each one unique state + // #1 subscriptionId for requests, #2 empty, #3 proposedOwner of stranger + s_functionsRouter.proposeSubscriptionOwnerTransfer(subscriptionId3, STRANGER_ADDRESS); + } + + function test_GetSubscriptionsInRange_RevertIfStartIsAfterEnd() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); + + s_functionsRouter.getSubscriptionsInRange(1, 0); + } + + function test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint64 lastSubscriptionId = s_functionsRouter.getSubscriptionCount(); + vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); + s_functionsRouter.getSubscriptionsInRange(1, lastSubscriptionId + 1); + } + + function test_GetSubscriptionsInRange_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint64 lastSubscriptionId = s_functionsRouter.getSubscriptionCount(); + FunctionsSubscriptions.Subscription[] memory subscriptions = s_functionsRouter.getSubscriptionsInRange( + s_subscriptionId, + lastSubscriptionId + ); + + assertEq(subscriptions.length, 3); + + // Check subscription 1 + assertEq(subscriptions[0].balance, s_subscriptionInitialFunding); + assertEq(subscriptions[0].owner, OWNER_ADDRESS); + assertEq(subscriptions[0].blockedBalance, 0); + assertEq(subscriptions[0].proposedOwner, address(0)); + assertEq(subscriptions[0].consumers[0], address(s_functionsClient)); + assertEq(subscriptions[0].flags, bytes32(0)); + + // Check subscription 2 + assertEq(subscriptions[1].balance, 0); + assertEq(subscriptions[1].owner, OWNER_ADDRESS); + assertEq(subscriptions[1].blockedBalance, 0); + assertEq(subscriptions[1].proposedOwner, address(0)); + assertEq(subscriptions[1].consumers.length, 0); + assertEq(subscriptions[1].flags, bytes32(0)); + + // Check subscription 3 + assertEq(subscriptions[2].balance, 0); + assertEq(subscriptions[2].owner, OWNER_ADDRESS); + assertEq(subscriptions[2].blockedBalance, 0); + assertEq(subscriptions[2].proposedOwner, address(STRANGER_ADDRESS)); + assertEq(subscriptions[2].consumers.length, 0); + assertEq(subscriptions[2].flags, bytes32(0)); + } +} + /// @notice #getSubscription contract FunctionsSubscriptions_GetSubscription is FunctionsSubscriptionSetup { function test_GetSubscription_Success() public { @@ -899,22 +981,149 @@ contract FunctionsSubscriptions_CancelSubscription is FunctionsSubscriptionSetup event SubscriptionCanceled(uint64 indexed subscriptionId, address fundsRecipient, uint256 fundsAmount); - function test_CancelSubscription_Success() public { + function test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() public { + // No requests have been completed + assertEq(s_functionsRouter.getConsumer(address(s_functionsClient), s_subscriptionId).completedRequests, 0); + // Subscription balance is less than deposit amount + assertLe(s_functionsRouter.getSubscription(s_subscriptionId).balance, s_subscriptionDepositJuels); + uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + uint96 expectedRefund = 0; + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). bool checkTopic1 = false; bool checkTopic2 = false; bool checkTopic3 = false; bool checkData = true; vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); - emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, s_subscriptionInitialFunding); + emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, expectedRefund); s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); - assertEq(subscriptionOwnerBalanceBefore + s_subscriptionInitialFunding, subscriptionOwnerBalanceAfter); + assertEq(subscriptionOwnerBalanceBefore + expectedRefund, subscriptionOwnerBalanceAfter); + + // Subscription should no longer exist + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + s_functionsRouter.getSubscription(s_subscriptionId); + + // Router owner should have expectedDepositWithheld to withdraw + uint96 expectedDepositWithheld = s_subscriptionInitialFunding; + uint256 balanceBeforeWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS); + s_functionsRouter.ownerWithdraw(STRANGER_ADDRESS, 0); + uint256 balanceAfterWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS); + assertEq(balanceBeforeWithdraw + expectedDepositWithheld, balanceAfterWithdraw); + } + + function test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() public { + // No requests have been completed + assertEq(s_functionsRouter.getConsumer(address(s_functionsClient), s_subscriptionId).completedRequests, 0); + // Subscription balance is more than deposit amount, double fund the subscription + s_linkToken.transferAndCall(address(s_functionsRouter), s_subscriptionInitialFunding, abi.encode(s_subscriptionId)); + assertGe(s_functionsRouter.getSubscription(s_subscriptionId).balance, s_subscriptionDepositJuels); + + uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + + uint96 expectedRefund = (s_subscriptionInitialFunding * 2) - s_subscriptionDepositJuels; + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, expectedRefund); + + s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); + + uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); + assertEq(subscriptionOwnerBalanceBefore + expectedRefund, subscriptionOwnerBalanceAfter); + + // Subscription should no longer exist + vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); + s_functionsRouter.getSubscription(s_subscriptionId); + + // Router owner should have expectedDepositWithheld to withdraw + uint96 expectedDepositWithheld = s_subscriptionDepositJuels; + uint256 balanceBeforeWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS); + s_functionsRouter.ownerWithdraw(STRANGER_ADDRESS, 0); + uint256 balanceAfterWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS); + assertEq(balanceBeforeWithdraw + expectedDepositWithheld, balanceAfterWithdraw); + } + + function test_CancelSubscription_SuccessRecieveDeposit() public { + // Complete 1 request = subscriptionDepositMinimumRequests + vm.recordLogs(); + bytes32 requestId = s_functionsClient.sendRequest( + s_donId, + "return 'hello world';", + new bytes(0), + new string[](0), + new bytes[](0), + s_subscriptionId, + 5500 + ); + + // Get commitment data from OracleRequest event log + Vm.Log[] memory entries = vm.getRecordedLogs(); + (, , , , , , , FunctionsResponse.Commitment memory commitment) = abi.decode( + entries[0].data, + (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment) + ); + + // Send as transmitter 1 + vm.stopPrank(); + vm.startPrank(NOP_TRANSMITTER_ADDRESS_1); + + // Build report + bytes32[] memory requestIds = new bytes32[](1); + requestIds[0] = requestId; + bytes[] memory results = new bytes[](1); + results[0] = bytes("hello world!"); + bytes[] memory errors = new bytes[](1); + // No error + bytes[] memory onchainMetadata = new bytes[](1); + onchainMetadata[0] = abi.encode(commitment); + bytes[] memory offchainMetadata = new bytes[](1); + // No offchain metadata + bytes memory report = abi.encode(requestIds, results, errors, onchainMetadata, offchainMetadata); + + // Build signers + address[31] memory signers; + signers[0] = NOP_SIGNER_ADDRESS_1; + + // Send report + vm.recordLogs(); + s_functionsCoordinator.callReportWithSigners(report, signers); + + // Get actual cost from RequestProcessed event log + Vm.Log[] memory entries2 = vm.getRecordedLogs(); + (uint96 totalCostJuels, , , , , ) = abi.decode( + entries2[2].data, + (uint96, address, FunctionsResponse.FulfillResult, bytes, bytes, bytes) + ); + + // Return to sending as owner + vm.stopPrank(); + vm.startPrank(OWNER_ADDRESS); + + uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS); + + uint96 expectedRefund = s_subscriptionInitialFunding - totalCostJuels; + // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + bool checkTopic1 = false; + bool checkTopic2 = false; + bool checkTopic3 = false; + bool checkData = true; + vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); + emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, expectedRefund); + + s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS); + + uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS); + assertEq(subscriptionOwnerBalanceBefore + expectedRefund, subscriptionOwnerBalanceAfter); + // Subscription should no longer exist vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector); s_functionsRouter.getSubscription(s_subscriptionId); } diff --git a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol index e6e7df15f50..7a911c3bd60 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol @@ -24,6 +24,8 @@ contract FunctionsRouterSetup is BaseTest { uint72 internal s_adminFee = 100; uint72 internal s_donFee = 100; bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175; + uint16 s_subscriptionDepositMinimumRequests = 1; + uint72 s_subscriptionDepositJuels = 11 * 1e18; int256 internal LINK_ETH_RATE = 6000000000000000; @@ -55,7 +57,9 @@ contract FunctionsRouterSetup is BaseTest { adminFee: s_adminFee, handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector, maxCallbackGasLimits: maxCallbackGasLimits, - gasForCallExactCheck: 5000 + gasForCallExactCheck: 5000, + subscriptionDepositMinimumRequests: s_subscriptionDepositMinimumRequests, + subscriptionDepositJuels: s_subscriptionDepositJuels }); } diff --git a/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts b/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts index e2f0372be15..86cfb9dd5fc 100644 --- a/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts +++ b/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts @@ -370,6 +370,9 @@ describe('Functions Router - Subscriptions', () => { ).to.be.revertedWith(`MustBeSubscriptionOwner()`) }) it('can cancel', async function () { + const strangerBalanceBefore = await contracts.linkToken.balanceOf( + roles.strangerAddress, + ) await contracts.linkToken .connect(roles.subOwner) .transferAndCall( @@ -383,11 +386,13 @@ describe('Functions Router - Subscriptions', () => { .cancelSubscription(subId, roles.strangerAddress), ) .to.emit(contracts.router, 'SubscriptionCanceled') - .withArgs(subId, roles.strangerAddress, BigNumber.from('1000')) + .withArgs(subId, roles.strangerAddress, BigNumber.from('0')) const strangerBalance = await contracts.linkToken.balanceOf( roles.strangerAddress, ) - expect(strangerBalance.toString()).to.equal('1000000000000001000') + expect(strangerBalance.toString()).to.equal( + strangerBalanceBefore.toString(), + ) await expect( contracts.router.connect(roles.subOwner).getSubscription(subId), ).to.be.revertedWith('InvalidSubscription') @@ -493,7 +498,7 @@ describe('Functions Router - Subscriptions', () => { .connect(roles.subOwner) .cancelSubscription(subId, roles.strangerAddress) }, - BigNumber.from('-1000'), + BigNumber.from('0'), ], ] for (const [fn, expectedBalanceChange] of balanceChangingFns) { diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts index 1107858e6b8..0973a5cd845 100644 --- a/contracts/test/v0.8/functions/v1/utils.ts +++ b/contracts/test/v0.8/functions/v1/utils.ts @@ -77,6 +77,8 @@ export type FunctionsRouterConfig = { handleOracleFulfillmentSelector: string maxCallbackGasLimits: number[] gasForCallExactCheck: number + subscriptionDepositMinimumRequests: number + subscriptionDepositJuels: BigNumber } export const functionsRouterConfig: FunctionsRouterConfig = { maxConsumersPerSubscription: 100, @@ -84,6 +86,8 @@ export const functionsRouterConfig: FunctionsRouterConfig = { handleOracleFulfillmentSelector: '0x0ca76175', maxCallbackGasLimits: [300_000, 500_000, 1_000_000], gasForCallExactCheck: 5000, + subscriptionDepositMinimumRequests: 10, + subscriptionDepositJuels: BigNumber.from('1000000000000000000'), } export type CoordinatorConfig = { feedStalenessSeconds: number diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index fad5be26a06..94f1efd2d6a 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -70,8 +70,8 @@ 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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":[],\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"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\":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\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b506040516200513038038062005130833981016040819052620000349162000418565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b505050505050620005c6565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033b565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160e81b0261ffff60e81b196001600160481b03909216600160a01b02600160a01b600160e81b031963ffffffff948516600160801b0216600160801b600160e81b03199585166c010000000000000000000000000263ffffffff60601b19978616680100000000000000000297909716600160401b600160801b0319998616640100000000026001600160401b0319909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980546001600160e01b039092166001600160e01b0319909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a906200033090839062000536565b60405180910390a150565b6200034562000347565b565b6000546001600160a01b03163314620003455760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003bb57600080fd5b919050565b805163ffffffff81168114620003bb57600080fd5b80516001600160481b0381168114620003bb57600080fd5b805161ffff81168114620003bb57600080fd5b80516001600160e01b0381168114620003bb57600080fd5b60008060008385036101408112156200043057600080fd5b6200043b85620003a3565b935061010080601f19830112156200045257600080fd5b60405191508082016001600160401b03811183821017156200048457634e487b7160e01b600052604160045260246000fd5b6040526200049560208701620003c0565b8252620004a560408701620003c0565b6020830152620004b860608701620003c0565b6040830152620004cb60808701620003c0565b6060830152620004de60a08701620003c0565b6080830152620004f160c08701620003d5565b60a08301526200050460e08701620003ed565b60c08301526200051681870162000400565b60e08301525091506200052d6101208501620003a3565b90509250925092565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525060018060481b0360a08401511660a083015260c0830151620005a360c084018261ffff169052565b5060e0830151620005bf60e08401826001600160e01b03169052565b5092915050565b60805160a051614b1a62000616600039600081816105ce0152818161075c01528181610a2f01528181610cc501528181611038015281816118220152613271015260006112600152614b1a6000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806385b214cf116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610539578063e4ddcea61461054c578063f2fde38b1461056257600080fd5b8063c3f909d4146103c4578063d227d24514610501578063d328a91e1461053157600080fd5b8063a631571e116100bd578063a631571e14610371578063afcb95d714610391578063b1dc65a4146103b157600080fd5b806385b214cf146103135780638da5cb5b146103365780639314176d1461035e57600080fd5b806379ba509711610145578063814118341161011f578063814118341461028957806381f1b9381461029e57806381ff7048146102a657600080fd5b806379ba5097146102665780637d4807871461026e5780637f15e1661461027657600080fd5b80632a905ccc116101765780632a905ccc146101f957806359b5b7ac1461021b57806366316d8d1461025357600080fd5b8063083a546614610192578063181f5a77146101a7575b600080fd5b6101a56101a0366004613564565b610575565b005b6101e36040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f0919061360a565b60405180910390f35b6102016105ca565b60405168ffffffffffffffffff90911681526020016101f0565b61020161022936600461375a565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101a56102613660046137e9565b610660565b6101a5610819565b6101a561091b565b6101a5610284366004613564565b610b1b565b610291610b6b565b6040516101f09190613873565b6101e3610bda565b6102f060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f0565b610326610321366004613886565b610cab565b60405190151581526020016101f0565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6101a561036c36600461391c565b610d8b565b61038461037f3660046139e6565b610fc7565b6040516101f09190613b3b565b6040805160018152600060208201819052918101919091526060016101f0565b6101a56103bf366004613b8f565b611167565b6104f46040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915250604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08201527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e082015290565b6040516101f09190613c46565b61051461050f366004613d06565b61181e565b6040516bffffffffffffffffffffffff90911681526020016101f0565b6101e3611980565b6101a5610547366004613e1f565b6119d7565b610554612403565b6040519081526020016101f0565b6101a5610570366004613eec565b612628565b61057d61263c565b60008190036105b8576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105c5828483613fa2565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065b91906140c8565b905090565b6106686126bf565b806bffffffffffffffffffffffff166000036106a25750336000908152600a60205260409020546bffffffffffffffffffffffff166106fc565b336000908152600a60205260409020546bffffffffffffffffffffffff808316911610156106fc576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906107299084906bffffffffffffffffffffffff16614114565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061077e7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b1580156107fd57600080fd5b505af1158015610811573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461089f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61092361286a565b61092b6126bf565b6000610935610b6b565b905060005b8151811015610b17576000600a600084848151811061095b5761095b614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610b06576000600a60008585815181106109ba576109ba614139565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610a517f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610a7e57610a7e614139565b6020026020010151836040518363ffffffff1660e01b8152600401610ad392919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610aed57600080fd5b505af1158015610b01573d6000803e3d6000fd5b505050505b50610b1081614168565b905061093a565b5050565b610b2361263c565b6000819003610b5e576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105c5828483613fa2565b60606006805480602002602001604051908101604052809291908181526020018280548015610bd057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ba5575b5050505050905090565b6060600d8054610be990613f09565b9050600003610c24576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610c3190613f09565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5d90613f09565b8015610bd05780601f10610c7f57610100808354040283529160200191610bd0565b820191906000526020600020905b815481529060010190602001808311610c8d57509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d1c576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260076020526040902054610d3757506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610d7a9084815260200190565b60405180910390a15060015b919050565b610d9361286a565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167d010000000000000000000000000000000000000000000000000000000000027fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90921674010000000000000000000000000000000000000000027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff63ffffffff94851670010000000000000000000000000000000002167fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff9585166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9786166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a90610fbc908390613c46565b60405180910390a150565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461108f576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a061109b836141a0565b612872565b90506110b26060830160408401613eec565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261110060c0870160a0880161428d565b61111261016088016101408901613eec565b61111c88806142aa565b61112e6101208b016101008c0161430f565b60208b01356111446101008d0160e08e0161432a565b8b60405161115a99989796959493929190614347565b60405180910390a3919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925290831461124e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610896565b61125c8b8b8b8b8b8b612c73565b60007f0000000000000000000000000000000000000000000000000000000000000000156112b95760028260200151836040015161129a91906143ef565b6112a49190614437565b6112af9060016143ef565b60ff1690506112cf565b60208201516112c99060016143ef565b60ff1690505b888114611338576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610896565b8887146113a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610896565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113e4576113e4614459565b60028111156113f5576113f5614459565b905250905060028160200151600281111561141257611412614459565b14801561145957506006816000015160ff168154811061143457611434614139565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6114bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610896565b50505050506114cc6134fc565b6000808a8a6040516114df929190614488565b6040519081900381206114f6918e90602001614498565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b8981101561180057600060018489846020811061155f5761155f614139565b61156c91901a601b6143ef565b8e8e8681811061157e5761157e614139565b905060200201358d8d8781811061159757611597614139565b90506020020135604051600081526020016040526040516115d4949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156115f6573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561167657611676614459565b600281111561168757611687614459565b90525092506001836020015160028111156116a4576116a4614459565b1461170b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610896565b8251600090879060ff16601f811061172557611725614139565b602002015173ffffffffffffffffffffffffffffffffffffffff16146117a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610896565b8086846000015160ff16601f81106117c1576117c1614139565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526117ec6001866143ef565b945050806117f990614168565b9050611540565b505050611811833383858e8e612d2a565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b1580156118be57600080fd5b505afa1580156118d2573d6000803e3d6000fd5b5050505066038d7ea4c68000821115611917576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006119216105ca565b9050600061196487878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061022992505050565b905061197285858385612ef8565b925050505b95945050505050565b6060600c805461198f90613f09565b90506000036119ca576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610c3190613f09565b855185518560ff16601f831115611a4a576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610896565b80600003611ab4576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610896565b818314611b42576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610896565b611b4d8160036144ac565b8311611bb5576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610896565b611bbd61263c565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611c049088612fe2565b60055415611db957600554600090611c1e906001906144c3565b9050600060058281548110611c3557611c35614139565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611c6f57611c6f614139565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611cef57611cef6144d6565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611d5857611d586144d6565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611c04915050565b60005b8151518110156122205760006004600084600001518481518110611de257611de2614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611e2c57611e2c614459565b14611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610896565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611ec457611ec4614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115611f6557611f65614459565b021790555060009150611f759050565b6004600084602001518481518110611f8f57611f8f614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611fd957611fd9614459565b14612040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610896565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061207357612073614139565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561211457612114614459565b02179055505082518051600592508390811061213257612132614139565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106121ae576121ae614139565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061221881614168565b915050611dbc565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff43811682029290921780855592048116929182916014916122d891849174010000000000000000000000000000000000000000900416614505565b92506101000a81548163ffffffff021916908363ffffffff1602179055506123374630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151612ffb565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986123ee988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614522565b60405180910390a15050505050505050505050565b604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c01000000000000000000000000808304821660608501527001000000000000000000000000000000008304909116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a0808501919091527d01000000000000000000000000000000000000000000000000000000000090920461ffff1660c08401526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa15801561255d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258191906145d2565b50935050925050804261259491906144c3565b836020015163ffffffff161080156125b657506000836020015163ffffffff16115b156125e457505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b60008213612621576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610896565b5092915050565b61263061263c565b612639816130a6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146126bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610896565b565b600b546bffffffffffffffffffffffff166000036126d957565b60006126e3610b6b565b90508051600003612720576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b5460009161273f916bffffffffffffffffffffffff16614622565b905060005b825181101561280b5781600a600085848151811061276457612764614139565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166127cc919061464d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508061280490614168565b9050612744565b5081516128189082614672565b600b80546000906128389084906bffffffffffffffffffffffff16614114565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6126bd61263c565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260408051610100808201835260085463ffffffff80821684526401000000008204811660208501526801000000000000000082048116948401949094526c010000000000000000000000008104841660608401527001000000000000000000000000000000008104909316608083015274010000000000000000000000000000000000000000830468ffffffffffffffffff1660a08301527d01000000000000000000000000000000000000000000000000000000000090920461ffff90811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152928501519192911611156129f8576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff1690506000612a398560e001513a848860800151612ef8565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612a95576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b183087604001518860a001518960c001516001612ab691906146a2565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff1642612c0a91906146c3565b63ffffffff16815250945084604051602001612c269190613b3b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b6000612c808260206144ac565b612c8b8560206144ac565b612c97886101446146c3565b612ca191906146c3565b612cab91906146c3565b612cb69060006146c3565b9050368114612d21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610896565b50505050505050565b606080808080612d3c868801886147b1565b8451949950929750909550935091501580612d5957508351855114155b80612d6657508251855114155b80612d7357508151855114155b80612d8057508051855114155b15612db7576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612eea576000612e4f878381518110612dda57612dda614139565b6020026020010151878481518110612df457612df4614139565b6020026020010151878581518110612e0e57612e0e614139565b6020026020010151878681518110612e2857612e28614139565b6020026020010151878781518110612e4257612e42614139565b602002602001015161319b565b90506000816006811115612e6557612e65614459565b1480612e8257506001816006811115612e8057612e80614459565b145b15612ed957868281518110612e9957612e99614139565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612ee381614168565b9050612dba565b505050505050505050505050565b60085460009081908690612f309063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614505565b612f3a9190614505565b60085463ffffffff918216925060009161271091612f599116886144ac565b612f639190614883565b612f6d90876146c3565b90506000612f7a8261342b565b90506000612f96846bffffffffffffffffffffffff84166144ac565b90506000612fb268ffffffffffffffffff808916908a1661464d565b9050612fd4612fcf6bffffffffffffffffffffffff8316846146c3565b61345a565b9a9950505050505050505050565b6000612fec610b6b565b511115610b1757610b176126bf565b6000808a8a8a8a8a8a8a8a8a60405160200161301f99989796959493929190614897565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613125576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610896565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906131b2919061496d565b9050806040516020016131c59190613b3b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a8152600790935291205414613217576006915050611977565b600087815260076020526040902054613234576002915050611977565b600061323f3a61342b565b905060008261012001518361010001516132599190614a40565b61326a9064ffffffffff1683614672565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff16886132c9919061464d565b338b6040518763ffffffff1660e01b81526004016132ec96959493929190614a5e565b60408051808303816000875af115801561330a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332e9190614ada565b9092509050600082600681111561334757613347614459565b14806133645750600182600681111561336257613362614459565b145b1561341d5760008b815260076020526040812055613382818461464d565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff909216939092916133ee9185911661464d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b6000613454613438612403565b61344a84670de0b6b3a76400006144ac565b612fcf9190614883565b92915050565b60006bffffffffffffffffffffffff8211156134f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610896565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f84011261352d57600080fd5b50813567ffffffffffffffff81111561354557600080fd5b60208301915083602082850101111561355d57600080fd5b9250929050565b6000806020838503121561357757600080fd5b823567ffffffffffffffff81111561358e57600080fd5b61359a8582860161351b565b90969095509350505050565b6000815180845260005b818110156135cc576020818501810151868301820152016135b0565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061361d60208301846135a6565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff8111828210171561367757613677613624565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136c4576136c4613624565b604052919050565b600082601f8301126136dd57600080fd5b813567ffffffffffffffff8111156136f7576136f7613624565b61372860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161367d565b81815284602083860101111561373d57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561376c57600080fd5b813567ffffffffffffffff81111561378357600080fd5b61378f848285016136cc565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461263957600080fd5b8035610d8681613797565b6bffffffffffffffffffffffff8116811461263957600080fd5b8035610d86816137c4565b600080604083850312156137fc57600080fd5b823561380781613797565b91506020830135613817816137c4565b809150509250929050565b600081518084526020808501945080840160005b8381101561386857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613836565b509495945050505050565b60208152600061361d6020830184613822565b60006020828403121561389857600080fd5b5035919050565b63ffffffff8116811461263957600080fd5b8035610d868161389f565b68ffffffffffffffffff8116811461263957600080fd5b8035610d86816138bc565b803561ffff81168114610d8657600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114610d8657600080fd5b600061010080838503121561393057600080fd5b6040519081019067ffffffffffffffff8211818310171561395357613953613624565b81604052833591506139648261389f565b818152613973602085016138b1565b6020820152613984604085016138b1565b6040820152613995606085016138b1565b60608201526139a6608085016138b1565b60808201526139b760a085016138d3565b60a08201526139c860c085016138de565b60c08201526139d960e085016138f0565b60e0820152949350505050565b6000602082840312156139f857600080fd5b813567ffffffffffffffff811115613a0f57600080fd5b8201610160818503121561361d57600080fd5b805182526020810151613a4d602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613a6d60408401826bffffffffffffffffffffffff169052565b506060810151613a95606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613ab1608084018267ffffffffffffffff169052565b5060a0810151613ac960a084018263ffffffff169052565b5060c0810151613ae660c084018268ffffffffffffffffff169052565b5060e0810151613b0360e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b61016081016134548284613a22565b60008083601f840112613b5c57600080fd5b50813567ffffffffffffffff811115613b7457600080fd5b6020830191508360208260051b850101111561355d57600080fd5b60008060008060008060008060e0898b031215613bab57600080fd5b606089018a811115613bbc57600080fd5b8998503567ffffffffffffffff80821115613bd657600080fd5b613be28c838d0161351b565b909950975060808b0135915080821115613bfb57600080fd5b613c078c838d01613b4a565b909750955060a08b0135915080821115613c2057600080fd5b50613c2d8b828c01613b4a565b999c989b50969995989497949560c00135949350505050565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525068ffffffffffffffffff60a08401511660a083015260c0830151613cb560c084018261ffff169052565b5060e083015161262160e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b67ffffffffffffffff8116811461263957600080fd5b8035610d8681613ce5565b600080600080600060808688031215613d1e57600080fd5b8535613d2981613ce5565b9450602086013567ffffffffffffffff811115613d4557600080fd5b613d518882890161351b565b9095509350506040860135613d658161389f565b949793965091946060013592915050565b600067ffffffffffffffff821115613d9057613d90613624565b5060051b60200190565b600082601f830112613dab57600080fd5b81356020613dc0613dbb83613d76565b61367d565b82815260059290921b84018101918181019086841115613ddf57600080fd5b8286015b84811015613e03578035613df681613797565b8352918301918301613de3565b509695505050505050565b803560ff81168114610d8657600080fd5b60008060008060008060c08789031215613e3857600080fd5b863567ffffffffffffffff80821115613e5057600080fd5b613e5c8a838b01613d9a565b97506020890135915080821115613e7257600080fd5b613e7e8a838b01613d9a565b9650613e8c60408a01613e0e565b95506060890135915080821115613ea257600080fd5b613eae8a838b016136cc565b9450613ebc60808a01613cfb565b935060a0890135915080821115613ed257600080fd5b50613edf89828a016136cc565b9150509295509295509295565b600060208284031215613efe57600080fd5b813561361d81613797565b600181811c90821680613f1d57607f821691505b602082108103613f56577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105c557600081815260208120601f850160051c81016020861015613f835750805b601f850160051c820191505b8181101561081157828155600101613f8f565b67ffffffffffffffff831115613fba57613fba613624565b613fce83613fc88354613f09565b83613f5c565b6000601f8411600181146140205760008515613fea5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556140b6565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561406f578685013582556020948501946001909201910161404f565b50868210156140aa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8051610d86816138bc565b6000602082840312156140da57600080fd5b815161361d816138bc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff828116828216039080821115612621576126216140e5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614199576141996140e5565b5060010190565b600061016082360312156141b357600080fd5b6141bb613653565b823567ffffffffffffffff8111156141d257600080fd5b6141de368286016136cc565b825250602083013560208201526141f7604084016137b9565b6040820152614208606084016137de565b6060820152614219608084016138d3565b608082015261422a60a08401613cfb565b60a082015261423b60c08401613cfb565b60c082015261424c60e084016138b1565b60e082015261010061425f8185016138de565b90820152610120614271848201613cfb565b908201526101406142838482016137b9565b9082015292915050565b60006020828403121561429f57600080fd5b813561361d81613ce5565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142df57600080fd5b83018035915067ffffffffffffffff8211156142fa57600080fd5b60200191503681900382131561355d57600080fd5b60006020828403121561432157600080fd5b61361d826138de565b60006020828403121561433c57600080fd5b813561361d8161389f565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301019050612fd460e0830184613a22565b60ff8181168382160190811115613454576134546140e5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff83168061444a5761444a614408565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b8082028115828204841417613454576134546140e5565b81810381811115613454576134546140e5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff818116838216019080821115612621576126216140e5565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526145528184018a613822565b905082810360808401526145668189613822565b905060ff871660a084015282810360c084015261458381876135a6565b905067ffffffffffffffff851660e08401528281036101008401526145a881856135a6565b9c9b505050505050505050505050565b805169ffffffffffffffffffff81168114610d8657600080fd5b600080600080600060a086880312156145ea57600080fd5b6145f3866145b8565b9450602086015193506040860151925060608601519150614616608087016145b8565b90509295509295909350565b60006bffffffffffffffffffffffff8084168061464157614641614408565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115612621576126216140e5565b6bffffffffffffffffffffffff81811683821602808216919082811461469a5761469a6140e5565b505092915050565b67ffffffffffffffff818116838216019080821115612621576126216140e5565b80820180821115613454576134546140e5565b600082601f8301126146e757600080fd5b813560206146f7613dbb83613d76565b82815260059290921b8401810191818101908684111561471657600080fd5b8286015b84811015613e03578035835291830191830161471a565b600082601f83011261474257600080fd5b81356020614752613dbb83613d76565b82815260059290921b8401810191818101908684111561477157600080fd5b8286015b84811015613e0357803567ffffffffffffffff8111156147955760008081fd5b6147a38986838b01016136cc565b845250918301918301614775565b600080600080600060a086880312156147c957600080fd5b853567ffffffffffffffff808211156147e157600080fd5b6147ed89838a016146d6565b9650602088013591508082111561480357600080fd5b61480f89838a01614731565b9550604088013591508082111561482557600080fd5b61483189838a01614731565b9450606088013591508082111561484757600080fd5b61485389838a01614731565b9350608088013591508082111561486957600080fd5b5061487688828901614731565b9150509295509295909350565b60008261489257614892614408565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526148de8285018b613822565b915083820360808501526148f2828a613822565b915060ff881660a085015283820360c085015261490f82886135a6565b90861660e085015283810361010085015290506145a881856135a6565b8051610d8681613797565b8051610d86816137c4565b8051610d8681613ce5565b8051610d868161389f565b805164ffffffffff81168114610d8657600080fd5b6000610160828403121561498057600080fd5b614988613653565b825181526149986020840161492c565b60208201526149a960408401614937565b60408201526149ba6060840161492c565b60608201526149cb60808401614942565b60808201526149dc60a0840161494d565b60a08201526149ed60c084016140bd565b60c08201526149fe60e084016140bd565b60e0820152610100614a11818501614958565b90820152610120614a23848201614958565b90820152610140614a3584820161494d565b908201529392505050565b64ffffffffff818116838216019080821115612621576126216140e5565b6000610200808352614a728184018a6135a6565b90508281036020840152614a8681896135a6565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614acf905060a0830184613a22565b979650505050505050565b60008060408385031215614aed57600080fd5b825160078110614afc57600080fd5b6020840151909250613817816137c456fea164736f6c6343000813000a", + 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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":[],\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"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\":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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"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\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b50604051620050f4380380620050f4833981016040819052620000349162000418565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b505050505050620005c6565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033b565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160e81b0261ffff60e81b196001600160481b03909216600160a01b02600160a01b600160e81b031963ffffffff948516600160801b0216600160801b600160e81b03199585166c010000000000000000000000000263ffffffff60601b19978616680100000000000000000297909716600160401b600160801b0319998616640100000000026001600160401b0319909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980546001600160e01b039092166001600160e01b0319909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a906200033090839062000536565b60405180910390a150565b6200034562000347565b565b6000546001600160a01b03163314620003455760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003bb57600080fd5b919050565b805163ffffffff81168114620003bb57600080fd5b80516001600160481b0381168114620003bb57600080fd5b805161ffff81168114620003bb57600080fd5b80516001600160e01b0381168114620003bb57600080fd5b60008060008385036101408112156200043057600080fd5b6200043b85620003a3565b935061010080601f19830112156200045257600080fd5b60405191508082016001600160401b03811183821017156200048457634e487b7160e01b600052604160045260246000fd5b6040526200049560208701620003c0565b8252620004a560408701620003c0565b6020830152620004b860608701620003c0565b6040830152620004cb60808701620003c0565b6060830152620004de60a08701620003c0565b6080830152620004f160c08701620003d5565b60a08301526200050460e08701620003ed565b60c08301526200051681870162000400565b60e08301525091506200052d6101208501620003a3565b90509250925092565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525060018060481b0360a08401511660a083015260c0830151620005a360c084018261ffff169052565b5060e0830151620005bf60e08401826001600160e01b03169052565b5092915050565b60805160a051614ade62000616600039600081816105be0152818161074c01528181610a1f01528181610cb301528181610ffa015281816117e50152613235015260006112230152614ade6000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806385b214cf116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610529578063e4ddcea61461053c578063f2fde38b1461055257600080fd5b8063c3f909d4146103b4578063d227d245146104f1578063d328a91e1461052157600080fd5b8063a631571e116100bd578063a631571e14610361578063afcb95d714610381578063b1dc65a4146103a157600080fd5b806385b214cf146103135780638da5cb5b146103265780639314176d1461034e57600080fd5b806379ba509711610145578063814118341161011f578063814118341461028957806381f1b9381461029e57806381ff7048146102a657600080fd5b806379ba5097146102665780637d4807871461026e5780637f15e1661461027657600080fd5b80632a905ccc116101765780632a905ccc146101f957806359b5b7ac1461021b57806366316d8d1461025357600080fd5b8063083a546614610192578063181f5a77146101a7575b600080fd5b6101a56101a0366004613528565b610565565b005b6101e36040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f091906135ce565b60405180910390f35b6102016105ba565b60405168ffffffffffffffffff90911681526020016101f0565b61020161022936600461371e565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101a56102613660046137ad565b610650565b6101a5610809565b6101a561090b565b6101a5610284366004613528565b610b0b565b610291610b5b565b6040516101f09190613837565b6101e3610bca565b6102f060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f0565b6101a561032136600461384a565b610c9b565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6101a561035c3660046138e0565b610d58565b61037461036f3660046139aa565b610f89565b6040516101f09190613aff565b6040805160018152600060208201819052918101919091526060016101f0565b6101a56103af366004613b53565b61112a565b6104e46040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915250604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08201527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e082015290565b6040516101f09190613c0a565b6105046104ff366004613cca565b6117e1565b6040516bffffffffffffffffffffffff90911681526020016101f0565b6101e3611943565b6101a5610537366004613de3565b61199a565b6105446123c6565b6040519081526020016101f0565b6101a5610560366004613eb0565b6125eb565b61056d6125ff565b60008190036105a8576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105b5828483613f66565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064b919061408c565b905090565b610658612682565b806bffffffffffffffffffffffff166000036106925750336000908152600a60205260409020546bffffffffffffffffffffffff166106ec565b336000908152600a60205260409020546bffffffffffffffffffffffff808316911610156106ec576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906107199084906bffffffffffffffffffffffff166140d8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061076e7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b1580156107ed57600080fd5b505af1158015610801573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61091361282d565b61091b612682565b6000610925610b5b565b905060005b8151811015610b07576000600a600084848151811061094b5761094b6140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610af6576000600a60008585815181106109aa576109aa6140fd565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610a417f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610a6e57610a6e6140fd565b6020026020010151836040518363ffffffff1660e01b8152600401610ac392919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610add57600080fd5b505af1158015610af1573d6000803e3d6000fd5b505050505b50610b008161412c565b905061092a565b5050565b610b136125ff565b6000819003610b4e576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105b5828483613f66565b60606006805480602002602001604051908101604052809291908181526020018280548015610bc057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610b95575b5050505050905090565b6060600d8054610bd990613ecd565b9050600003610c14576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610c2190613ecd565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4d90613ecd565b8015610bc05780601f10610c6f57610100808354040283529160200191610bc0565b820191906000526020600020905b815481529060010190602001808311610c7d57509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d0a576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610d4d9083815260200190565b60405180910390a150565b610d6061282d565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167d010000000000000000000000000000000000000000000000000000000000027fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90921674010000000000000000000000000000000000000000027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff63ffffffff94851670010000000000000000000000000000000002167fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff9585166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9786166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a90610d4d908390613c0a565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611051576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61106261105d83614164565b612835565b90506110746060830160408401613eb0565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff326110c260c0870160a08801614251565b6110d461016088016101408901613eb0565b6110de888061426e565b6110f06101208b016101008c016142d3565b60208b01356111066101008d0160e08e016142ee565b8b60405161111c9998979695949392919061430b565b60405180910390a35b919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611211576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610886565b61121f8b8b8b8b8b8b612c36565b60007f00000000000000000000000000000000000000000000000000000000000000001561127c5760028260200151836040015161125d91906143b3565b61126791906143fb565b6112729060016143b3565b60ff169050611292565b602082015161128c9060016143b3565b60ff1690505b8881146112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610886565b888714611364576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610886565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113a7576113a761441d565b60028111156113b8576113b861441d565b90525090506002816020015160028111156113d5576113d561441d565b14801561141c57506006816000015160ff16815481106113f7576113f76140fd565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610886565b505050505061148f6134c0565b6000808a8a6040516114a292919061444c565b6040519081900381206114b9918e9060200161445c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117c3576000600184898460208110611522576115226140fd565b61152f91901a601b6143b3565b8e8e86818110611541576115416140fd565b905060200201358d8d8781811061155a5761155a6140fd565b9050602002013560405160008152602001604052604051611597949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156115b9573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156116395761163961441d565b600281111561164a5761164a61441d565b90525092506001836020015160028111156116675761166761441d565b146116ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610886565b8251600090879060ff16601f81106116e8576116e86140fd565b602002015173ffffffffffffffffffffffffffffffffffffffff161461176a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610886565b8086846000015160ff16601f8110611784576117846140fd565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526117af6001866143b3565b945050806117bc9061412c565b9050611503565b5050506117d4833383858e8e612ced565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b15801561188157600080fd5b505afa158015611895573d6000803e3d6000fd5b5050505066038d7ea4c680008211156118da576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006118e46105ba565b9050600061192787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061022992505050565b905061193585858385612ebb565b925050505b95945050505050565b6060600c805461195290613ecd565b905060000361198d576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610c2190613ecd565b855185518560ff16601f831115611a0d576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610886565b80600003611a77576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610886565b818314611b05576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610886565b611b10816003614470565b8311611b78576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610886565b611b806125ff565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611bc79088612fa5565b60055415611d7c57600554600090611be190600190614487565b9050600060058281548110611bf857611bf86140fd565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611c3257611c326140fd565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611cb257611cb261449a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611d1b57611d1b61449a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611bc7915050565b60005b8151518110156121e35760006004600084600001518481518110611da557611da56140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611def57611def61441d565b14611e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610886565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611e8757611e876140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115611f2857611f2861441d565b021790555060009150611f389050565b6004600084602001518481518110611f5257611f526140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611f9c57611f9c61441d565b14612003576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610886565b6040805180820190915260ff821681526020810160028152506004600084602001518481518110612036576120366140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156120d7576120d761441d565b0217905550508251805160059250839081106120f5576120f56140fd565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915582015180516006919083908110612171576121716140fd565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055806121db8161412c565b915050611d7f565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161229b918491740100000000000000000000000000000000000000009004166144c9565b92506101000a81548163ffffffff021916908363ffffffff1602179055506122fa4630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151612fbe565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986123b1988b9891977401000000000000000000000000000000000000000090920463ffffffff169690959194919391926144e6565b60405180910390a15050505050505050505050565b604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c01000000000000000000000000808304821660608501527001000000000000000000000000000000008304909116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a0808501919091527d01000000000000000000000000000000000000000000000000000000000090920461ffff1660c08401526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa158015612520573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125449190614596565b5093505092505080426125579190614487565b836020015163ffffffff1610801561257957506000836020015163ffffffff16115b156125a757505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b600082136125e4576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610886565b5092915050565b6125f36125ff565b6125fc81613069565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314612680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610886565b565b600b546bffffffffffffffffffffffff1660000361269c57565b60006126a6610b5b565b905080516000036126e3576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b54600091612702916bffffffffffffffffffffffff166145e6565b905060005b82518110156127ce5781600a6000858481518110612727576127276140fd565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff1661278f9190614611565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806127c79061412c565b9050612707565b5081516127db9082614636565b600b80546000906127fb9084906bffffffffffffffffffffffff166140d8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6126806125ff565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260408051610100808201835260085463ffffffff80821684526401000000008204811660208501526801000000000000000082048116948401949094526c010000000000000000000000008104841660608401527001000000000000000000000000000000008104909316608083015274010000000000000000000000000000000000000000830468ffffffffffffffffff1660a08301527d01000000000000000000000000000000000000000000000000000000000090920461ffff90811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152928501519192911611156129bb576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff16905060006129fc8560e001513a848860800151612ebb565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612a58576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612adb3087604001518860a001518960c001516001612a799190614666565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff1642612bcd9190614687565b63ffffffff16815250945084604051602001612be99190613aff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b6000612c43826020614470565b612c4e856020614470565b612c5a88610144614687565b612c649190614687565b612c6e9190614687565b612c79906000614687565b9050368114612ce4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610886565b50505050505050565b606080808080612cff86880188614775565b8451949950929750909550935091501580612d1c57508351855114155b80612d2957508251855114155b80612d3657508151855114155b80612d4357508051855114155b15612d7a576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612ead576000612e12878381518110612d9d57612d9d6140fd565b6020026020010151878481518110612db757612db76140fd565b6020026020010151878581518110612dd157612dd16140fd565b6020026020010151878681518110612deb57612deb6140fd565b6020026020010151878781518110612e0557612e056140fd565b602002602001015161315e565b90506000816006811115612e2857612e2861441d565b1480612e4557506001816006811115612e4357612e4361441d565b145b15612e9c57868281518110612e5c57612e5c6140fd565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612ea68161412c565b9050612d7d565b505050505050505050505050565b60085460009081908690612ef39063ffffffff6c010000000000000000000000008204811691680100000000000000009004166144c9565b612efd91906144c9565b60085463ffffffff918216925060009161271091612f1c911688614470565b612f269190614847565b612f309087614687565b90506000612f3d826133ef565b90506000612f59846bffffffffffffffffffffffff8416614470565b90506000612f7568ffffffffffffffffff808916908a16614611565b9050612f97612f926bffffffffffffffffffffffff831684614687565b61341e565b9a9950505050505050505050565b6000612faf610b5b565b511115610b0757610b07612682565b6000808a8a8a8a8a8a8a8a8a604051602001612fe29998979695949392919061485b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036130e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610886565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906131759190614931565b60008881526007602052604090205490915061319557600291505061193a565b806040516020016131a69190613aff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a81526007909352912054146131f857600691505061193a565b60006132033a6133ef565b9050600082610120015183610100015161321d9190614a04565b61322e9064ffffffffff1683614636565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff168861328d9190614611565b338b6040518763ffffffff1660e01b81526004016132b096959493929190614a22565b60408051808303816000875af11580156132ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f29190614a9e565b9092509050600082600681111561330b5761330b61441d565b1480613328575060018260068111156133265761332661441d565b145b156133e15760008b8152600760205260408120556133468184614611565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff909216939092916133b291859116614611565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b60006134186133fc6123c6565b61340e84670de0b6b3a7640000614470565b612f929190614847565b92915050565b60006bffffffffffffffffffffffff8211156134bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610886565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f8401126134f157600080fd5b50813567ffffffffffffffff81111561350957600080fd5b60208301915083602082850101111561352157600080fd5b9250929050565b6000806020838503121561353b57600080fd5b823567ffffffffffffffff81111561355257600080fd5b61355e858286016134df565b90969095509350505050565b6000815180845260005b8181101561359057602081850181015186830182015201613574565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006135e1602083018461356a565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff8111828210171561363b5761363b6135e8565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613688576136886135e8565b604052919050565b600082601f8301126136a157600080fd5b813567ffffffffffffffff8111156136bb576136bb6135e8565b6136ec60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613641565b81815284602083860101111561370157600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561373057600080fd5b813567ffffffffffffffff81111561374757600080fd5b61375384828501613690565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff811681146125fc57600080fd5b80356111258161375b565b6bffffffffffffffffffffffff811681146125fc57600080fd5b803561112581613788565b600080604083850312156137c057600080fd5b82356137cb8161375b565b915060208301356137db81613788565b809150509250929050565b600081518084526020808501945080840160005b8381101561382c57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016137fa565b509495945050505050565b6020815260006135e160208301846137e6565b60006020828403121561385c57600080fd5b5035919050565b63ffffffff811681146125fc57600080fd5b803561112581613863565b68ffffffffffffffffff811681146125fc57600080fd5b803561112581613880565b803561ffff8116811461112557600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461112557600080fd5b60006101008083850312156138f457600080fd5b6040519081019067ffffffffffffffff82118183101715613917576139176135e8565b816040528335915061392882613863565b81815261393760208501613875565b602082015261394860408501613875565b604082015261395960608501613875565b606082015261396a60808501613875565b608082015261397b60a08501613897565b60a082015261398c60c085016138a2565b60c082015261399d60e085016138b4565b60e0820152949350505050565b6000602082840312156139bc57600080fd5b813567ffffffffffffffff8111156139d357600080fd5b820161016081850312156135e157600080fd5b805182526020810151613a11602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613a3160408401826bffffffffffffffffffffffff169052565b506060810151613a59606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613a75608084018267ffffffffffffffff169052565b5060a0810151613a8d60a084018263ffffffff169052565b5060c0810151613aaa60c084018268ffffffffffffffffff169052565b5060e0810151613ac760e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161341882846139e6565b60008083601f840112613b2057600080fd5b50813567ffffffffffffffff811115613b3857600080fd5b6020830191508360208260051b850101111561352157600080fd5b60008060008060008060008060e0898b031215613b6f57600080fd5b606089018a811115613b8057600080fd5b8998503567ffffffffffffffff80821115613b9a57600080fd5b613ba68c838d016134df565b909950975060808b0135915080821115613bbf57600080fd5b613bcb8c838d01613b0e565b909750955060a08b0135915080821115613be457600080fd5b50613bf18b828c01613b0e565b999c989b50969995989497949560c00135949350505050565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525068ffffffffffffffffff60a08401511660a083015260c0830151613c7960c084018261ffff169052565b5060e08301516125e460e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b67ffffffffffffffff811681146125fc57600080fd5b803561112581613ca9565b600080600080600060808688031215613ce257600080fd5b8535613ced81613ca9565b9450602086013567ffffffffffffffff811115613d0957600080fd5b613d15888289016134df565b9095509350506040860135613d2981613863565b949793965091946060013592915050565b600067ffffffffffffffff821115613d5457613d546135e8565b5060051b60200190565b600082601f830112613d6f57600080fd5b81356020613d84613d7f83613d3a565b613641565b82815260059290921b84018101918181019086841115613da357600080fd5b8286015b84811015613dc7578035613dba8161375b565b8352918301918301613da7565b509695505050505050565b803560ff8116811461112557600080fd5b60008060008060008060c08789031215613dfc57600080fd5b863567ffffffffffffffff80821115613e1457600080fd5b613e208a838b01613d5e565b97506020890135915080821115613e3657600080fd5b613e428a838b01613d5e565b9650613e5060408a01613dd2565b95506060890135915080821115613e6657600080fd5b613e728a838b01613690565b9450613e8060808a01613cbf565b935060a0890135915080821115613e9657600080fd5b50613ea389828a01613690565b9150509295509295509295565b600060208284031215613ec257600080fd5b81356135e18161375b565b600181811c90821680613ee157607f821691505b602082108103613f1a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105b557600081815260208120601f850160051c81016020861015613f475750805b601f850160051c820191505b8181101561080157828155600101613f53565b67ffffffffffffffff831115613f7e57613f7e6135e8565b613f9283613f8c8354613ecd565b83613f20565b6000601f841160018114613fe45760008515613fae5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561407a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140335786850135825560209485019460019092019101614013565b508682101561406e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b805161112581613880565b60006020828403121561409e57600080fd5b81516135e181613880565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8281168282160390808211156125e4576125e46140a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361415d5761415d6140a9565b5060010190565b6000610160823603121561417757600080fd5b61417f613617565b823567ffffffffffffffff81111561419657600080fd5b6141a236828601613690565b825250602083013560208201526141bb6040840161377d565b60408201526141cc606084016137a2565b60608201526141dd60808401613897565b60808201526141ee60a08401613cbf565b60a08201526141ff60c08401613cbf565b60c082015261421060e08401613875565b60e08201526101006142238185016138a2565b90820152610120614235848201613cbf565b9082015261014061424784820161377d565b9082015292915050565b60006020828403121561426357600080fd5b81356135e181613ca9565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142a357600080fd5b83018035915067ffffffffffffffff8211156142be57600080fd5b60200191503681900382131561352157600080fd5b6000602082840312156142e557600080fd5b6135e1826138a2565b60006020828403121561430057600080fd5b81356135e181613863565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301019050612f9760e08301846139e6565b60ff8181168382160190811115613418576134186140a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff83168061440e5761440e6143cc565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b8082028115828204841417613418576134186140a9565b81810381811115613418576134186140a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff8181168382160190808211156125e4576125e46140a9565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526145168184018a6137e6565b9050828103608084015261452a81896137e6565b905060ff871660a084015282810360c0840152614547818761356a565b905067ffffffffffffffff851660e084015282810361010084015261456c818561356a565b9c9b505050505050505050505050565b805169ffffffffffffffffffff8116811461112557600080fd5b600080600080600060a086880312156145ae57600080fd5b6145b78661457c565b94506020860151935060408601519250606086015191506145da6080870161457c565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614605576146056143cc565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156125e4576125e46140a9565b6bffffffffffffffffffffffff81811683821602808216919082811461465e5761465e6140a9565b505092915050565b67ffffffffffffffff8181168382160190808211156125e4576125e46140a9565b80820180821115613418576134186140a9565b600082601f8301126146ab57600080fd5b813560206146bb613d7f83613d3a565b82815260059290921b840181019181810190868411156146da57600080fd5b8286015b84811015613dc757803583529183019183016146de565b600082601f83011261470657600080fd5b81356020614716613d7f83613d3a565b82815260059290921b8401810191818101908684111561473557600080fd5b8286015b84811015613dc757803567ffffffffffffffff8111156147595760008081fd5b6147678986838b0101613690565b845250918301918301614739565b600080600080600060a0868803121561478d57600080fd5b853567ffffffffffffffff808211156147a557600080fd5b6147b189838a0161469a565b965060208801359150808211156147c757600080fd5b6147d389838a016146f5565b955060408801359150808211156147e957600080fd5b6147f589838a016146f5565b9450606088013591508082111561480b57600080fd5b61481789838a016146f5565b9350608088013591508082111561482d57600080fd5b5061483a888289016146f5565b9150509295509295909350565b600082614856576148566143cc565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526148a28285018b6137e6565b915083820360808501526148b6828a6137e6565b915060ff881660a085015283820360c08501526148d3828861356a565b90861660e0850152838103610100850152905061456c818561356a565b80516111258161375b565b805161112581613788565b805161112581613ca9565b805161112581613863565b805164ffffffffff8116811461112557600080fd5b6000610160828403121561494457600080fd5b61494c613617565b8251815261495c602084016148f0565b602082015261496d604084016148fb565b604082015261497e606084016148f0565b606082015261498f60808401614906565b60808201526149a060a08401614911565b60a08201526149b160c08401614081565b60c08201526149c260e08401614081565b60e08201526101006149d581850161491c565b908201526101206149e784820161491c565b908201526101406149f9848201614911565b908201529392505050565b64ffffffffff8181168382160190808211156125e4576125e46140a9565b6000610200808352614a368184018a61356a565b90508281036020840152614a4a818961356a565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614a93905060a08301846139e6565b979650505050505050565b60008060408385031215614ab157600080fd5b825160078110614ac057600080fd5b60208401519092506137db8161378856fea164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI diff --git a/core/gethwrappers/functions/generated/functions_router/functions_router.go b/core/gethwrappers/functions/generated/functions_router/functions_router.go index c035e320157..2c482048c49 100644 --- a/core/gethwrappers/functions/generated/functions_router/functions_router.go +++ b/core/gethwrappers/functions/generated/functions_router/functions_router.go @@ -45,11 +45,13 @@ type FunctionsResponseCommitment struct { } type FunctionsRouterConfig struct { - MaxConsumersPerSubscription uint16 - AdminFee *big.Int - HandleOracleFulfillmentSelector [4]byte - GasForCallExactCheck uint16 - MaxCallbackGasLimits []uint32 + MaxConsumersPerSubscription uint16 + AdminFee *big.Int + HandleOracleFulfillmentSelector [4]byte + GasForCallExactCheck uint16 + MaxCallbackGasLimits []uint32 + SubscriptionDepositMinimumRequests uint16 + SubscriptionDepositJuels *big.Int } type IFunctionsSubscriptionsConsumer struct { @@ -68,8 +70,8 @@ type IFunctionsSubscriptionsSubscription struct { } var FunctionsRouterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateRequestId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deductionAttempt\",\"type\":\"uint256\"}],\"name\":\"TotalBalanceInvariantViolated\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"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\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"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\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620062d1380380620062d18339810160408190526200003491620004df565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200067b565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b462000287565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b92910190620002ea565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516200027c9190620005dd565b60405180910390a150565b60065461010090046001600160a01b03163314620002e85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b828054828255906000526020600020906007016008900481019282156200038e5791602002820160005b838211156200035a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000314565b80156200038c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200035a565b505b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715620003f257620003f2620003b7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004235762000423620003b7565b604052919050565b805161ffff811681146200043e57600080fd5b919050565b600082601f8301126200045557600080fd5b815160206001600160401b03821115620004735762000473620003b7565b8160051b62000484828201620003f8565b92835284810182019282810190878511156200049f57600080fd5b83870192505b84831015620004d457825163ffffffff81168114620004c45760008081fd5b82529183019190830190620004a5565b979650505050505050565b60008060408385031215620004f357600080fd5b82516001600160a01b03811681146200050b57600080fd5b60208401519092506001600160401b03808211156200052957600080fd5b9084019060a082870312156200053e57600080fd5b62000548620003cd565b62000553836200042b565b815260208301516001600160481b03811681146200057057600080fd5b602082015260408301516001600160e01b0319811681146200059157600080fd5b6040820152620005a4606084016200042b565b6060820152608083015182811115620005bc57600080fd5b620005ca8882860162000443565b6080830152508093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160a080840152805160c0840181905260009291820190839060e08601905b808310156200067057835163ffffffff16825292840192600192909201919084019062000648565b509695505050505050565b608051615c1e620006b3600039600081816113b40152818161218601528181612a7e01528181612b4201526132bd0152615c1e6000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063aab396bd116100e3578063d7ae1d3011610097578063e82ad7d411610071578063e82ad7d4146106bf578063ea320e0b146106d2578063f2fde38b146106e557600080fd5b8063d7ae1d3014610686578063e72f6e3014610699578063e82622aa146106ac57600080fd5b8063badc3eb6116100c8578063badc3eb614610648578063c3f909d41461065e578063cc77470a1461067357600080fd5b8063aab396bd14610638578063b734c0f41461064057600080fd5b80639f87fad71161013a578063a47c76961161011f578063a47c7696146105f2578063a4c0ed3614610612578063a9c9a9181461062557600080fd5b80639f87fad7146105d7578063a21a23e4146105ea57600080fd5b8063823597401161016b57806382359740146105995780638456cb59146105ac5780638da5cb5b146105b457600080fd5b80637341c10c1461057e57806379ba50971461059157600080fd5b80633f4ba83a1161023f5780635c975abb116101f357806366419970116101cd57806366419970146104d6578063674603d0146104fd5780636a2215de1461054657600080fd5b80635c975abb146104995780635ed6dfba146104b057806366316d8d146104c357600080fd5b8063461d276211610224578063461d2762146104455780634b8832d31461045857806355fedefa1461046b57600080fd5b80633f4ba83a1461041c57806341db4ca31461042457600080fd5b80631ded3b36116102965780632a905ccc1161027b5780632a905ccc146103ba57806333060529146103e85780633e871e4d1461040957600080fd5b80631ded3b361461039457806321b60e7f146103a757600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f13660046148f7565b6106f8565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f6610326366004614938565b610757565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f91906149df565b6102f66103a23660046149f2565b610853565b6102f66103b5366004614bb5565b610885565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161030f565b6103fb6103f6366004614e61565b6109b2565b60405161030f929190614f49565b6102f6610417366004614fd6565b610d8a565b6102f661100f565b6104376104323660046150d8565b611021565b60405190815260200161030f565b6104376104533660046150d8565b611081565b6102f661046636600461515c565b61108d565b6104376104793660046148f7565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f66104be36600461518a565b6111db565b6102f66104d136600461518a565b6113fd565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b61051061050b3660046151b8565b61154f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161030f565b6105596105543660046151e6565b6115df565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f661058c36600461515c565b61169e565b6102f6611851565b6102f66105a73660046148f7565b611978565b6102f6611abf565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610559565b6102f66105e536600461515c565b611acf565b6104e4611ea4565b6106056106003660046148f7565b612031565b60405161030f9190615250565b6102f66106203660046152d8565b612166565b6105596106333660046151e6565b6123b2565b600954610437565b6102f6612411565b61065061255d565b60405161030f929190615334565b61066661262d565b60405161030f919061538b565b6104e4610681366004615435565b612762565b6102f661069436600461515c565b6129e2565b6102f66106a7366004615435565b612a45565b6102f66106ba366004615452565b612bbe565b6104a06106cd3660046148f7565b612e8f565b6102f66106e03660046151e6565b612fde565b6102f66106f3366004615435565b612feb565b610700612ffc565b61070981613004565b67ffffffffffffffff81166000908152600360205260409020546107549082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661307a565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107bc576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106107d7576107d76154c8565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff16111561084d576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107b3565b50505050565b61085b612ffc565b61086482613004565b67ffffffffffffffff90911660009081526003602081905260409091200155565b61088d613366565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361097492600b92910190614742565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516109a7919061538b565b60405180910390a150565b6000806109bd6133ec565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a26576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251600090815260056020526040902054610a885782516020840151604051600294507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154f7565b60405180910390a2506000610d7f565b8251600090815260056020908152604091829020549151610aab91869101615529565b6040516020818303038152906040528051906020012014610b035782516020840151604051600694507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154f7565b8261012001518360a0015163ffffffff16610b1e9190615685565b64ffffffffff165a1015610b695782516020840151604051600494507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a7891889087906154f7565b6000610b7e8460a0015163ffffffff166133f4565b610b8890886156aa565b9050600081878660c0015168ffffffffffffffffff16610ba891906156d2565b610bb291906156d2565b9050610bc18560800151612031565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c395784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154f7565b60405180910390a25060009150610d7f9050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c9e5784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a9089906154f7565b505082516000908152600560205260408120819055835160a08501516060860151610cce92918c918c9190613496565b8051909150610cde576001610ce1565b60005b92506000610d1b8560800151866040015187606001518860c0015168ffffffffffffffffff168c610d1588602001516133f4565b8d613654565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610d72969594939291906156f7565b60405180910390a3519150505b965096945050505050565b610d92613366565b8151815181141580610da45750600881115b15610ddb576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ecd576000848281518110610dfa57610dfa6154c8565b602002602001015190506000848381518110610e1857610e186154c8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e83575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610eba576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080610ec69061577a565b9050610dde565b506040805180820190915283815260208082018490528451600c91610ef69183918801906147ed565b506020828101518051610f0f9260018501920190614828565b5090505060005b835181101561084d577f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481848281518110610f5257610f526154c8565b602002602001015160086000878581518110610f7057610f706154c8565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858481518110610fb957610fb96154c8565b6020026020010151604051610ff79392919092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a16110088161577a565b9050610f16565b611017613366565b61101f6139d6565b565b60008061102d836115df565b905061107583828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613a539050565b98975050505050505050565b60008061102d836123b2565b6110956133ec565b61109e82613e4b565b6110a6613f11565b73ffffffffffffffffffffffffffffffffffffffff8116158061110d575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15611144576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6111e3612ffc565b806bffffffffffffffffffffffff166000036112195750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611285576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff808416911610156112ee576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b306000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff166157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff1661137191906157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506113f883836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661401b9092919063ffffffff16565b505050565b6114056133ec565b806bffffffffffffffffffffffff1660000361144d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff9081169082168110156114b9576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff80841691161015611522576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b336000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff166157b2565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600c5460ff8216101561166857600c805460ff8316908110611607576116076154c8565b9060005260206000200154830361165857600d805460ff831690811061162f5761162f6154c8565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b611661816157d7565b90506115e3565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107b3565b6116a66133ec565b6116af82613e4b565b6116b7613f11565b60006116c6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff821611611728576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff161561177057505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff1633146118d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107b3565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6119806133ec565b611988613f11565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611a28576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107b3565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611844565b611ac7613366565b61101f6140a8565b611ad76133ec565b611ae082613e4b565b611ae8613f11565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b90576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611be5576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611c6057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c35575b5050505050905060005b8151811015611e08578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c9c57611c9c6154c8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611df8578160018351611cce91906157f6565b81518110611cde57611cde6154c8565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611d2157611d216154c8565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d9b57611d9b615809565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611e08565b611e018161577a565b9050611c6a565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b6000611eae6133ec565b611eb6613f11565b60028054600090611ed09067ffffffffffffffff16615838565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611f46578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611fe192600285019290910190614828565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a081019190915261206b82613004565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561214c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612121575b505050505081526020016003820154815250509050919050565b61216e6133ec565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146121dd576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612217576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612225828401846148f7565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661229e576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906122d583856156d2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff1661232b91906156d2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f8828784612392919061585f565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff16806115d9576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107b3565b612419613366565b60005b600c5481101561253c576000600c600001828154811061243e5761243e6154c8565b906000526020600020015490506000600c6001018381548110612463576124636154c8565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556125358161577a565b905061241c565b50600c600061254b82826148a2565b6125596001830160006148a2565b5050565b606080600c600001600c600101818054806020026020016040519081016040528092919081815260200182805480156125b557602002820191906000526020600020905b8154815260200190600101908083116125a1575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561261e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116125f3575b50505050509050915091509091565b6040805160a08101825260008082526020820181905291810182905260608082019290925260808101919091526040805160a081018252600a805461ffff808216845268ffffffffffffffffff620100008304166020808601919091527fffffffff000000000000000000000000000000000000000000000000000000006b010000000000000000000000840460e01b16858701526f01000000000000000000000000000000909204166060840152600b80548551818402810184019096528086529394929360808601939283018282801561275457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116127175790505b505050505081525050905090565b600061276c6133ec565b612774613f11565b6002805460009061278e9067ffffffffffffffff16615838565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015612804578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff938416178455938601516060870151909116909302921691909117600182015560808301518051919261289f92600285019290910190614828565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b6129ea6133ec565b6129f382613e4b565b6129fb613f11565b612a0482612e8f565b15612a3b576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612559828261307a565b612a4d612ffc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612ada573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612afe9190615872565b6000549091506bffffffffffffffffffffffff16818110156113f8576000612b2682846157f6565b9050612b6973ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016858361401b565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612bc66133ec565b60005b818110156113f8576000838383818110612be557612be56154c8565b90506101600201803603810190612bfc919061588b565b80516080820151600082815260056020908152604091829020549151949550929391929091612c2d91869101615529565b6040516020818303038152906040528051906020012014612c7a576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612cbf576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015612d32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5691906158a8565b5060408084015167ffffffffffffffff831660009081526003602052918220600101805491929091612d979084906bffffffffffffffffffffffff166157b2565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612e1f91859169010000000000000000009004166158ca565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612e889061577a565b9050612bc9565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612f0757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612edc575b5050505050905060005b8151811015612fd457600060046000848481518110612f3257612f326154c8565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612fc357506001949350505050565b50612fcd8161577a565b9050612f11565b5060009392505050565b612fe6613366565b600955565b612ff3613366565b61075481614103565b61101f613366565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610754576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561315b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613130575b505050918352505060039190910154602090910152805190915060005b82608001515181101561321c57600460008460800151838151811061319f5761319f6154c8565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690556132158161577a565b9050613178565b5067ffffffffffffffff84166000908152600360205260408120818155600181018290559061324e60028301826148a2565b5060006003919091018190558054829190819061327a9084906bffffffffffffffffffffffff166157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061330183826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661401b9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e96565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16331461101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107b3565b61101f6141ff565b60006bffffffffffffffffffffffff821115613492576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107b3565b5090565b60408051606080820183526000808352602083015291810191909152813b1580156134e957505060408051606081018252600080825260208083018290528351918252810183529181019190915261364b565b600a546040516000916b010000000000000000000000900460e01b90613517908a908a908a906024016158eb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f01000000000000000000000000000000909104169260009283928392820181803683370190505090505a848110156135e557600080fd5b8490036040810481038a106135f957600080fd5b505a60008087516020890160008d8ff193505a900391503d608481111561361e575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015293505050505b95945050505050565b6040805180820190915260008082526020820152600061367484866156aa565b905060008161368388866156d2565b61368d91906156d2565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff808316911610156137205767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812080548392906137579084906bffffffffffffffffffffffff166157b2565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600360205260409020600101548b82169116101590506138045767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812060010180548b929061383e9084906bffffffffffffffffffffffff166157b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461387891906156d2565b33600090815260016020526040812080549091906138a59084906bffffffffffffffffffffffff166156d2565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926138ec918591166156d2565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f1685529252909120805460019260099161397091859169010000000000000000009004166158ca565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b6139de61426c565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613a5d6133ec565b613a6685613004565b613a7033866142d8565b613a7a8583610757565b8351600003613ab4576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613abf86612031565b90506000613acd338861154f565b905060008873ffffffffffffffffffffffffffffffffffffffff1663a631571e6040518061016001604052808a8152602001613b238c67ffffffffffffffff166000908152600360208190526040909120015490565b815233602082015260408781015188519190920191613b41916157b2565b6bffffffffffffffffffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018b67ffffffffffffffff168152602001856020015167ffffffffffffffff1681526020018863ffffffff1681526020018961ffff168152602001856040015167ffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613c079190615916565b610160604051808303816000875af1158015613c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c4b9190615a7b565b805160009081526005602052604090205490915015613c9c5780516040517f304f32e800000000000000000000000000000000000000000000000000000000815260048101919091526024016107b3565b604051806101600160405280826000015181526020018a73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018967ffffffffffffffff1681526020018663ffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff16815250604051602001613da19190615529565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550613de13389836040015161434c565b8767ffffffffffffffff168a82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9866020015133328d8d8d8a60400151604051613e359796959493929190615b4e565b60405180910390a4519998505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613ec2576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614612559576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613f415750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613fa290339060248101615bc6565b602060405180830381865afa158015613fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fe391906158a8565b610754576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107b3565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f8908490614427565b6140b06141ff565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613a293390565b3373ffffffffffffffffffffffffffffffffffffffff821603614182576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107b3565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff161561101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107b3565b60065460ff1661101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff16612559576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143869084906bffffffffffffffffffffffff166156d2565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff80891685529252909120805460019450909284926143fc9284929004166158ca565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b6000614489826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166145339092919063ffffffff16565b8051909150156113f857808060200190518101906144a791906158a8565b6113f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107b3565b6060614542848460008561454a565b949350505050565b6060824710156145dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107b3565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516146059190615bf5565b60006040518083038185875af1925050503d8060008114614642576040519150601f19603f3d011682016040523d82523d6000602084013e614647565b606091505b509150915061465887838387614663565b979650505050505050565b606083156146f95782516000036146f25773ffffffffffffffffffffffffffffffffffffffff85163b6146f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b5081614542565b614542838381511561470e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b391906149df565b828054828255906000526020600020906007016008900481019282156147e15791602002820160005b838211156147af57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261476b565b80156147df5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026147af565b505b506134929291506148bc565b8280548282559060005260206000209081019282156147e1579160200282015b828111156147e157825182559160200191906001019061480d565b8280548282559060005260206000209081019282156147e1579160200282015b828111156147e157825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614848565b508054600082559060005260206000209081019061075491905b5b8082111561349257600081556001016148bd565b67ffffffffffffffff8116811461075457600080fd5b80356148f2816148d1565b919050565b60006020828403121561490957600080fd5b8135614914816148d1565b9392505050565b63ffffffff8116811461075457600080fd5b80356148f28161491b565b6000806040838503121561494b57600080fd5b8235614956816148d1565b915060208301356149668161491b565b809150509250929050565b60005b8381101561498c578181015183820152602001614974565b50506000910152565b600081518084526149ad816020860160208601614971565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006149146020830184614995565b60008060408385031215614a0557600080fd5b8235614a10816148d1565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614a7057614a70614a1e565b60405290565b604051610160810167ffffffffffffffff81118282101715614a7057614a70614a1e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ae157614ae1614a1e565b604052919050565b803561ffff811681146148f257600080fd5b68ffffffffffffffffff8116811461075457600080fd5b80356148f281614afb565b600067ffffffffffffffff821115614b3757614b37614a1e565b5060051b60200190565b600082601f830112614b5257600080fd5b81356020614b67614b6283614b1d565b614a9a565b82815260059290921b84018101918181019086841115614b8657600080fd5b8286015b84811015614baa578035614b9d8161491b565b8352918301918301614b8a565b509695505050505050565b600060208284031215614bc757600080fd5b813567ffffffffffffffff80821115614bdf57600080fd5b9083019060a08286031215614bf357600080fd5b614bfb614a4d565b614c0483614ae9565b81526020830135614c1481614afb565b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114614c4c57600080fd5b6040820152614c5d60608401614ae9565b6060820152608083013582811115614c7457600080fd5b614c8087828601614b41565b60808301525095945050505050565b600082601f830112614ca057600080fd5b813567ffffffffffffffff811115614cba57614cba614a1e565b614ceb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a9a565b818152846020838601011115614d0057600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461075457600080fd5b80356148f281614d1d565b73ffffffffffffffffffffffffffffffffffffffff8116811461075457600080fd5b80356148f281614d42565b64ffffffffff8116811461075457600080fd5b80356148f281614d6f565b60006101608284031215614da057600080fd5b614da8614a76565b905081358152614dba60208301614d64565b6020820152614dcb60408301614d37565b6040820152614ddc60608301614d64565b6060820152614ded608083016148e7565b6080820152614dfe60a0830161492d565b60a0820152614e0f60c08301614b12565b60c0820152614e2060e08301614b12565b60e0820152610100614e33818401614d82565b90820152610120614e45838201614d82565b90820152610140614e5783820161492d565b9082015292915050565b6000806000806000806102008789031215614e7b57600080fd5b863567ffffffffffffffff80821115614e9357600080fd5b614e9f8a838b01614c8f565b97506020890135915080821115614eb557600080fd5b50614ec289828a01614c8f565b9550506040870135614ed381614d1d565b93506060870135614ee381614d1d565b92506080870135614ef381614d42565b9150614f028860a08901614d8d565b90509295509295509295565b60078110614f45577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60408101614f578285614f0e565b6bffffffffffffffffffffffff831660208301529392505050565b600082601f830112614f8357600080fd5b81356020614f93614b6283614b1d565b82815260059290921b84018101918181019086841115614fb257600080fd5b8286015b84811015614baa578035614fc981614d42565b8352918301918301614fb6565b60008060408385031215614fe957600080fd5b823567ffffffffffffffff8082111561500157600080fd5b818501915085601f83011261501557600080fd5b81356020615025614b6283614b1d565b82815260059290921b8401810191818101908984111561504457600080fd5b948201945b8386101561506257853582529482019490820190615049565b9650508601359250508082111561507857600080fd5b5061508585828601614f72565b9150509250929050565b60008083601f8401126150a157600080fd5b50813567ffffffffffffffff8111156150b957600080fd5b6020830191508360208285010111156150d157600080fd5b9250929050565b60008060008060008060a087890312156150f157600080fd5b86356150fc816148d1565b9550602087013567ffffffffffffffff81111561511857600080fd5b61512489828a0161508f565b9096509450615137905060408801614ae9565b925060608701356151478161491b565b80925050608087013590509295509295509295565b6000806040838503121561516f57600080fd5b823561517a816148d1565b9150602083013561496681614d42565b6000806040838503121561519d57600080fd5b82356151a881614d42565b9150602083013561496681614d1d565b600080604083850312156151cb57600080fd5b82356151d681614d42565b91506020830135614966816148d1565b6000602082840312156151f857600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561524557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101615213565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a08401526152c260e08401826151ff565b905060a084015160c08401528091505092915050565b600080600080606085870312156152ee57600080fd5b84356152f981614d42565b935060208501359250604085013567ffffffffffffffff81111561531c57600080fd5b6153288782880161508f565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b8281101561536d57815184529284019290840190600101615351565b5050508381038285015261538181866151ff565b9695505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b80831015614baa57835163ffffffff16825292840192600192909201919084019061540f565b60006020828403121561544757600080fd5b813561491481614d42565b6000806020838503121561546557600080fd5b823567ffffffffffffffff8082111561547d57600080fd5b818501915085601f83011261549157600080fd5b8135818111156154a057600080fd5b866020610160830285010111156154b657600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016145426040830184614f0e565b8151815260208083015161016083019161555a9084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015161557a60408401826bffffffffffffffffffffffff169052565b5060608301516155a2606084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060808301516155be608084018267ffffffffffffffff169052565b5060a08301516155d660a084018263ffffffff169052565b5060c08301516155f360c084018268ffffffffffffffffff169052565b5060e083015161561060e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff8181168382160190808211156156a3576156a3615656565b5092915050565b6bffffffffffffffffffffffff81811683821602808216919082811461564e5761564e615656565b6bffffffffffffffffffffffff8181168382160190808211156156a3576156a3615656565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff861660208201526157316040820186614f0e565b60c06060820152600061574760c0830186614995565b82810360808401526157598186614995565b905082810360a084015261576d8185614995565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036157ab576157ab615656565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156156a3576156a3615656565b600060ff821660ff81036157ed576157ed615656565b60010192915050565b818103818111156115d9576115d9615656565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff80831681810361585557615855615656565b6001019392505050565b808201808211156115d9576115d9615656565b60006020828403121561588457600080fd5b5051919050565b6000610160828403121561589e57600080fd5b6149148383614d8d565b6000602082840312156158ba57600080fd5b8151801515811461491457600080fd5b67ffffffffffffffff8181168382160190808211156156a3576156a3615656565b8381526060602082015260006159046060830185614995565b82810360408401526153818185614995565b6020815260008251610160806020850152615935610180850183614995565b9150602085015160408501526040850151615968606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e08501516101006159df8187018363ffffffff169052565b86015190506101206159f68682018361ffff169052565b8601519050610140615a138682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b80516148f281614d42565b80516148f281614d1d565b80516148f2816148d1565b80516148f28161491b565b80516148f281614afb565b80516148f281614d6f565b60006101608284031215615a8e57600080fd5b615a96614a76565b82518152615aa660208401615a39565b6020820152615ab760408401615a44565b6040820152615ac860608401615a39565b6060820152615ad960808401615a4f565b6080820152615aea60a08401615a5a565b60a0820152615afb60c08401615a65565b60c0820152615b0c60e08401615a65565b60e0820152610100615b1f818501615a70565b90820152610120615b31848201615a70565b90820152610140615b43848201615a5a565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615b8f60e0830187614995565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006145426040830184614995565b60008251615c07818460208701614971565b919091019291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateRequestId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"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\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionIdStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionIdEnd\",\"type\":\"uint64\"}],\"name\":\"getSubscriptionsInRange\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription[]\",\"name\":\"subscriptions\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"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\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200673c3803806200673c833981016040819052620000349162000549565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200071a565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b4620002c0565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b9291019062000323565b5060a08201516002909101805460c0909301516001600160481b031662010000026001600160581b031990931661ffff909216919091179190911790556040517ea5832bf95f66c7814294cc4db681f20ee79608bfb8912a5321d66cfed5e98590620002b590839062000652565b60405180910390a150565b60065461010090046001600160a01b03163314620003215760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b82805482825590600052602060002090600701600890048101928215620003c75791602002820160005b838211156200039357835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026200034d565b8015620003c55782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000393565b505b50620003d5929150620003d9565b5090565b5b80821115620003d55760008155600101620003da565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b03811182821017156200042b576200042b620003f0565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200045c576200045c620003f0565b604052919050565b805161ffff811681146200047757600080fd5b919050565b80516001600160481b03811681146200047757600080fd5b80516001600160e01b0319811681146200047757600080fd5b600082601f830112620004bf57600080fd5b815160206001600160401b03821115620004dd57620004dd620003f0565b8160051b620004ee82820162000431565b92835284810182019282810190878511156200050957600080fd5b83870192505b848310156200053e57825163ffffffff811681146200052e5760008081fd5b825291830191908301906200050f565b979650505050505050565b600080604083850312156200055d57600080fd5b82516001600160a01b03811681146200057557600080fd5b60208401519092506001600160401b03808211156200059357600080fd5b9084019060e08287031215620005a857600080fd5b620005b262000406565b620005bd8362000464565b8152620005cd602084016200047c565b6020820152620005e06040840162000494565b6040820152620005f36060840162000464565b60608201526080830151828111156200060b57600080fd5b6200061988828601620004ad565b6080830152506200062d60a0840162000464565b60a08201526200064060c084016200047c565b60c08201528093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160e060a0840152805161010084018190526000929182019083906101208601905b80831015620006e857835163ffffffff168252928401926001929092019190840190620006c0565b5060a087015161ffff811660c0880152935060c08701516001600160481b03811660e088015293509695505050505050565b608051615fea62000752600039600081816111cd0152818161208c015281816129b801528181612a7c01526135d30152615fea6000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c80637341c10c11610191578063b734c0f4116100e3578063e72f6e3011610097578063ea320e0b11610071578063ea320e0b146106dd578063ec2454e5146106f0578063f2fde38b1461071057600080fd5b8063e72f6e30146106a4578063e82622aa146106b7578063e82ad7d4146106ca57600080fd5b8063c3f909d4116100c8578063c3f909d414610669578063cc77470a1461067e578063d7ae1d301461069157600080fd5b8063b734c0f41461064b578063badc3eb61461065357600080fd5b80639f87fad711610145578063a4c0ed361161011f578063a4c0ed361461061d578063a9c9a91814610630578063aab396bd1461064357600080fd5b80639f87fad7146105e2578063a21a23e4146105f5578063a47c7696146105fd57600080fd5b8063823597401161017657806382359740146105a45780638456cb59146105b75780638da5cb5b146105bf57600080fd5b80637341c10c1461058957806379ba50971461059c57600080fd5b806341db4ca31161024a5780635ed6dfba116101fe57806366419970116101d857806366419970146104e1578063674603d0146105085780636a2215de1461055157600080fd5b80635ed6dfba146104a85780636162a323146104bb57806366316d8d146104ce57600080fd5b80634b8832d31161022f5780634b8832d31461045057806355fedefa146104635780635c975abb1461049157600080fd5b806341db4ca31461041c578063461d27621461043d57600080fd5b80631ded3b36116102a1578063330605291161028657806333060529146103e05780633e871e4d146104015780633f4ba83a1461041457600080fd5b80631ded3b361461039f5780632a905ccc146103b257600080fd5b806310fc49c1116102d257806310fc49c11461032357806312b5834914610336578063181f5a771461035657600080fd5b806302bcc5b6146102ee5780630c5d49cb14610303575b600080fd5b6103016102fc366004614ba6565b610723565b005b61030b608481565b60405161ffff90911681526020015b60405180910390f35b610301610331366004614be7565b610783565b6000546040516bffffffffffffffffffffffff909116815260200161031a565b6103926040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161031a9190614c8e565b6103016103ad366004614ca1565b61087f565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161031a565b6103f36103ee366004614f8c565b6108b1565b60405161031a929190615074565b61030161040f366004615135565b610c7c565b610301610e91565b61042f61042a366004615249565b610ea3565b60405190815260200161031a565b61042f61044b366004615249565b610f03565b61030161045e3660046152cd565b610f0f565b61042f610471366004614ba6565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161031a565b6103016104b63660046152fb565b61105d565b6103016104c93660046153bd565b611216565b6103016104dc3660046152fb565b611396565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161031a565b61051b610516366004615490565b61147f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161031a565b61056461055f3660046154be565b61150f565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161031a565b6103016105973660046152cd565b6115ce565b610301611781565b6103016105b2366004614ba6565b6118a8565b6103016119ef565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610564565b6103016105f03660046152cd565b6119ff565b6104ef611daa565b61061061060b366004614ba6565b611f37565b60405161031a91906155a7565b61030161062b3660046155ba565b61206c565b61056461063e3660046154be565b6122b8565b60095461042f565b610301612317565b61065b612463565b60405161031a929190615616565b610671612533565b60405161031a919061566d565b6104ef61068c366004615749565b61269a565b61030161069f3660046152cd565b61291a565b6103016106b2366004615749565b61297f565b6103016106c5366004615766565b612af8565b6104986106d8366004614ba6565b612db7565b6103016106eb3660046154be565b612f06565b6107036106fe3660046157dc565b612f13565b60405161031a91906157fa565b61030161071e366004615749565b6131a8565b61072b6131b9565b610734816131c1565b67ffffffffffffffff81166000908152600360205260408120546107809183916c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690613237565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107e8576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106108035761080361587a565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff161115610879576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107df565b50505050565b6108876131b9565b610890826131c1565b67ffffffffffffffff90911660009081526003602081905260409091200155565b6000806108bc613689565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610925576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82516000908152600560205260409020548061098a5783516020850151604051600295507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee19161097891899088906158a9565b60405180910390a25060009050610c71565b808460405160200161099c91906158db565b60405160208183030381529060405280519060200120146109f45783516020850151604051600695507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee19161097891899088906158a9565b8361012001518460a0015163ffffffff16610a0f9190615a37565b64ffffffffff165a1015610a5a5783516020850151604051600495507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee19161097891899088906158a9565b506000610a708460a0015163ffffffff16613691565b610a7a9088615a55565b9050600081878660c0015168ffffffffffffffffff16610a9a9190615a7d565b610aa49190615a7d565b9050610ab38560800151611f37565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610b2b5784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610b17918a9089906158a9565b60405180910390a25060009150610c719050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610b905784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610b17918a9089906158a9565b505082516000908152600560205260408120819055835160a08501516060860151610bc092918c918c9190613733565b8051909150610bd0576001610bd3565b60005b92506000610c0d8560800151866040015187606001518860c0015168ffffffffffffffffff168c610c078860200151613691565b8d6138f1565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610c6496959493929190615aa2565b60405180910390a3519150505b965096945050505050565b610c84613c17565b8151815181141580610c965750600881115b15610ccd576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e47576000848281518110610cec57610cec61587a565b602002602001015190506000848381518110610d0a57610d0a61587a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610d75575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610dac576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040908190205490517f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f48191610e2c91859173ffffffffffffffffffffffffffffffffffffffff1690859092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a1505080610e4090615b25565b9050610cd0565b506040805180820190915283815260208082018490528451600d91610e709183918801906149e6565b506020828101518051610e899260018501920190614a2d565b505050505050565b610e99613c17565b610ea1613c9d565b565b600080610eaf8361150f565b9050610ef783828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613d1a9050565b98975050505050505050565b600080610eaf836122b8565b610f17613689565b610f20826140ef565b610f286141b5565b73ffffffffffffffffffffffffffffffffffffffff81161580610f8f575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15610fc6576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6110656131b9565b806bffffffffffffffffffffffff1660000361109b5750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611107576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107df565b30600090815260016020526040812080548492906111349084906bffffffffffffffffffffffff16615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff1661118a9190615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061121183836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166142bf9092919063ffffffff16565b505050565b61121e613c17565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361130592600b92910190614aa7565b5060a08201516002909101805460c09093015168ffffffffffffffffff1662010000027fffffffffffffffffffffffffffffffffffffffffff000000000000000000000090931661ffff909216919091179190911790556040517ea5832bf95f66c7814294cc4db681f20ee79608bfb8912a5321d66cfed5e9859061138b90839061566d565b60405180910390a150565b61139e613689565b806bffffffffffffffffffffffff166000036113e6576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611452576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107df565b33600090815260016020526040812080548492906111349084906bffffffffffffffffffffffff16615b5d565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600d5460ff8216101561159857600d805460ff83169081106115375761153761587a565b9060005260206000200154830361158857600e805460ff831690811061155f5761155f61587a565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b61159181615b82565b9050611513565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107df565b6115d6613689565b6115df826140ef565b6115e76141b5565b60006115f6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff821611611658576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107df565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff16156116a057505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff163314611802576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107df565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6118b0613689565b6118b86141b5565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611958576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107df565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611774565b6119f7613c17565b610ea161434c565b611a07613689565b611a10826140ef565b611a186141b5565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151582526101008104851693820193909352690100000000000000000090920490921691810191909152611a9782846143a7565b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611aec576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611b6757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611b3c575b5050505050905060005b8151811015611d0f578373ffffffffffffffffffffffffffffffffffffffff16828281518110611ba357611ba361587a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611cff578160018351611bd59190615ba1565b81518110611be557611be561587a565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611c2857611c2861587a565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611ca257611ca2615bb4565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611d0f565b611d0881615b25565b9050611b71565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b910160405180910390a250505050565b6000611db4613689565b611dbc6141b5565b60028054600090611dd69067ffffffffffffffff16615be3565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611e4c578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611ee792600285019290910190614a2d565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a0810191909152611f71826131c1565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561205257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612027575b505050505081526020016003820154815250509050919050565b612074613689565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146120e3576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020811461211d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061212b82840184614ba6565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166121a4576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906121db8385615a7d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff166122319190615a7d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846122989190615c0a565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff1680611509576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107df565b61231f613c17565b60005b600d54811015612442576000600d60000182815481106123445761234461587a565b906000526020600020015490506000600d60010183815481106123695761236961587a565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905561243b81615b25565b9050612322565b50600d60006124518282614b51565b61245f600183016000614b51565b5050565b606080600d600001600d600101818054806020026020016040519081016040528092919081815260200182805480156124bb57602002820191906000526020600020905b8154815260200190600101908083116124a7575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561252457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116124f9575b50505050509050915091509091565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082015260a0810182905260c08101919091526040805160e08082018352600a805461ffff808216855262010000820468ffffffffffffffffff166020808701919091526b010000000000000000000000830490941b7fffffffff0000000000000000000000000000000000000000000000000000000016858701526f01000000000000000000000000000000909104166060840152600b805485518185028101850190965280865293949193608086019383018282801561266557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116126285790505b50505091835250506002919091015461ffff8116602083015262010000900468ffffffffffffffffff16604090910152919050565b60006126a4613689565b6126ac6141b5565b600280546000906126c69067ffffffffffffffff16615be3565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c081018252600080825233602083015291810182905260608101829052919250608082019060405190808252806020026020018201604052801561273c578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff93841617845593860151606087015190911690930292169190911760018201556080830151805191926127d792600285019290910190614a2d565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b612922613689565b61292b826140ef565b6129336141b5565b61293c82612db7565b15612973576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61245f82826001613237565b6129876131b9565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a389190615c1d565b6000549091506bffffffffffffffffffffffff1681811015611211576000612a608284615ba1565b9050612aa373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685836142bf565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612b00613689565b60005b81811015611211576000838383818110612b1f57612b1f61587a565b90506101600201803603810190612b369190615c36565b80516080820151600082815260056020908152604091829020549151949550929391929091612b67918691016158db565b6040516020818303038152906040528051906020012014612bb4576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612bf9576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf90602401600060405180830381600087803b158015612c6757600080fd5b505af1158015612c7b573d6000803e3d6000fd5b50505060408085015167ffffffffffffffff84166000908152600360205291822060010180549193509190612cbf9084906bffffffffffffffffffffffff16615b5d565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612d479185916901000000000000000000900416615c53565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612db090615b25565b9050612b03565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612e2f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612e04575b5050505050905060005b8151811015612efc57600060046000848481518110612e5a57612e5a61587a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612eeb57506001949350505050565b50612ef581615b25565b9050612e39565b5060009392505050565b612f0e613c17565b600955565b60608167ffffffffffffffff168367ffffffffffffffff161180612f46575060025467ffffffffffffffff908116908316115b80612f5b575060025467ffffffffffffffff16155b15612f92576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612f9c8383615c74565b612fa7906001615c53565b67ffffffffffffffff1667ffffffffffffffff811115612fc957612fc9614ccd565b60405190808252806020026020018201604052801561304657816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612fe75790505b50905060005b6130568484615c74565b67ffffffffffffffff1681116131a1576003600061307e8367ffffffffffffffff8816615c0a565b67ffffffffffffffff1681526020808201929092526040908101600020815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561316057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613135575b505050505081526020016003820154815250508282815181106131855761318561587a565b60200260200101819052508061319a90615b25565b905061304c565b5092915050565b6131b0613c17565b6107808161441b565b610ea1613c17565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610780576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff83166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561331857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116132ed575b50505091835250506003919091015460209091015280519091506000805b83608001515181101561342e5760008460800151828151811061335b5761335b61587a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff8116600090815260048352604080822067ffffffffffffffff808e16845294529020549092506133bb9169010000000000000000009091041684615c53565b73ffffffffffffffffffffffffffffffffffffffff909116600090815260046020908152604080832067ffffffffffffffff8c168452909152902080547fffffffffffffffffffffffffffffff0000000000000000000000000000000000169055915061342781615b25565b9050613336565b5067ffffffffffffffff8616600090815260036020526040812081815560018101829055906134606002830182614b51565b50600060039190910155600c5461ffff81169062010000900468ffffffffffffffffff1685801561349e57508161ffff168367ffffffffffffffff16105b1561355a576000846bffffffffffffffffffffffff168268ffffffffffffffffff16116134d6578168ffffffffffffffffff166134d8565b845b90506bffffffffffffffffffffffff81161561355857306000908152600160205260408120805483929061351b9084906bffffffffffffffffffffffff16615a7d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080856135559190615b5d565b94505b505b6bffffffffffffffffffffffff841615613617576000805485919081906135909084906bffffffffffffffffffffffff16615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061361787856bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166142bf9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff891681526bffffffffffffffffffffffff8616602082015267ffffffffffffffff8a16917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815910160405180910390a25050505050505050565b610ea1614517565b60006bffffffffffffffffffffffff82111561372f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107df565b5090565b60408051606080820183526000808352602083015291810191909152813b1580156137865750506040805160608101825260008082526020808301829052835191825281018352918101919091526138e8565b600a546040516000916b010000000000000000000000900460e01b906137b4908a908a908a90602401615c95565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f01000000000000000000000000000000909104169260009283928392820181803683370190505090505a8481101561388257600080fd5b8490036040810481038a1061389657600080fd5b505a60008087516020890160008d8ff193505a900391503d60848111156138bb575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015293505050505b95945050505050565b604080518082019091526000808252602082015260006139118486615a55565b90506000816139208886615a7d565b61392a9190615a7d565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff80831691161080613991575067ffffffffffffffff8a166000908152600360205260409020600101546bffffffffffffffffffffffff808b169116105b156139f45767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107df565b67ffffffffffffffff8a1660009081526003602052604081208054839290613a2b9084906bffffffffffffffffffffffff16615b5d565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c16600090815260036020526040812060010180548d94509092613a7f91859116615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508184613ab99190615a7d565b3360009081526001602052604081208054909190613ae69084906bffffffffffffffffffffffff16615a7d565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b94509092613b2d91859116615a7d565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f16855292529091208054600192600991613bb19185916901000000000000000000900416615c53565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b600654610100900473ffffffffffffffffffffffffffffffffffffffff163314610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107df565b613ca5614584565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613d24613689565b613d2d856131c1565b613d3733866143a7565b613d418583610783565b8351600003613d7b576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613d8686611f37565b90506000613d94338861147f565b600a54604080516101608101825289815267ffffffffffffffff8b1660009081526003602081815293822001549495506201000090930468ffffffffffffffffff169373ffffffffffffffffffffffffffffffffffffffff8d169263a631571e929190820190815233602082015260408881015189519190920191613e1891615b5d565b6bffffffffffffffffffffffff1681526020018568ffffffffffffffffff1681526020018c67ffffffffffffffff168152602001866020015167ffffffffffffffff1681526020018963ffffffff1681526020018a61ffff168152602001866040015167ffffffffffffffff168152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613ec49190615cc0565b610160604051808303816000875af1158015613ee4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f089190615e25565b805160009081526005602052604090205490915015613f595780516040517f304f32e800000000000000000000000000000000000000000000000000000000815260048101919091526024016107df565b604051806101600160405280826000015181526020018b73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018a67ffffffffffffffff1681526020018763ffffffff1681526020018368ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff1681525060405160200161404491906158db565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550614084338a83604001516145f0565b8867ffffffffffffffff168b82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9876020015133328e8e8e8a604001516040516140d89796959493929190615ef8565b60405180910390a4519a9950505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680614166576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461245f576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff16806141e55750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf89061424690339060248101615f70565b602060405180830381865afa158015614263573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142879190615f9f565b610780576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107df565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112119084906146cb565b614354614517565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613cf03390565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff1661245f576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82160361449a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107df565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff1615610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107df565b60065460ff16610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107df565b67ffffffffffffffff82166000908152600360205260408120600101805483929061462a9084906bffffffffffffffffffffffff16615a7d565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff80891685529252909120805460019450909284926146a0928492900416615c53565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b600061472d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166147d79092919063ffffffff16565b805190915015611211578080602001905181019061474b9190615f9f565b611211576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107df565b60606147e684846000856147ee565b949350505050565b606082471015614880576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107df565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516148a99190615fc1565b60006040518083038185875af1925050503d80600081146148e6576040519150601f19603f3d011682016040523d82523d6000602084013e6148eb565b606091505b50915091506148fc87838387614907565b979650505050505050565b6060831561499d5782516000036149965773ffffffffffffffffffffffffffffffffffffffff85163b614996576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107df565b50816147e6565b6147e683838151156149b25781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107df9190614c8e565b828054828255906000526020600020908101928215614a21579160200282015b82811115614a21578251825591602001919060010190614a06565b5061372f929150614b6b565b828054828255906000526020600020908101928215614a21579160200282015b82811115614a2157825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614a4d565b82805482825590600052602060002090600701600890048101928215614a215791602002820160005b83821115614b1457835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614ad0565b8015614b445782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614b14565b505061372f929150614b6b565b508054600082559060005260206000209081019061078091905b5b8082111561372f5760008155600101614b6c565b67ffffffffffffffff8116811461078057600080fd5b8035614ba181614b80565b919050565b600060208284031215614bb857600080fd5b8135614bc381614b80565b9392505050565b63ffffffff8116811461078057600080fd5b8035614ba181614bca565b60008060408385031215614bfa57600080fd5b8235614c0581614b80565b91506020830135614c1581614bca565b809150509250929050565b60005b83811015614c3b578181015183820152602001614c23565b50506000910152565b60008151808452614c5c816020860160208601614c20565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000614bc36020830184614c44565b60008060408385031215614cb457600080fd5b8235614cbf81614b80565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614d2057614d20614ccd565b60405290565b60405160e0810167ffffffffffffffff81118282101715614d2057614d20614ccd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614d9057614d90614ccd565b604052919050565b600082601f830112614da957600080fd5b813567ffffffffffffffff811115614dc357614dc3614ccd565b614df460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614d49565b818152846020838601011115614e0957600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461078057600080fd5b8035614ba181614e26565b73ffffffffffffffffffffffffffffffffffffffff8116811461078057600080fd5b8035614ba181614e4b565b68ffffffffffffffffff8116811461078057600080fd5b8035614ba181614e78565b64ffffffffff8116811461078057600080fd5b8035614ba181614e9a565b60006101608284031215614ecb57600080fd5b614ed3614cfc565b905081358152614ee560208301614e6d565b6020820152614ef660408301614e40565b6040820152614f0760608301614e6d565b6060820152614f1860808301614b96565b6080820152614f2960a08301614bdc565b60a0820152614f3a60c08301614e8f565b60c0820152614f4b60e08301614e8f565b60e0820152610100614f5e818401614ead565b90820152610120614f70838201614ead565b90820152610140614f82838201614bdc565b9082015292915050565b6000806000806000806102008789031215614fa657600080fd5b863567ffffffffffffffff80821115614fbe57600080fd5b614fca8a838b01614d98565b97506020890135915080821115614fe057600080fd5b50614fed89828a01614d98565b9550506040870135614ffe81614e26565b9350606087013561500e81614e26565b9250608087013561501e81614e4b565b915061502d8860a08901614eb8565b90509295509295509295565b60078110615070577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b604081016150828285615039565b6bffffffffffffffffffffffff831660208301529392505050565b600067ffffffffffffffff8211156150b7576150b7614ccd565b5060051b60200190565b600082601f8301126150d257600080fd5b813560206150e76150e28361509d565b614d49565b82815260059290921b8401810191818101908684111561510657600080fd5b8286015b8481101561512a57803561511d81614e4b565b835291830191830161510a565b509695505050505050565b6000806040838503121561514857600080fd5b823567ffffffffffffffff8082111561516057600080fd5b818501915085601f83011261517457600080fd5b813560206151846150e28361509d565b82815260059290921b840181019181810190898411156151a357600080fd5b948201945b838610156151c1578535825294820194908201906151a8565b965050860135925050808211156151d757600080fd5b506151e4858286016150c1565b9150509250929050565b60008083601f84011261520057600080fd5b50813567ffffffffffffffff81111561521857600080fd5b60208301915083602082850101111561523057600080fd5b9250929050565b803561ffff81168114614ba157600080fd5b60008060008060008060a0878903121561526257600080fd5b863561526d81614b80565b9550602087013567ffffffffffffffff81111561528957600080fd5b61529589828a016151ee565b90965094506152a8905060408801615237565b925060608701356152b881614bca565b80925050608087013590509295509295509295565b600080604083850312156152e057600080fd5b82356152eb81614b80565b91506020830135614c1581614e4b565b6000806040838503121561530e57600080fd5b823561531981614e4b565b91506020830135614c1581614e26565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114614ba157600080fd5b600082601f83011261536a57600080fd5b8135602061537a6150e28361509d565b82815260059290921b8401810191818101908684111561539957600080fd5b8286015b8481101561512a5780356153b081614bca565b835291830191830161539d565b6000602082840312156153cf57600080fd5b813567ffffffffffffffff808211156153e757600080fd5b9083019060e082860312156153fb57600080fd5b615403614d26565b61540c83615237565b815261541a60208401614e8f565b602082015261542b60408401615329565b604082015261543c60608401615237565b606082015260808301358281111561545357600080fd5b61545f87828601615359565b60808301525061547160a08401615237565b60a082015261548260c08401614e8f565b60c082015295945050505050565b600080604083850312156154a357600080fd5b82356154ae81614e4b565b91506020830135614c1581614b80565b6000602082840312156154d057600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561551d57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016154eb565b509495945050505050565b60006bffffffffffffffffffffffff808351168452602083015173ffffffffffffffffffffffffffffffffffffffff8082166020870152826040860151166040870152806060860151166060870152505050608082015160c0608085015261559360c08501826154d7565b60a093840151949093019390935250919050565b602081526000614bc36020830184615528565b600080600080606085870312156155d057600080fd5b84356155db81614e4b565b935060208501359250604085013567ffffffffffffffff8111156155fe57600080fd5b61560a878288016151ee565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b8281101561564f57815184529284019290840190600101615633565b5050508381038285015261566381866154d7565b9695505050505050565b60006020808352610100830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160e060a0860152818151808452610120870191508483019350600092505b8083101561571a57835163ffffffff1682529284019260019290920191908401906156f4565b5060a087015161ffff811660c0880152935060c087015168ffffffffffffffffff811660e08801529350615663565b60006020828403121561575b57600080fd5b8135614bc381614e4b565b6000806020838503121561577957600080fd5b823567ffffffffffffffff8082111561579157600080fd5b818501915085601f8301126157a557600080fd5b8135818111156157b457600080fd5b866020610160830285010111156157ca57600080fd5b60209290920196919550909350505050565b600080604083850312156157ef57600080fd5b82356154ae81614b80565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561586d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261585b858351615528565b94509285019290850190600101615821565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016147e66040830184615039565b8151815260208083015161016083019161590c9084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015161592c60408401826bffffffffffffffffffffffff169052565b506060830151615954606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151615970608084018267ffffffffffffffff169052565b5060a083015161598860a084018263ffffffff169052565b5060c08301516159a560c084018268ffffffffffffffffff169052565b5060e08301516159c260e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff8181168382160190808211156131a1576131a1615a08565b6bffffffffffffffffffffffff818116838216028082169190828114615a0057615a00615a08565b6bffffffffffffffffffffffff8181168382160190808211156131a1576131a1615a08565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff86166020820152615adc6040820186615039565b60c060608201526000615af260c0830186614c44565b8281036080840152615b048186614c44565b905082810360a0840152615b188185614c44565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615b5657615b56615a08565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156131a1576131a1615a08565b600060ff821660ff8103615b9857615b98615a08565b60010192915050565b8181038181111561150957611509615a08565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff808316818103615c0057615c00615a08565b6001019392505050565b8082018082111561150957611509615a08565b600060208284031215615c2f57600080fd5b5051919050565b60006101608284031215615c4957600080fd5b614bc38383614eb8565b67ffffffffffffffff8181168382160190808211156131a1576131a1615a08565b67ffffffffffffffff8281168282160390808211156131a1576131a1615a08565b838152606060208201526000615cae6060830185614c44565b82810360408401526156638185614c44565b6020815260008251610160806020850152615cdf610180850183614c44565b9150602085015160408501526040850151615d12606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e0850151610100615d898187018363ffffffff169052565b8601519050610120615da08682018361ffff169052565b8601519050610140615dbd8682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b8051614ba181614e4b565b8051614ba181614e26565b8051614ba181614b80565b8051614ba181614bca565b8051614ba181614e78565b8051614ba181614e9a565b60006101608284031215615e3857600080fd5b615e40614cfc565b82518152615e5060208401615de3565b6020820152615e6160408401615dee565b6040820152615e7260608401615de3565b6060820152615e8360808401615df9565b6080820152615e9460a08401615e04565b60a0820152615ea560c08401615e0f565b60c0820152615eb660e08401615e0f565b60e0820152610100615ec9818501615e1a565b90820152610120615edb848201615e1a565b90820152610140615eed848201615e04565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615f3960e0830187614c44565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006147e66040830184614c44565b600060208284031215615fb157600080fd5b81518015158114614bc357600080fd5b60008251615fd3818460208701614c20565b919091019291505056fea164736f6c6343000813000a", } var FunctionsRouterABI = FunctionsRouterMetaData.ABI @@ -451,6 +453,28 @@ func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscriptionCount() (ui return _FunctionsRouter.Contract.GetSubscriptionCount(&_FunctionsRouter.CallOpts) } +func (_FunctionsRouter *FunctionsRouterCaller) GetSubscriptionsInRange(opts *bind.CallOpts, subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error) { + var out []interface{} + err := _FunctionsRouter.contract.Call(opts, &out, "getSubscriptionsInRange", subscriptionIdStart, subscriptionIdEnd) + + if err != nil { + return *new([]IFunctionsSubscriptionsSubscription), err + } + + out0 := *abi.ConvertType(out[0], new([]IFunctionsSubscriptionsSubscription)).(*[]IFunctionsSubscriptionsSubscription) + + return out0, err + +} + +func (_FunctionsRouter *FunctionsRouterSession) GetSubscriptionsInRange(subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error) { + return _FunctionsRouter.Contract.GetSubscriptionsInRange(&_FunctionsRouter.CallOpts, subscriptionIdStart, subscriptionIdEnd) +} + +func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscriptionsInRange(subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error) { + return _FunctionsRouter.Contract.GetSubscriptionsInRange(&_FunctionsRouter.CallOpts, subscriptionIdStart, subscriptionIdEnd) +} + func (_FunctionsRouter *FunctionsRouterCaller) GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _FunctionsRouter.contract.Call(opts, &out, "getTotalBalance") @@ -3358,7 +3382,7 @@ func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.Abig } func (FunctionsRouterConfigUpdated) Topic() common.Hash { - return common.HexToHash("0x049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c") + return common.HexToHash("0x00a5832bf95f66c7814294cc4db681f20ee79608bfb8912a5321d66cfed5e985") } func (FunctionsRouterContractProposed) Topic() common.Hash { @@ -3460,6 +3484,8 @@ type FunctionsRouterInterface interface { GetSubscriptionCount(opts *bind.CallOpts) (uint64, error) + GetSubscriptionsInRange(opts *bind.CallOpts, subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error) + GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) IsValidCallbackGasLimit(opts *bind.CallOpts, subscriptionId uint64, callbackGasLimit uint32) error 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 9ba9e1ea565..07a431d993a 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,10 +4,10 @@ functions_allow_list: ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfSer functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin e7ccac9717c937a2a360a8de661178b4cceb7e3456fe56429009783549071941 +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin 21bd322caf977c4802d2c17419b57487cca438c7c5fafc52a9a9e1c9f4a72289 functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin c8dbbd5ebb34435800d6674700068837c3a252db60046a14b0e61e829db517de functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c -functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin 29b2dae67ffdbb7893e1e37ab5c3652f470bb4748827bba31c3b997c42b0e682 +functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin 9dedd3a36043605fd9bedf821e7ec5b4281a5c7ae2e4a1955f37aff8ba13519f functions_v1_events_mock: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsV1EventsMock.bin 0f0ba42e0cc33c7abc8b8fd4fdfce903748a169886dd5f16cfdd56e75bcf708d ocr2dr: ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.bin d9a794b33f47cc57563d216f7cf3a612309fc3062356a27e30005cf1d59e449d ocr2dr_client: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.bin 84aa63f9dbc5c7eac240db699b09e613ca4c6cd56dab10bdc25b02461b717e21 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 ec655980abf..c376213ed13 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 @@ -192,11 +192,13 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, var handleOracleFulfillmentSelector [4]byte copy(handleOracleFulfillmentSelector[:], handleOracleFulfillmentSelectorSlice[:4]) functionsRouterConfig := functions_router.FunctionsRouterConfig{ - MaxConsumersPerSubscription: uint16(100), - AdminFee: big.NewInt(0), - HandleOracleFulfillmentSelector: handleOracleFulfillmentSelector, - MaxCallbackGasLimits: []uint32{300_000, 500_000, 1_000_000}, - GasForCallExactCheck: 5000, + MaxConsumersPerSubscription: uint16(100), + AdminFee: big.NewInt(0), + HandleOracleFulfillmentSelector: handleOracleFulfillmentSelector, + MaxCallbackGasLimits: []uint32{300_000, 500_000, 1_000_000}, + GasForCallExactCheck: 5000, + SubscriptionDepositMinimumRequests: 10, + SubscriptionDepositJuels: big.NewInt(9 * 1e18), // 9 LINK } routerAddress, _, routerContract, err := functions_router.DeployFunctionsRouter(owner, b, linkAddr, functionsRouterConfig) require.NoError(t, err) From dc6e52b48a3025411d0b209a4430e1b6f4748fc3 Mon Sep 17 00:00:00 2001 From: ferglor <19188060+ferglor@users.noreply.github.com> Date: Fri, 8 Sep 2023 23:13:44 +0100 Subject: [PATCH 76/88] Batch insert records into the upkeep state store (#10488) * Use a batch insert * No longer insert records, store them for bulk insert, fail tests * Synchronous tick inserts * Insert on a tick * Data race * Test flake with inserts not completing * Wait for writes * Comment flake * Comment flake * Fix flake * Clean up tests * Extract emoty db test * Rename orm function to BatchInsertRecords * Remove the errCh * Add jitter to the ticker, remove it from the other * Re run CI * Comment flake * Side step flake --- .../ocr2keeper/evm21/upkeepstate/orm.go | 38 +++- .../ocr2keeper/evm21/upkeepstate/orm_test.go | 18 +- .../ocr2keeper/evm21/upkeepstate/store.go | 72 +++++-- .../evm21/upkeepstate/store_test.go | 185 ++++++++++++++---- 4 files changed, 245 insertions(+), 68 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm.go index 94a16f23dfe..d441b71819e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm.go @@ -34,16 +34,40 @@ func NewORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) * } } -// InsertUpkeepState is idempotent and sets upkeep state values in db -func (o *orm) InsertUpkeepState(state persistedStateRecord, qopts ...pg.QOpt) error { +// BatchInsertRecords is idempotent and sets upkeep state values in db +func (o *orm) BatchInsertRecords(state []persistedStateRecord, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) - query := `INSERT INTO evm_upkeep_states (evm_chain_id, work_id, completion_state, block_number, inserted_at, upkeep_id, ineligibility_reason) - VALUES ($1::NUMERIC, $2, $3, $4, $5, $6::NUMERIC, $7) - ON CONFLICT (evm_chain_id, work_id) - DO NOTHING` + if len(state) == 0 { + return nil + } + + type row struct { + EvmChainId *utils.Big + WorkId string + CompletionState uint8 + BlockNumber int64 + InsertedAt time.Time + UpkeepId *utils.Big + IneligibilityReason uint8 + } + + var rows []row + for _, record := range state { + rows = append(rows, row{ + EvmChainId: o.chainID, + WorkId: record.WorkID, + CompletionState: record.CompletionState, + BlockNumber: record.BlockNumber, + InsertedAt: record.InsertedAt, + UpkeepId: record.UpkeepID, + IneligibilityReason: record.IneligibilityReason, + }) + } - return q.ExecQ(query, o.chainID, state.WorkID, state.CompletionState, state.BlockNumber, state.InsertedAt, state.UpkeepID, state.IneligibilityReason) + return q.ExecQNamed(`INSERT INTO evm_upkeep_states +(evm_chain_id, work_id, completion_state, block_number, inserted_at, upkeep_id, ineligibility_reason) VALUES +(:evm_chain_id, :work_id, :completion_state, :block_number, :inserted_at, :upkeep_id, :ineligibility_reason) ON CONFLICT (evm_chain_id, work_id) DO NOTHING`, rows) } // SelectStatesByWorkIDs searches the data store for stored states for the diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm_test.go index c816627e92c..54ca7285dd0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm_test.go @@ -21,16 +21,18 @@ func TestInsertSelectDelete(t *testing.T) { db := pgtest.NewSqlxDB(t) orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) - inserted := persistedStateRecord{ - UpkeepID: utils.NewBig(big.NewInt(2)), - WorkID: "0x1", - CompletionState: 100, - BlockNumber: 2, - IneligibilityReason: 2, - InsertedAt: time.Now(), + inserted := []persistedStateRecord{ + { + UpkeepID: utils.NewBig(big.NewInt(2)), + WorkID: "0x1", + CompletionState: 100, + BlockNumber: 2, + IneligibilityReason: 2, + InsertedAt: time.Now(), + }, } - err := orm.InsertUpkeepState(inserted) + err := orm.BatchInsertRecords(inserted) require.NoError(t, err, "no error expected from insert") diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go index 3b37b58d03d..ce1b50de229 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go @@ -21,11 +21,13 @@ const ( // CacheExpiration is the amount of time that we keep a record in the cache. CacheExpiration = 24 * time.Hour // GCInterval is the amount of time between cache cleanups. - GCInterval = 2 * time.Hour + GCInterval = 2 * time.Hour + flushCadence = 30 * time.Second + concurrentBatchCalls = 10 ) type ORM interface { - InsertUpkeepState(persistedStateRecord, ...pg.QOpt) error + BatchInsertRecords([]persistedStateRecord, ...pg.QOpt) error SelectStatesByWorkIDs([]string, ...pg.QOpt) ([]persistedStateRecord, error) DeleteExpired(time.Time, ...pg.QOpt) error } @@ -39,7 +41,9 @@ type UpkeepStateStore interface { } var ( - _ UpkeepStateStore = &upkeepStateStore{} + _ UpkeepStateStore = &upkeepStateStore{} + newTickerFn = time.NewTicker + batchSize = 1000 ) // upkeepStateRecord is a record that we save in a local cache. @@ -66,6 +70,10 @@ type upkeepStateStore struct { mu sync.RWMutex cache map[string]*upkeepStateRecord + pendingRecords []persistedStateRecord + sem chan struct{} + batchSize int + // service values cancel context.CancelFunc } @@ -73,12 +81,15 @@ type upkeepStateStore struct { // NewUpkeepStateStore creates a new state store func NewUpkeepStateStore(orm ORM, lggr logger.Logger, scanner PerformedLogsScanner) *upkeepStateStore { return &upkeepStateStore{ - orm: orm, - lggr: lggr.Named("UpkeepStateStore"), - cache: map[string]*upkeepStateRecord{}, - scanner: scanner, - retention: CacheExpiration, - cleanCadence: GCInterval, + orm: orm, + lggr: lggr.Named("UpkeepStateStore"), + cache: map[string]*upkeepStateRecord{}, + scanner: scanner, + retention: CacheExpiration, + cleanCadence: GCInterval, + pendingRecords: []persistedStateRecord{}, + sem: make(chan struct{}, concurrentBatchCalls), + batchSize: batchSize, } } @@ -108,9 +119,12 @@ func (u *upkeepStateStore) Start(pctx context.Context) error { { go func(ctx context.Context) { - ticker := time.NewTicker(utils.WithJitter(u.cleanCadence)) + ticker := time.NewTicker(u.cleanCadence) defer ticker.Stop() + flushTicker := newTickerFn(utils.WithJitter(flushCadence)) + defer flushTicker.Stop() + for { select { case <-ticker.C: @@ -119,8 +133,11 @@ func (u *upkeepStateStore) Start(pctx context.Context) error { } ticker.Reset(utils.WithJitter(u.cleanCadence)) + case <-flushTicker.C: + u.flush(ctx) case <-ctx.Done(): - + u.flush(ctx) + return } } }(ctx) @@ -129,6 +146,33 @@ func (u *upkeepStateStore) Start(pctx context.Context) error { return nil } +func (u *upkeepStateStore) flush(ctx context.Context) { + cloneRecords := make([]persistedStateRecord, len(u.pendingRecords)) + + u.mu.Lock() + copy(cloneRecords, u.pendingRecords) + u.pendingRecords = []persistedStateRecord{} + u.mu.Unlock() + + for i := 0; i < len(cloneRecords); i += u.batchSize { + end := i + u.batchSize + if end > len(cloneRecords) { + end = len(cloneRecords) + } + + batch := cloneRecords[i:end] + + u.sem <- struct{}{} + + go func() { + if err := u.orm.BatchInsertRecords(batch, pg.WithParentCtx(ctx)); err != nil { + u.lggr.Errorw("error inserting records", "err", err) + } + <-u.sem + }() + } +} + // Close stops the service of pruning stale data; implements io.Closer func (u *upkeepStateStore) Close() error { u.mu.Lock() @@ -200,13 +244,15 @@ func (u *upkeepStateStore) upsertStateRecord(ctx context.Context, workID string, u.cache[workID] = record - return u.orm.InsertUpkeepState(persistedStateRecord{ + u.pendingRecords = append(u.pendingRecords, persistedStateRecord{ UpkeepID: utils.NewBig(upkeepID), WorkID: record.workID, CompletionState: uint8(record.state), IneligibilityReason: reason, InsertedAt: record.addedAt, - }, pg.WithParentCtx(ctx)) + }) + + return nil } // fetchPerformed fetches all performed logs from the scanner to populate the cache. diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go index fd2e6464239..9e7ba81e5eb 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go @@ -220,29 +220,23 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) { } tests := []struct { - name string - queryIDs []string - storedValues []storedValue - expected []ocr2keepers.UpkeepState + name string + flushSize int + expectedWrites int + queryIDs []string + storedValues []storedValue + expected []ocr2keepers.UpkeepState }{ { - name: "querying non-stored workIDs on empty db returns unknown state results", - queryIDs: []string{"0x1", "0x2", "0x3", "0x4"}, - expected: []ocr2keepers.UpkeepState{ - ocr2keepers.UnknownState, - ocr2keepers.UnknownState, - ocr2keepers.UnknownState, - ocr2keepers.UnknownState, - }, - }, - { - name: "querying non-stored workIDs on db with values returns unknown state results", - queryIDs: []string{"0x1", "0x2", "0x3", "0x4"}, + name: "querying non-stored workIDs on db with values returns unknown state results", + queryIDs: []string{"0x1", "0x2", "0x3", "0x4"}, + flushSize: 10, + expectedWrites: 1, storedValues: []storedValue{ - {result: makeTestResult(1, "0x11", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(2, "0x22", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(3, "0x33", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(4, "0x44", false, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(1, "0x11", false, 1), state: ocr2keepers.Performed}, + {result: makeTestResult(2, "0x22", false, 1), state: ocr2keepers.Performed}, + {result: makeTestResult(3, "0x33", false, 1), state: ocr2keepers.Performed}, + {result: makeTestResult(4, "0x44", false, 1), state: ocr2keepers.Performed}, }, expected: []ocr2keepers.UpkeepState{ ocr2keepers.UnknownState, @@ -252,13 +246,15 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) { }, }, { - name: "querying workIDs with non-stored values returns valid results", - queryIDs: []string{"0x1", "0x2", "0x3", "0x4"}, + name: "storing eligible values is a noop", + queryIDs: []string{"0x1", "0x2", "0x3", "0x4"}, + flushSize: 4, + expectedWrites: 1, storedValues: []storedValue{ - {result: makeTestResult(5, "0x1", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(6, "0x2", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(7, "0x3", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(8, "0x44", false, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(9, "0x1", false, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(10, "0x2", false, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(11, "0x3", false, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(12, "0x4", true, 1), state: ocr2keepers.Performed}, // gets inserted }, expected: []ocr2keepers.UpkeepState{ ocr2keepers.Ineligible, @@ -268,31 +264,43 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) { }, }, { - name: "storing eligible values is a noop", - queryIDs: []string{"0x1", "0x2", "0x3", "0x4"}, + name: "provided state on setupkeepstate is currently ignored for eligible check results", + queryIDs: []string{"0x1", "0x2"}, + flushSize: 1, + expectedWrites: 1, storedValues: []storedValue{ - {result: makeTestResult(9, "0x1", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(10, "0x2", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(11, "0x3", false, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(12, "0x4", true, 1), state: ocr2keepers.Performed}, + {result: makeTestResult(13, "0x1", true, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(14, "0x2", false, 1), state: ocr2keepers.Performed}, // gets inserted }, expected: []ocr2keepers.UpkeepState{ - ocr2keepers.Ineligible, - ocr2keepers.Ineligible, - ocr2keepers.Ineligible, ocr2keepers.UnknownState, + ocr2keepers.Ineligible, }, }, { - name: "provided state on setupkeepstate is currently ignored for eligible check results", - queryIDs: []string{"0x1", "0x2"}, + name: "provided state outside the flush batch isn't registered in the db", + queryIDs: []string{"0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8"}, + flushSize: 3, + expectedWrites: 2, storedValues: []storedValue{ {result: makeTestResult(13, "0x1", true, 1), state: ocr2keepers.Ineligible}, - {result: makeTestResult(14, "0x2", false, 1), state: ocr2keepers.Performed}, + {result: makeTestResult(14, "0x2", false, 1), state: ocr2keepers.Performed}, // gets inserted + {result: makeTestResult(15, "0x3", true, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(16, "0x4", false, 1), state: ocr2keepers.Performed}, // gets inserted + {result: makeTestResult(17, "0x5", true, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(18, "0x6", false, 1), state: ocr2keepers.Performed}, // gets inserted + {result: makeTestResult(19, "0x7", true, 1), state: ocr2keepers.Ineligible}, + {result: makeTestResult(20, "0x8", false, 1), state: ocr2keepers.Performed}, // gets inserted }, expected: []ocr2keepers.UpkeepState{ ocr2keepers.UnknownState, ocr2keepers.Ineligible, + ocr2keepers.UnknownState, + ocr2keepers.Ineligible, + ocr2keepers.UnknownState, + ocr2keepers.Ineligible, + ocr2keepers.UnknownState, + ocr2keepers.Ineligible, }, }, } @@ -301,13 +309,45 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) { t.Run(test.name, func(t *testing.T) { ctx := testutils.Context(t) + tickerCh := make(chan time.Time) + oldNewTickerFn := newTickerFn + oldFlushSize := batchSize + defer func() { + }() + newTickerFn = func(d time.Duration) *time.Ticker { + return &time.Ticker{ + C: tickerCh, + } + } + batchSize = test.flushSize + defer func() { + newTickerFn = oldNewTickerFn + batchSize = oldFlushSize + }() + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.ErrorLevel) chainID := testutils.FixtureChainID db := pgtest.NewSqlxDB(t) - orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + realORM := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + insertFinished := make(chan struct{}, 1) + orm := &wrappedORM{ + BatchInsertRecordsFn: func(records []persistedStateRecord, opt ...pg.QOpt) error { + err := realORM.BatchInsertRecords(records, opt...) + insertFinished <- struct{}{} + return err + }, + SelectStatesByWorkIDsFn: func(strings []string, opt ...pg.QOpt) ([]persistedStateRecord, error) { + return realORM.SelectStatesByWorkIDs(strings, opt...) + }, + DeleteExpiredFn: func(t time.Time, opt ...pg.QOpt) error { + return realORM.DeleteExpired(t, opt...) + }, + } scanner := &mockScanner{} store := NewUpkeepStateStore(orm, lggr, scanner) + require.NoError(t, store.Start(ctx)) + t.Cleanup(func() { t.Log("cleaning up database") @@ -320,6 +360,13 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) { require.NoError(t, store.SetUpkeepState(context.Background(), insert.result, insert.state), "storing states should not produce an error") } + tickerCh <- time.Now() + + // if this test inserts data, wait for the insert to complete before proceeding + for i := 0; i < test.expectedWrites; i++ { + <-insertFinished + } + // empty the cache before doing selects to force a db lookup store.cache = make(map[string]*upkeepStateRecord) @@ -332,10 +379,50 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) { observedLogs.TakeAll() require.Equal(t, 0, observedLogs.Len()) + + require.NoError(t, store.Close()) }) } } +func TestUpkeepStateStore_emptyDB(t *testing.T) { + t.Run("querying non-stored workIDs on empty db returns unknown state results", func(t *testing.T) { + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.ErrorLevel) + chainID := testutils.FixtureChainID + db := pgtest.NewSqlxDB(t) + realORM := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + insertFinished := make(chan struct{}, 1) + orm := &wrappedORM{ + BatchInsertRecordsFn: func(records []persistedStateRecord, opt ...pg.QOpt) error { + err := realORM.BatchInsertRecords(records, opt...) + insertFinished <- struct{}{} + return err + }, + SelectStatesByWorkIDsFn: func(strings []string, opt ...pg.QOpt) ([]persistedStateRecord, error) { + return realORM.SelectStatesByWorkIDs(strings, opt...) + }, + DeleteExpiredFn: func(t time.Time, opt ...pg.QOpt) error { + return realORM.DeleteExpired(t, opt...) + }, + } + scanner := &mockScanner{} + store := NewUpkeepStateStore(orm, lggr, scanner) + + states, err := store.SelectByWorkIDs(context.Background(), []string{"0x1", "0x2", "0x3", "0x4"}...) + assert.NoError(t, err) + assert.Equal(t, []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + ocr2keepers.UnknownState, + ocr2keepers.UnknownState, + ocr2keepers.UnknownState, + }, states) + + observedLogs.TakeAll() + + require.Equal(t, 0, observedLogs.Len()) + }) +} + func TestUpkeepStateStore_Upsert(t *testing.T) { db := pgtest.NewSqlxDB(t) ctx := testutils.Context(t) @@ -475,7 +562,7 @@ func (_m *mockORM) setErr(err error) { _m.err = err } -func (_m *mockORM) InsertUpkeepState(state persistedStateRecord, _ ...pg.QOpt) error { +func (_m *mockORM) BatchInsertRecords(state []persistedStateRecord, _ ...pg.QOpt) error { return nil } @@ -498,3 +585,21 @@ func (_m *mockORM) DeleteExpired(tm time.Time, _ ...pg.QOpt) error { return _m.err } + +type wrappedORM struct { + BatchInsertRecordsFn func([]persistedStateRecord, ...pg.QOpt) error + SelectStatesByWorkIDsFn func([]string, ...pg.QOpt) ([]persistedStateRecord, error) + DeleteExpiredFn func(time.Time, ...pg.QOpt) error +} + +func (o *wrappedORM) BatchInsertRecords(r []persistedStateRecord, q ...pg.QOpt) error { + return o.BatchInsertRecordsFn(r, q...) +} + +func (o *wrappedORM) SelectStatesByWorkIDs(ids []string, q ...pg.QOpt) ([]persistedStateRecord, error) { + return o.SelectStatesByWorkIDsFn(ids, q...) +} + +func (o *wrappedORM) DeleteExpired(t time.Time, q ...pg.QOpt) error { + return o.DeleteExpiredFn(t, q...) +} From 5dbc5ddeddc57fec5ac34e846a4883e1e8c77aa3 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Fri, 8 Sep 2023 15:28:19 -0700 Subject: [PATCH 77/88] move networks to CTF (#10434) * move networks to CTF * bump ctf * go.sum * go.mod * update version again * update go mod * update go.sum * updated develop --- integration-tests/benchmark/keeper_test.go | 3 +- .../chaos/automation_chaos_test.go | 3 +- integration-tests/chaos/ocr2vrf_chaos_test.go | 3 +- integration-tests/chaos/ocr_chaos_test.go | 3 +- .../docker/test_env/test_env_builder.go | 3 +- integration-tests/go.mod | 4 +- integration-tests/go.sum | 8 +- .../load/functions/gateway_test.go | 6 +- integration-tests/load/functions/setup.go | 16 +- integration-tests/networks/known_networks.go | 598 ------------------ integration-tests/performance/cron_test.go | 3 +- .../performance/directrequest_test.go | 3 +- integration-tests/performance/flux_test.go | 3 +- integration-tests/performance/keeper_test.go | 3 +- integration-tests/performance/ocr_test.go | 3 +- integration-tests/performance/vrf_test.go | 3 +- .../reorg/automation_reorg_test.go | 3 +- integration-tests/reorg/reorg_test.go | 5 +- integration-tests/runner_helpers.go | 4 +- integration-tests/smoke/automation_test.go | 4 +- integration-tests/smoke/ocr2_test.go | 3 +- integration-tests/smoke/ocr2vrf_test.go | 3 +- integration-tests/testsetups/ocr.go | 3 +- 23 files changed, 57 insertions(+), 633 deletions(-) delete mode 100644 integration-tests/networks/known_networks.go diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index 6ce0fb7138f..fbabfab78cc 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -20,11 +20,12 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index 0da3271785e..bb7fe1b8f00 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -20,11 +20,12 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - "github.com/smartcontractkit/chainlink/integration-tests/networks" ) var ( diff --git a/integration-tests/chaos/ocr2vrf_chaos_test.go b/integration-tests/chaos/ocr2vrf_chaos_test.go index 7d10107ba56..91c9084d408 100644 --- a/integration-tests/chaos/ocr2vrf_chaos_test.go +++ b/integration-tests/chaos/ocr2vrf_chaos_test.go @@ -18,13 +18,14 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions/ocr2vrf_constants" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" ) func TestOCR2VRFChaos(t *testing.T) { diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index 58b4d5bea65..1e5b8451454 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -22,11 +22,12 @@ import ( ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" ) var ( diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index 27f98b36139..7726c115fff 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -12,8 +12,9 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/logwatch" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" ) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 553b73e9473..6002149a561 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -20,7 +20,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-env v0.36.0 - github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2 + github.com/smartcontractkit/chainlink-testing-framework v1.16.5-0.20230908202859-e75102cf5f40 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 github.com/smartcontractkit/ocr2keepers v0.7.22 @@ -231,7 +231,7 @@ require ( github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.2 // indirect + github.com/holiman/uint256 v1.2.3 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/imdario/mergo v0.3.16 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e11b633b636..a741ba40492 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1395,8 +1395,8 @@ github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTx github.com/hetznercloud/hcloud-go v1.41.0 h1:KJGFRRc68QiVu4PrEP5BmCQVveCP2CM26UGQUKGpIUs= 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.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= -github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= +github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= 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= @@ -2258,8 +2258,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97ac github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918/go.mod h1:/yp/sqD8Iz5GU5fcercjrw0ivJF7HDcupYg+Gjr7EPg= -github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2 h1:llbIpJD17IXj0TPwE1r/bgB3X7Gkk9LKsxsXkTBmGe0= -github.com/smartcontractkit/chainlink-testing-framework v1.16.3-0.20230901233155-c2c6e9c075c2/go.mod h1:xtLIwNaVw/4zWSMnA7j8u1t9tKh0OykvIsYI4xZT3B4= +github.com/smartcontractkit/chainlink-testing-framework v1.16.5-0.20230908202859-e75102cf5f40 h1:FWVrA9QiLjez+XmWJ9ZEHf8RgDVCA6NmAySN3bA/MXQ= +github.com/smartcontractkit/chainlink-testing-framework v1.16.5-0.20230908202859-e75102cf5f40/go.mod h1:Ry6fRPr8TwrIsYVNEF1pguAgzE3QW1s54tbLWnFtfI4= github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI= github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= diff --git a/integration-tests/load/functions/gateway_test.go b/integration-tests/load/functions/gateway_test.go index 946afdd711a..c8e63f92f2b 100644 --- a/integration-tests/load/functions/gateway_test.go +++ b/integration-tests/load/functions/gateway_test.go @@ -1,10 +1,12 @@ package loadfunctions import ( - "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + "testing" + "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" - "testing" + + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" ) func TestGatewayLoad(t *testing.T) { diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go index f30772c198c..60986595b9f 100644 --- a/integration-tests/load/functions/setup.go +++ b/integration-tests/load/functions/setup.go @@ -2,20 +2,22 @@ package loadfunctions import ( "crypto/ecdsa" + "math/big" + mrand "math/rand" + "os" + "strconv" + "time" + "github.com/ethereum/go-ethereum/crypto" "github.com/go-resty/resty/v2" "github.com/pkg/errors" "github.com/rs/zerolog/log" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils" - "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy" - "math/big" - mrand "math/rand" - "os" - "strconv" - "time" ) type FunctionsTest struct { diff --git a/integration-tests/networks/known_networks.go b/integration-tests/networks/known_networks.go deleted file mode 100644 index 4d12d6b5b60..00000000000 --- a/integration-tests/networks/known_networks.go +++ /dev/null @@ -1,598 +0,0 @@ -// Package networks holds all known network information for the tests -package networks - -import ( - "crypto/ecdsa" - "fmt" - "os" - "strings" - "time" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/utils" - - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/logging" -) - -// Pre-configured test networks and their connections -// Some networks with public RPC endpoints are already filled out, but make use of environment variables to use info like -// private RPC endpoints and private keys. -var ( - // To create replica of simulated EVM network, with different chain ids - AdditionalSimulatedChainIds = []int64{3337, 4337, 5337, 6337, 7337, 8337, 9337, 9338} - AdditionalSimulatedPvtKeys = []string{ - "5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a", - "7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6", - "47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a", - "8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba", - "92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e", - "4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356", - "dbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97", - "2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6", - } - // SelectedNetworks uses the SELECTED_NETWORKS env var to determine which network to run the test on. - // For use in tests that utilize multiple chains. For tests on one chain, see SelectedNetwork - // For CCIP use index 1 and 2 of SELECTED_NETWORKS to denote source and destination network respectively - SelectedNetworks []blockchain.EVMNetwork = determineSelectedNetworks() - // SelectedNetwork uses the first listed network in SELECTED_NETWORKS, for use in tests on only one chain - SelectedNetwork blockchain.EVMNetwork = SelectedNetworks[0] - - // SimulatedEVM represents a simulated network - SimulatedEVM blockchain.EVMNetwork = blockchain.SimulatedEVMNetwork - // generalEVM is a customizable network through environment variables - // This is getting little use, and causes some confusion. Can re-enable if people want it. - // generalEVM blockchain.EVMNetwork = blockchain.LoadNetworkFromEnvironment() - - // SimulatedevmNonDev1 represents a simulated network which can be used to deploy a non-dev geth node - SimulatedEVMNonDev1 = blockchain.EVMNetwork{ - Name: "source-chain", - Simulated: true, - ClientImplementation: blockchain.EthereumClientImplementation, - SupportsEIP1559: true, - ChainID: 1337, - PrivateKeys: []string{ - "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", - }, - URLs: []string{"ws://source-chain-ethereum-geth:8546"}, - HTTPURLs: []string{"http://source-chain-ethereum-geth:8544"}, - ChainlinkTransactionLimit: 500000, - Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 10000, - DefaultGasLimit: 6000000, - } - - // SimulatedEVM_NON_DEV_2 represents a simulated network with chain id 2337 which can be used to deploy a non-dev geth node - SimulatedEVMNonDev2 = blockchain.EVMNetwork{ - Name: "dest-chain", - Simulated: true, - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 2337, - PrivateKeys: []string{ - "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", - }, - URLs: []string{"ws://dest-chain-ethereum-geth:8546"}, - HTTPURLs: []string{"http://dest-chain-ethereum-geth:8544"}, - ChainlinkTransactionLimit: 500000, - Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 10000, - DefaultGasLimit: 6000000, - } - - SimulatedEVMNonDev = blockchain.EVMNetwork{ - Name: "geth", - Simulated: true, - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 1337, - PrivateKeys: []string{ - "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", - }, - URLs: []string{"ws://geth-ethereum-geth:8546"}, - HTTPURLs: []string{"http://geth-ethereum-geth:8544"}, - ChainlinkTransactionLimit: 500000, - Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 10000, - } - - EthereumMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Ethereum Mainnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 1, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: 5 * time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - FinalityTag: true, - DefaultGasLimit: 6000000, - } - - // sepoliaTestnet https://sepolia.dev/ - SepoliaTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Sepolia Testnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 11155111, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - FinalityTag: true, - DefaultGasLimit: 6000000, - } - - // goerliTestnet https://goerli.net/ - GoerliTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Goerli Testnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 5, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: 5 * time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - FinalityTag: true, - DefaultGasLimit: 6000000, - } - - KlaytnMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Klaytn Mainnet", - SupportsEIP1559: false, - ClientImplementation: blockchain.KlaytnClientImplementation, - ChainID: 8217, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - } - - // klaytnBaobab https://klaytn.foundation/ - KlaytnBaobab blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Klaytn Baobab", - SupportsEIP1559: false, - ClientImplementation: blockchain.KlaytnClientImplementation, - ChainID: 1001, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - } - - MetisAndromeda blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Metis Andromeda", - SupportsEIP1559: false, - ClientImplementation: blockchain.MetisClientImplementation, - ChainID: 1088, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - } - - // metisStardust https://www.metis.io/ - MetisStardust blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Metis Stardust", - SupportsEIP1559: false, - ClientImplementation: blockchain.MetisClientImplementation, - ChainID: 588, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - } - - ArbitrumMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Arbitrum Mainnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.ArbitrumClientImplementation, - ChainID: 42161, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, - MinimumConfirmations: 0, - GasEstimationBuffer: 0, - FinalityTag: true, - DefaultGasLimit: 100000000, - } - - // arbitrumGoerli https://developer.offchainlabs.com/docs/public_chains - ArbitrumGoerli blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Arbitrum Goerli", - SupportsEIP1559: true, - ClientImplementation: blockchain.ArbitrumClientImplementation, - ChainID: 421613, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 0, - GasEstimationBuffer: 0, - FinalityTag: true, - DefaultGasLimit: 100000000, - } - - OptimismMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Optimism Mainnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.OptimismClientImplementation, - ChainID: 10, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - FinalityTag: true, - DefaultGasLimit: 6000000, - } - - // optimismGoerli https://dev.optimism.io/kovan-to-goerli/ - OptimismGoerli blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Optimism Goerli", - SupportsEIP1559: true, - ClientImplementation: blockchain.OptimismClientImplementation, - ChainID: 420, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - FinalityTag: true, - DefaultGasLimit: 6000000, - } - - RSKMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "RSK Mainnet", - SupportsEIP1559: false, - ClientImplementation: blockchain.RSKClientImplementation, - ChainID: 30, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - } - - // rskTestnet https://www.rsk.co/ - RSKTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "RSK Testnet", - SupportsEIP1559: false, - ClientImplementation: blockchain.RSKClientImplementation, - ChainID: 31, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - } - - PolygonMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Polygon Mainnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.PolygonClientImplementation, - ChainID: 137, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - FinalityDepth: 550, - DefaultGasLimit: 6000000, - } - - // PolygonMumbai https://mumbai.polygonscan.com/ - PolygonMumbai blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Polygon Mumbai", - SupportsEIP1559: true, - ClientImplementation: blockchain.PolygonClientImplementation, - ChainID: 80001, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: 3 * time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 100000, - FinalityDepth: 550, - DefaultGasLimit: 8000000, - } - - AvalancheMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Avalanche Mainnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 43114, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - FinalityDepth: 35, - DefaultGasLimit: 6000000, - } - - AvalancheFuji = blockchain.EVMNetwork{ - Name: "Avalanche Fuji", - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 43113, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - FinalityDepth: 35, - DefaultGasLimit: 6000000, - } - - Quorum = blockchain.EVMNetwork{ - Name: "Quorum", - SupportsEIP1559: false, - ClientImplementation: blockchain.QuorumClientImplementation, - ChainID: 1337, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - } - - BaseGoerli blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Base Goerli", - SupportsEIP1559: true, - ClientImplementation: blockchain.OptimismClientImplementation, - ChainID: 84531, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 0, - GasEstimationBuffer: 0, - } - - CeloAlfajores = blockchain.EVMNetwork{ - Name: "Celo Alfajores", - SupportsEIP1559: false, - ClientImplementation: blockchain.CeloClientImplementation, - ChainID: 44787, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - } - - ScrollSepolia = blockchain.EVMNetwork{ - Name: "Scroll Sepolia", - ClientImplementation: blockchain.ScrollClientImplementation, - ChainID: 534351, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - } - - ScrollMainnet = blockchain.EVMNetwork{ - Name: "Scroll Mainnet", - ClientImplementation: blockchain.ScrollClientImplementation, - ChainID: 534352, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 0, - } - - CeloMainnet = blockchain.EVMNetwork{ - Name: "Celo", - ClientImplementation: blockchain.CeloClientImplementation, - ChainID: 42220, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 1, - GasEstimationBuffer: 1000, - } - - BaseMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "Base Mainnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.OptimismClientImplementation, - ChainID: 8453, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 0, - GasEstimationBuffer: 0, - } - - BSCTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "BSC Testnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.BSCClientImplementation, - ChainID: 97, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 3, - GasEstimationBuffer: 0, - } - - BSCMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ - Name: "BSC Mainnet", - SupportsEIP1559: true, - ClientImplementation: blockchain.BSCClientImplementation, - ChainID: 56, - Simulated: false, - ChainlinkTransactionLimit: 5000, - Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, - MinimumConfirmations: 3, - GasEstimationBuffer: 0, - } - - MappedNetworks = map[string]blockchain.EVMNetwork{ - "SIMULATED": SimulatedEVM, - "SIMULATED_1": SimulatedEVMNonDev1, - "SIMULATED_2": SimulatedEVMNonDev2, - "SIMULATED_NONDEV": SimulatedEVMNonDev, - // "GENERAL": generalEVM, // See above - "ETHEREUM_MAINNET": EthereumMainnet, - "GOERLI": GoerliTestnet, - "SEPOLIA": SepoliaTestnet, - "KLAYTN_MAINNET": KlaytnMainnet, - "KLAYTN_BAOBAB": KlaytnBaobab, - "METIS_ANDROMEDA": MetisAndromeda, - "METIS_STARDUST": MetisStardust, - "ARBITRUM_MAINNET": ArbitrumMainnet, - "ARBITRUM_GOERLI": ArbitrumGoerli, - "OPTIMISM_MAINNET": OptimismMainnet, - "OPTIMISM_GOERLI": OptimismGoerli, - "BASE_GOERLI": BaseGoerli, - "CELO_ALFAJORES": CeloAlfajores, - "CELO_MAINNET": CeloMainnet, - "RSK": RSKTestnet, - "MUMBAI": PolygonMumbai, - "POLYGON_MAINNET": PolygonMainnet, - "AVALANCHE_FUJI": AvalancheFuji, - "AVALANCHE_MAINNET": AvalancheMainnet, - "QUORUM": Quorum, - "SCROLL_SEPOLIA": ScrollSepolia, - "SCROLL_MAINNET": ScrollMainnet, - "BASE_MAINNET": BaseMainnet, - "BSC_TESTNET": BSCTestnet, - "BSC_MAINNET": BSCMainnet, - } -) - -// determineSelectedNetworks uses `SELECTED_NETWORKS` to determine which networks to run the tests on. -// Use DetermineSelectedNetwork for tests that only use one network -func determineSelectedNetworks() []blockchain.EVMNetwork { - logging.Init() - selectedNetworks := make([]blockchain.EVMNetwork, 0) - rawSelectedNetworks := strings.ToUpper(os.Getenv("SELECTED_NETWORKS")) - setNetworkNames := strings.Split(rawSelectedNetworks, ",") - - for _, setNetworkName := range setNetworkNames { - if chosenNetwork, valid := MappedNetworks[setNetworkName]; valid { - log.Info(). - Interface("SELECTED_NETWORKS", setNetworkNames). - Str("Network Name", chosenNetwork.Name). - Msg("Read network choice from 'SELECTED_NETWORKS'") - setURLs(setNetworkName, &chosenNetwork) - setKeys(setNetworkName, &chosenNetwork) - selectedNetworks = append(selectedNetworks, chosenNetwork) - } else { - validNetworks := make([]string, 0) - for validNetwork := range MappedNetworks { - validNetworks = append(validNetworks, validNetwork) - } - log.Fatal(). - Interface("SELECTED_NETWORKS", setNetworkNames). - Str("Valid Networks", strings.Join(validNetworks, ", ")). - Msg("SELECTED_NETWORKS value is invalid. Use a valid network(s).") - } - } - return selectedNetworks -} - -// setURLs sets a network URL(s) based on env vars -func setURLs(prefix string, network *blockchain.EVMNetwork) { - prefix = strings.Trim(prefix, "_") - prefix = strings.ToUpper(prefix) - - if strings.Contains(prefix, "SIMULATED") { // Use defaults for SIMULATED - return - } - - wsEnvVar := fmt.Sprintf("%s_URLS", prefix) - httpEnvVar := fmt.Sprintf("%s_HTTP_URLS", prefix) - wsEnvURLs, err := utils.GetEnv(wsEnvVar) - if err != nil { - log.Fatal().Err(err).Str("env var", wsEnvVar).Msg("Error getting env var") - } - httpEnvURLs, err := utils.GetEnv(httpEnvVar) - if err != nil { - log.Fatal().Err(err).Str("env var", httpEnvVar).Msg("Error getting env var") - } - if wsEnvURLs == "" { - evmUrls, err := utils.GetEnv("EVM_URLS") - if err != nil { - log.Fatal().Err(err).Str("env var", "EVM_URLS").Msg("Error getting env var") - } - evmhttpUrls, err := utils.GetEnv("EVM_HTTP_URLS") - if err != nil { - log.Fatal().Err(err).Str("env var", "EVM_HTTP_URLS").Msg("Error getting env var") - } - wsURLs := strings.Split(evmUrls, ",") - httpURLs := strings.Split(evmhttpUrls, ",") - log.Warn().Msgf("No '%s' env var defined, defaulting to 'EVM_URLS'", wsEnvVar) - network.URLs = wsURLs - network.HTTPURLs = httpURLs - return - } - - wsURLs := strings.Split(wsEnvURLs, ",") - httpURLs := strings.Split(httpEnvURLs, ",") - network.URLs = wsURLs - network.HTTPURLs = httpURLs - log.Info().Msg("Read network URLs") -} - -// setKeys sets a network's private key(s) based on env vars -func setKeys(prefix string, network *blockchain.EVMNetwork) { - prefix = strings.Trim(prefix, "_") - prefix = strings.ToUpper(prefix) - - if strings.Contains(prefix, "SIMULATED") { // Use defaults for SIMULATED - return - } - - envVar := fmt.Sprintf("%s_KEYS", prefix) - keysFromEnv, err := utils.GetEnv(envVar) - if err != nil { - log.Fatal().Err(err).Str("env var", envVar).Msg("Error getting env var") - } - if keysFromEnv == "" { - log.Warn().Msg(fmt.Sprintf("No '%s' env var defined, defaulting to 'EVM_KEYS'", envVar)) - keysFromEnv = os.Getenv("EVM_KEYS") - } - keys := strings.Split(keysFromEnv, ",") - for i, key := range keys { - keys[i] = strings.TrimPrefix(key, "0x") - } - network.PrivateKeys = keys - - // log public keys for debugging - publicKeys := []string{} - for _, key := range network.PrivateKeys { - publicKey, err := privateKeyToAddress(key) - if err != nil { - log.Fatal().Err(err).Msg("Error getting public key from private key") - } - publicKeys = append(publicKeys, publicKey) - } - log.Info().Interface("Funding Addresses", publicKeys).Msg("Read network Keys") -} - -func privateKeyToAddress(privateKeyString string) (string, error) { - privateKey, err := crypto.HexToECDSA(privateKeyString) - if err != nil { - return "", err - } - publicKey := privateKey.Public() - publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) - if !ok { - return "", fmt.Errorf("error casting private key to public ECDSA key") - } - return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil -} diff --git a/integration-tests/performance/cron_test.go b/integration-tests/performance/cron_test.go index 933014a1698..c66a1803564 100644 --- a/integration-tests/performance/cron_test.go +++ b/integration-tests/performance/cron_test.go @@ -22,9 +22,10 @@ import ( ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) diff --git a/integration-tests/performance/directrequest_test.go b/integration-tests/performance/directrequest_test.go index 47a16de1091..dca84ab09c3 100644 --- a/integration-tests/performance/directrequest_test.go +++ b/integration-tests/performance/directrequest_test.go @@ -20,10 +20,11 @@ import ( ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" "github.com/google/uuid" diff --git a/integration-tests/performance/flux_test.go b/integration-tests/performance/flux_test.go index ecacce90ca7..bc914c329b9 100644 --- a/integration-tests/performance/flux_test.go +++ b/integration-tests/performance/flux_test.go @@ -21,10 +21,11 @@ import ( ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) diff --git a/integration-tests/performance/keeper_test.go b/integration-tests/performance/keeper_test.go index 346f0897d47..384729dfab3 100644 --- a/integration-tests/performance/keeper_test.go +++ b/integration-tests/performance/keeper_test.go @@ -20,11 +20,12 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) diff --git a/integration-tests/performance/ocr_test.go b/integration-tests/performance/ocr_test.go index 25791161bc2..d056d58e30b 100644 --- a/integration-tests/performance/ocr_test.go +++ b/integration-tests/performance/ocr_test.go @@ -18,10 +18,11 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) diff --git a/integration-tests/performance/vrf_test.go b/integration-tests/performance/vrf_test.go index 2074eecaf78..59eb5e3980b 100644 --- a/integration-tests/performance/vrf_test.go +++ b/integration-tests/performance/vrf_test.go @@ -18,10 +18,11 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 4a75d92d5d1..f3d3ed9369f 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -19,11 +19,12 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/networks" ) var ( diff --git a/integration-tests/reorg/reorg_test.go b/integration-tests/reorg/reorg_test.go index d6ac5ce1cf1..c944b7a7539 100644 --- a/integration-tests/reorg/reorg_test.go +++ b/integration-tests/reorg/reorg_test.go @@ -1,6 +1,7 @@ package reorg import ( + "context" "fmt" "math/big" "os" @@ -23,13 +24,13 @@ import ( ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" - "context" "github.com/onsi/gomega" "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/networks" ) const ( diff --git a/integration-tests/runner_helpers.go b/integration-tests/runner_helpers.go index 17950064575..43268a703ac 100644 --- a/integration-tests/runner_helpers.go +++ b/integration-tests/runner_helpers.go @@ -12,12 +12,12 @@ import ( "strings" "time" - gh "github.com/cli/go-gh/v2" + "github.com/cli/go-gh/v2" "github.com/ethereum/go-ethereum/crypto" "github.com/manifoldco/promptui" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink-testing-framework/networks" ) func waitForWorkflowRun(branch, ghUser string) (string, error) { diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 368b833a683..67b9b0b2648 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -17,12 +17,14 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "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/docker/test_env" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils" cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 6588586c39d..adaaf21ba19 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -16,13 +16,14 @@ import ( "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + + "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" ) diff --git a/integration-tests/smoke/ocr2vrf_test.go b/integration-tests/smoke/ocr2vrf_test.go index 504750fdafb..50a21b81d8e 100644 --- a/integration-tests/smoke/ocr2vrf_test.go +++ b/integration-tests/smoke/ocr2vrf_test.go @@ -15,13 +15,14 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions/ocr2vrf_constants" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" ) func TestOCR2VRFRedeemModel(t *testing.T) { diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index 1c210af1174..07aa3b2c4e8 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -36,11 +36,12 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" ) From cc85898a58305219c4c7bcd1440ccfb86442bcb7 Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Sat, 9 Sep 2023 01:41:54 +0300 Subject: [PATCH 78/88] Thread control utility (#10560) * utility for managing group of goroutines * refactor context to StopChan * remove limits * leftovers * leftovers round #2 * lint --- core/utils/thread_control.go | 44 +++++++++++++++++++++++++++++++ core/utils/thread_control_test.go | 27 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 core/utils/thread_control.go create mode 100644 core/utils/thread_control_test.go diff --git a/core/utils/thread_control.go b/core/utils/thread_control.go new file mode 100644 index 00000000000..8f7fff42496 --- /dev/null +++ b/core/utils/thread_control.go @@ -0,0 +1,44 @@ +package utils + +import ( + "context" + "sync" +) + +var _ ThreadControl = &threadControl{} + +// ThreadControl is a helper for managing a group of goroutines. +type ThreadControl interface { + // Go starts a goroutine and tracks the lifetime of the goroutine. + Go(fn func(context.Context)) + // Close cancels the goroutines and waits for all of them to exit. + Close() +} + +func NewThreadControl() *threadControl { + tc := &threadControl{ + stop: make(chan struct{}), + } + + return tc +} + +type threadControl struct { + threadsWG sync.WaitGroup + stop StopChan +} + +func (tc *threadControl) Go(fn func(context.Context)) { + tc.threadsWG.Add(1) + go func() { + defer tc.threadsWG.Done() + ctx, cancel := tc.stop.NewCtx() + defer cancel() + fn(ctx) + }() +} + +func (tc *threadControl) Close() { + close(tc.stop) + tc.threadsWG.Wait() +} diff --git a/core/utils/thread_control_test.go b/core/utils/thread_control_test.go new file mode 100644 index 00000000000..9001ca7241c --- /dev/null +++ b/core/utils/thread_control_test.go @@ -0,0 +1,27 @@ +package utils + +import ( + "context" + "sync/atomic" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestThreadControl_Close(t *testing.T) { + n := 10 + tc := NewThreadControl() + + finished := atomic.Int32{} + + for i := 0; i < n; i++ { + tc.Go(func(ctx context.Context) { + <-ctx.Done() + finished.Add(1) + }) + } + + tc.Close() + + require.Equal(t, int32(n), finished.Load()) +} From d3dfc5c9d5a64fd1df86bf68f452baf06c66ef06 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Fri, 8 Sep 2023 19:10:44 -0400 Subject: [PATCH 79/88] (chore): Update Functions v1 single line comments to nat spec (#10567) --- .../functions/dev/1_0_0/FunctionsBilling.sol | 68 ++++---- .../functions/dev/1_0_0/FunctionsClient.sol | 26 +-- .../dev/1_0_0/FunctionsCoordinator.sol | 28 ++-- .../functions/dev/1_0_0/FunctionsRouter.sol | 42 ++--- .../dev/1_0_0/FunctionsSubscriptions.sol | 80 +++++----- .../src/v0.8/functions/dev/1_0_0/Routable.sol | 14 +- .../accessControl/TermsOfServiceAllowList.sol | 26 +-- .../interfaces/ITermsOfServiceAllowList.sol | 48 +++--- .../1_0_0/example/FunctionsClientExample.sol | 28 ++-- .../1_0_0/interfaces/IFunctionsBilling.sol | 42 ++--- .../dev/1_0_0/interfaces/IFunctionsClient.sol | 14 +- .../interfaces/IFunctionsCoordinator.sol | 38 ++--- .../dev/1_0_0/interfaces/IFunctionsRouter.sol | 112 ++++++------- .../interfaces/IFunctionsSubscriptions.sol | 150 +++++++++--------- .../interfaces/IOwnableFunctionsRouter.sol | 2 +- .../dev/1_0_0/libraries/FunctionsRequest.sol | 54 +++---- .../dev/1_0_0/libraries/FunctionsResponse.sol | 2 +- 17 files changed, 381 insertions(+), 393 deletions(-) diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol index 5518bad1513..c616f7355d2 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol @@ -10,11 +10,9 @@ import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; -/** - * @title Functions Billing contract - * @notice Contract that calculates payment from users to the nodes of the Decentralized Oracle Network (DON). - * @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. - */ +/// @title Functions Billing contract +/// @notice Contract that calculates payment from users to the nodes of the Decentralized Oracle Network (DON). +/// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. abstract contract FunctionsBilling is Routable, IFunctionsBilling { using FunctionsResponse for FunctionsResponse.RequestMeta; using FunctionsResponse for FunctionsResponse.Commitment; @@ -82,14 +80,14 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // | Configuration | // ================================================================ - // @notice Gets the Chainlink Coordinator's billing configuration - // @return config + /// @notice Gets the Chainlink Coordinator's billing configuration + /// @return config function getConfig() external view returns (Config memory) { return s_config; } - // @notice Sets the Chainlink Coordinator's billing configuration - // @param config - See the contents of the Config struct in IFunctionsBilling.Config for more information + /// @notice Sets the Chainlink Coordinator's billing configuration + /// @param config - See the contents of the Config struct in IFunctionsBilling.Config for more information function updateConfig(Config memory config) public { _onlyOwner(); @@ -101,17 +99,17 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // | Fee Calculation | // ================================================================ - // @inheritdoc IFunctionsBilling + /// @inheritdoc IFunctionsBilling function getDONFee(bytes memory /* requestData */) public view override returns (uint72) { return s_config.donFee; } - // @inheritdoc IFunctionsBilling + /// @inheritdoc IFunctionsBilling function getAdminFee() public view override returns (uint72) { return _getRouter().getAdminFee(); } - // @inheritdoc IFunctionsBilling + /// @inheritdoc IFunctionsBilling function getWeiPerUnitLink() public view returns (uint256) { Config memory config = s_config; (, int256 weiPerUnitLink, , uint256 timestamp, ) = s_linkToNativeFeed.latestRoundData(); @@ -135,7 +133,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // | Cost Estimation | // ================================================================ - // @inheritdoc IFunctionsBilling + /// @inheritdoc IFunctionsBilling function estimateCost( uint64 subscriptionId, bytes calldata data, @@ -152,7 +150,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return _calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee); } - // @notice Estimate the cost in Juels of LINK + /// @notice Estimate the cost in Juels of LINK // that will be charged to a subscription to fulfill a Functions request // Gas Price can be overestimated to account for flucuations between request and response time function _calculateCostEstimate( @@ -165,7 +163,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint256 gasPriceWithOverestimation = gasPriceWei + ((gasPriceWei * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000); - // @NOTE: Basis Points are 1/100th of 1%, divide by 10_000 to bring back to original units + /// @NOTE: Basis Points are 1/100th of 1%, divide by 10_000 to bring back to original units uint96 juelsPerGas = _getJuelsPerGas(gasPriceWithOverestimation); uint256 estimatedGasReimbursement = juelsPerGas * executionGas; @@ -178,12 +176,10 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // | Billing | // ================================================================ - // @notice Initiate the billing process for an Functions request - // @dev Only callable by the Functions Router - // @param data - Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - // @param requestDataVersion - Version number of the structure of the request data - // @param billing - Billing configuration for the request - // @return commitment - The parameters of the request that must be held consistent at response time + /// @notice Initiate the billing process for an Functions request + /// @dev Only callable by the Functions Router + /// @param request - Chainlink Functions request data, see FunctionsResponse.RequestMeta for the structure + /// @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) { @@ -233,8 +229,8 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return commitment; } - // @notice Generate a keccak hash request ID - // @dev uses the number of requests that the consumer of a subscription has sent as a nonce + /// @notice Generate a keccak hash request ID + /// @dev uses the number of requests that the consumer of a subscription has sent as a nonce function _computeRequestId( address don, address client, @@ -244,13 +240,13 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return keccak256(abi.encode(don, client, subscriptionId, nonce)); } - // @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription - // @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment - // @param response response data from DON consensus - // @param err error from DON consensus - // @return result fulfillment result - // @dev Only callable by a node that has been approved on the Coordinator - // @dev simulated offchain to determine if sufficient balance is present to fulfill the request + /// @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription + /// @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment + /// @param response response data from DON consensus + /// @param err error from DON consensus + /// @return result fulfillment result + /// @dev Only callable by a node that has been approved on the Coordinator + /// @dev simulated offchain to determine if sufficient balance is present to fulfill the request function _fulfillAndBill( bytes32 requestId, bytes memory response, @@ -305,9 +301,9 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // | Request Timeout | // ================================================================ - // @inheritdoc IFunctionsBilling - // @dev Only callable by the Router - // @dev Used by FunctionsRouter.sol during timeout of a request + /// @inheritdoc IFunctionsBilling + /// @dev Only callable by the Router + /// @dev Used by FunctionsRouter.sol during timeout of a request function deleteCommitment(bytes32 requestId) external override onlyRouter { // Delete commitment delete s_requestCommitments[requestId]; @@ -318,7 +314,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // | Fund withdrawal | // ================================================================ - // @inheritdoc IFunctionsBilling + /// @inheritdoc IFunctionsBilling function oracleWithdraw(address recipient, uint96 amount) external { _disperseFeePool(); @@ -331,8 +327,8 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(recipient, amount); } - // @inheritdoc IFunctionsBilling - // @dev Only callable by the Coordinator owner + /// @inheritdoc IFunctionsBilling + /// @dev Only callable by the Coordinator owner function oracleWithdrawAll() external { _onlyOwner(); _disperseFeePool(); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol index 41db3e98b29..ecbbbd928fe 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol @@ -6,8 +6,8 @@ import {IFunctionsClient} from "./interfaces/IFunctionsClient.sol"; import {FunctionsRequest} from "./libraries/FunctionsRequest.sol"; -// @title The Chainlink Functions client contract -// @notice Contract developers can inherit this contract in order to make Chainlink Functions requests +/// @title The Chainlink Functions client contract +/// @notice Contract developers can inherit this contract in order to make Chainlink Functions requests abstract contract FunctionsClient is IFunctionsClient { using FunctionsRequest for FunctionsRequest.Request; @@ -22,11 +22,11 @@ abstract contract FunctionsClient is IFunctionsClient { i_router = IFunctionsRouter(router); } - // @notice Sends a Chainlink Functions request - // @param data The CBOR encoded bytes data for a Functions request - // @param subscriptionId The subscription ID that will be charged to service the request - // @param callbackGasLimit the amount of gas that will be available for the fulfillment callback - // @return requestId The generated request ID for this request + /// @notice Sends a Chainlink Functions request + /// @param data The CBOR encoded bytes data for a Functions request + /// @param subscriptionId The subscription ID that will be charged to service the request + /// @param callbackGasLimit the amount of gas that will be available for the fulfillment callback + /// @return requestId The generated request ID for this request function _sendRequest( bytes memory data, uint64 subscriptionId, @@ -44,14 +44,14 @@ abstract contract FunctionsClient is IFunctionsClient { return requestId; } - // @notice User defined function to handle a response from the DON - // @param requestId The request ID, returned by sendRequest() - // @param response Aggregated response from the execution of the user's source code - // @param err Aggregated error from the execution of the user code or from the execution pipeline - // @dev Either response or error parameter will be set, but never both + /// @notice User defined function to handle a response from the DON + /// @param requestId The request ID, returned by sendRequest() + /// @param response Aggregated response from the execution of the user's source code + /// @param err Aggregated error from the execution of the user code or from the execution pipeline + /// @dev Either response or error parameter will be set, but never both function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal virtual; - // @inheritdoc IFunctionsClient + /// @inheritdoc IFunctionsClient function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external override { if (msg.sender != address(i_router)) { revert OnlyRouterCanFulfill(); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol index aa7b1d5c7e1..540b382d652 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol @@ -9,15 +9,15 @@ import {FunctionsBilling} from "./FunctionsBilling.sol"; import {OCR2Base} from "./ocr/OCR2Base.sol"; import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; -// @title Functions Coordinator contract -// @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with -// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. +/// @title Functions Coordinator contract +/// @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with +/// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilling { using FunctionsResponse for FunctionsResponse.RequestMeta; using FunctionsResponse for FunctionsResponse.Commitment; using FunctionsResponse for FunctionsResponse.FulfillResult; - // @inheritdoc ITypeAndVersion + /// @inheritdoc ITypeAndVersion string public constant override typeAndVersion = "Functions Coordinator v1.0.0"; event OracleRequest( @@ -47,7 +47,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli address linkToNativeFeed ) OCR2Base(true) FunctionsBilling(router, config, linkToNativeFeed) {} - // @inheritdoc IFunctionsCoordinator + /// @inheritdoc IFunctionsCoordinator function getThresholdPublicKey() external view override returns (bytes memory) { if (s_thresholdPublicKey.length == 0) { revert EmptyPublicKey(); @@ -55,7 +55,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_thresholdPublicKey; } - // @inheritdoc IFunctionsCoordinator + /// @inheritdoc IFunctionsCoordinator function setThresholdPublicKey(bytes calldata thresholdPublicKey) external override onlyOwner { if (thresholdPublicKey.length == 0) { revert EmptyPublicKey(); @@ -63,7 +63,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_thresholdPublicKey = thresholdPublicKey; } - // @inheritdoc IFunctionsCoordinator + /// @inheritdoc IFunctionsCoordinator function getDONPublicKey() external view override returns (bytes memory) { if (s_donPublicKey.length == 0) { revert EmptyPublicKey(); @@ -71,7 +71,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_donPublicKey; } - // @inheritdoc IFunctionsCoordinator + /// @inheritdoc IFunctionsCoordinator function setDONPublicKey(bytes calldata donPublicKey) external override onlyOwner { if (donPublicKey.length == 0) { revert EmptyPublicKey(); @@ -79,7 +79,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_donPublicKey = donPublicKey; } - // @dev check if node is in current transmitter list + /// @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 @@ -91,7 +91,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return false; } - // @inheritdoc IFunctionsCoordinator + /// @inheritdoc IFunctionsCoordinator function startRequest( FunctionsResponse.RequestMeta calldata request ) external override onlyRouter returns (FunctionsResponse.Commitment memory commitment) { @@ -113,19 +113,19 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return commitment; } - // DON fees are pooled together. If the OCR configuration is going to change, these need to be distributed. + /// @dev DON fees are pooled together. If the OCR configuration is going to change, these need to be distributed. function _beforeSetConfig(uint8 /* _f */, bytes memory /* _onchainConfig */) internal override { if (_getTransmitters().length > 0) { _disperseFeePool(); } } - // Used by FunctionsBilling.sol + /// @dev Used by FunctionsBilling.sol function _getTransmitters() internal view override returns (address[] memory) { return s_transmitters; } - // Report hook called within OCR2Base.sol + /// @dev Report hook called within OCR2Base.sol function _report( uint256 /*initialGas*/, address /*transmitter*/, @@ -171,7 +171,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli } } - // Used in FunctionsBilling.sol + /// @dev Used in FunctionsBilling.sol function _onlyOwner() internal view override { _validateOwnership(); } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol index 1d09b1e6739..41cd90341f3 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol @@ -137,20 +137,20 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // | Configuration | // ================================================================ - // @notice The identifier of the route to retrieve the address of the access control contract + /// @notice The identifier of the route to retrieve the address of the access control contract // The access control contract controls which accounts can manage subscriptions - // @return id - bytes32 id that can be passed to the "getContractById" of the Router + /// @return id - bytes32 id that can be passed to the "getContractById" of the Router function getConfig() external view returns (Config memory) { return s_config; } - // @notice The router configuration + /// @notice The router configuration function updateConfig(Config memory config) public onlyOwner { s_config = config; emit ConfigUpdated(config); } - // @inheritdoc IFunctionsRouter + /// @inheritdoc IFunctionsRouter function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) public view { uint8 callbackGasLimitsIndexSelector = uint8(getFlags(subscriptionId)[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); if (callbackGasLimitsIndexSelector >= s_config.maxCallbackGasLimits.length) { @@ -162,22 +162,22 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, } } - // @inheritdoc IFunctionsRouter + /// @inheritdoc IFunctionsRouter function getAdminFee() external view override returns (uint72) { return s_config.adminFee; } - // @inheritdoc IFunctionsRouter + /// @inheritdoc IFunctionsRouter function getAllowListId() external view override returns (bytes32) { return s_allowListId; } - // @inheritdoc IFunctionsRouter + /// @inheritdoc IFunctionsRouter function setAllowListId(bytes32 allowListId) external override onlyOwner { s_allowListId = allowListId; } - // Used within FunctionsSubscriptions.sol + /// @dev Used within FunctionsSubscriptions.sol function _getMaxConsumers() internal view override returns (uint16) { return s_config.maxConsumersPerSubscription; } @@ -191,7 +191,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // | Requests | // ================================================================ - // @inheritdoc IFunctionsRouter + /// @inheritdoc IFunctionsRouter function sendRequest( uint64 subscriptionId, bytes calldata data, @@ -203,7 +203,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, return _sendRequest(donId, coordinator, subscriptionId, data, dataVersion, callbackGasLimit); } - // @inheritdoc IFunctionsRouter + /// @inheritdoc IFunctionsRouter function sendRequestToProposed( uint64 subscriptionId, bytes calldata data, @@ -299,7 +299,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // | Responses | // ================================================================ - // @inheritdoc IFunctionsRouter + /// @inheritdoc IFunctionsRouter function fulfill( bytes memory response, bytes memory err, @@ -474,7 +474,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // | Route methods | // ================================================================ - // @inheritdoc IRouterBase + /// @inheritdoc IFunctionsRouter function getContractById(bytes32 id) public view override returns (address) { address currentImplementation = s_route[id]; if (currentImplementation == address(0)) { @@ -483,7 +483,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, return currentImplementation; } - // @inheritdoc IRouterBase + /// @inheritdoc IFunctionsRouter function getProposedContractById(bytes32 id) public view override returns (address) { // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH for (uint8 i = 0; i < s_proposedContractSet.ids.length; ++i) { @@ -498,12 +498,12 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // | Contract Proposal methods | // ================================================================ - // @inheritdoc IRouterBase + /// @inheritdoc IFunctionsRouter function getProposedContractSet() external view override returns (bytes32[] memory, address[] memory) { return (s_proposedContractSet.ids, s_proposedContractSet.to); } - // @inheritdoc IRouterBase + /// @inheritdoc IFunctionsRouter function proposeContractsUpdate( bytes32[] memory proposedContractSetIds, address[] memory proposedContractSetAddresses @@ -535,7 +535,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, s_proposedContractSet = ContractProposalSet({ids: proposedContractSetIds, to: proposedContractSetAddresses}); } - // @inheritdoc IRouterBase + /// @inheritdoc IFunctionsRouter function updateContracts() external override onlyOwner { // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH for (uint256 i = 0; i < s_proposedContractSet.ids.length; ++i) { @@ -553,17 +553,17 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // ================================================================ // Favoring internal functions over actual modifiers to reduce contract size - // Used within FunctionsSubscriptions.sol + /// @dev Used within FunctionsSubscriptions.sol function _whenNotPaused() internal view override { _requireNotPaused(); } - // Used within FunctionsSubscriptions.sol + /// @dev Used within FunctionsSubscriptions.sol function _onlyRouterOwner() internal view override { _validateOwnership(); } - // Used within FunctionsSubscriptions.sol + /// @dev Used within FunctionsSubscriptions.sol function _onlySenderThatAcceptedToS() internal view override { address currentImplementation = s_route[s_allowListId]; if (currentImplementation == address(0)) { @@ -575,12 +575,12 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, } } - // @inheritdoc IRouterBase + /// @inheritdoc IFunctionsRouter function pause() external override onlyOwner { _pause(); } - // @inheritdoc IRouterBase + /// @inheritdoc IFunctionsRouter function unpause() external override onlyOwner { _unpause(); } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol index cab8e2b0803..864225fd38c 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol @@ -13,9 +13,9 @@ import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/tok import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; -// @title Functions Subscriptions contract -// @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON). -// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. +/// @title Functions Subscriptions contract +/// @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON). +/// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Receiver { using SafeERC20 for IERC20; using FunctionsResponse for FunctionsResponse.Commitment; @@ -32,7 +32,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // sent tokens using transfer and so we may need to use recoverFunds. uint96 private s_totalLinkBalance; - // @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator. + /// @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator. mapping(address coordinator => uint96 balanceJuelsLink) private s_withdrawableTokens; // ================================================================ @@ -96,8 +96,8 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // | Request/Response | // ================================================================ - // @notice Sets a request as in-flight - // @dev Only callable within the Router + /// @notice Sets a request as in-flight + /// @dev Only callable within the Router function _markRequestInFlight(address client, uint64 subscriptionId, uint96 estimatedTotalCostJuels) internal { // Earmark subscription funds s_subscriptions[subscriptionId].blockedBalance += estimatedTotalCostJuels; @@ -106,8 +106,8 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece s_consumers[client][subscriptionId].initiatedRequests += 1; } - // @notice Moves funds from one subscription account to another. - // @dev Only callable by the Coordinator contract that is saved in the request commitment + /// @notice Moves funds from one subscription account to another. + /// @dev Only callable by the Coordinator contract that is saved in the request commitment function _pay( uint64 subscriptionId, uint96 estimatedTotalCostJuels, @@ -149,14 +149,14 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // | Owner methods | // ================================================================ - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function ownerCancelSubscription(uint64 subscriptionId) external override { _onlyRouterOwner(); _isExistingSubscription(subscriptionId); _cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner, false); } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function recoverFunds(address to) external override { _onlyRouterOwner(); uint256 externalBalance = i_linkToken.balanceOf(address(this)); @@ -173,7 +173,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // | Fund withdrawal | // ================================================================ - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function oracleWithdraw(address recipient, uint96 amount) external override { _whenNotPaused(); @@ -189,10 +189,10 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece i_linkToken.safeTransfer(recipient, amount); } - // @notice Owner withdraw LINK earned through admin fees - // @notice If amount is 0 the full balance will be withdrawn - // @param recipient where to send the funds - // @param amount amount to withdraw + /// @notice Owner withdraw LINK earned through admin fees + /// @notice If amount is 0 the full balance will be withdrawn + /// @param recipient where to send the funds + /// @param amount amount to withdraw function ownerWithdraw(address recipient, uint96 amount) external { _onlyRouterOwner(); if (amount == 0) { @@ -213,11 +213,11 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // ================================================================ // This function is to be invoked when using LINK.transferAndCall - // @dev Note to fund the subscription, use transferAndCall. For example - // @dev LINKTOKEN.transferAndCall( - // @dev address(ROUTER), - // @dev amount, - // @dev abi.encode(subscriptionId)); + /// @dev Note to fund the subscription, use transferAndCall. For example + /// @dev LINKTOKEN.transferAndCall( + /// @dev address(ROUTER), + /// @dev amount, + /// @dev abi.encode(subscriptionId)); function onTokenTransfer(address /* sender */, uint256 amount, bytes calldata data) external override { _whenNotPaused(); if (msg.sender != address(i_linkToken)) { @@ -242,17 +242,17 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // | Subscription management | // ================================================================ - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function getTotalBalance() external view override returns (uint96) { return s_totalLinkBalance; } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function getSubscriptionCount() external view override returns (uint64) { return s_currentSubscriptionId; } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function getSubscription(uint64 subscriptionId) public view override returns (Subscription memory) { _isExistingSubscription(subscriptionId); return s_subscriptions[subscriptionId]; @@ -279,26 +279,26 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece return subscriptions; } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function getConsumer(address client, uint64 subscriptionId) public view override returns (Consumer memory) { return s_consumers[client][subscriptionId]; } - // Used within this file & FunctionsRouter.sol + /// @dev Used within this file & FunctionsRouter.sol function _isExistingSubscription(uint64 subscriptionId) internal view { if (s_subscriptions[subscriptionId].owner == address(0)) { revert InvalidSubscription(); } } - // Used within FunctionsRouter.sol + /// @dev Used within FunctionsRouter.sol function _isAllowedConsumer(address client, uint64 subscriptionId) internal view { if (!s_consumers[client][subscriptionId].allowed) { revert InvalidConsumer(); } } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function createSubscription() external override returns (uint64 subscriptionId) { _whenNotPaused(); _onlySenderThatAcceptedToS(); @@ -318,7 +318,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece return subscriptionId; } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function createSubscriptionWithConsumer(address consumer) external override returns (uint64 subscriptionId) { _whenNotPaused(); _onlySenderThatAcceptedToS(); @@ -342,7 +342,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece return subscriptionId; } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external override { _whenNotPaused(); _onlySubscriptionOwner(subscriptionId); @@ -356,7 +356,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece emit SubscriptionOwnerTransferRequested(subscriptionId, msg.sender, newOwner); } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external override { _whenNotPaused(); _onlySenderThatAcceptedToS(); @@ -371,7 +371,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece emit SubscriptionOwnerTransferred(subscriptionId, previousOwner, msg.sender); } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function removeConsumer(uint64 subscriptionId, address consumer) external override { _whenNotPaused(); _onlySubscriptionOwner(subscriptionId); @@ -397,10 +397,10 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece emit SubscriptionConsumerRemoved(subscriptionId, consumer); } - // overriden in FunctionsRouter.sol + /// @dev Overriden in FunctionsRouter.sol function _getMaxConsumers() internal view virtual returns (uint16); - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function addConsumer(uint64 subscriptionId, address consumer) external override { _whenNotPaused(); _onlySubscriptionOwner(subscriptionId); @@ -471,7 +471,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece _cancelSubscriptionHelper(subscriptionId, to, true); } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function pendingRequestExists(uint64 subscriptionId) public view override returns (bool) { address[] memory consumers = s_subscriptions[subscriptionId].consumers; // NOTE: loop iterations are bounded by config.maxConsumers @@ -484,14 +484,14 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece return false; } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function setFlags(uint64 subscriptionId, bytes32 flags) external override { _onlyRouterOwner(); _isExistingSubscription(subscriptionId); s_subscriptions[subscriptionId].flags = flags; } - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function getFlags(uint64 subscriptionId) public view returns (bytes32) { return s_subscriptions[subscriptionId].flags; } @@ -500,7 +500,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece // | Request Timeout | // ================================================================ - // @inheritdoc IFunctionsSubscriptions + /// @inheritdoc IFunctionsSubscriptions function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external override { _whenNotPaused(); @@ -545,12 +545,12 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece } } - // Overriden in FunctionsRouter.sol + /// @dev Overriden in FunctionsRouter.sol function _onlySenderThatAcceptedToS() internal virtual; - // Overriden in FunctionsRouter.sol + /// @dev Overriden in FunctionsRouter.sol function _onlyRouterOwner() internal virtual; - // Overriden in FunctionsRouter.sol + /// @dev Overriden in FunctionsRouter.sol function _whenNotPaused() internal virtual; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol b/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol index 8c09eba5d79..b50b1e603f9 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.19; import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; import {IOwnableFunctionsRouter} from "./interfaces/IOwnableFunctionsRouter.sol"; -// @title This abstract should be inherited by contracts that will be used -// as the destinations to a route (id=>contract) on the Router. -// It provides a Router getter and modifiers +/// @title This abstract should be inherited by contracts that will be used +/// as the destinations to a route (id=>contract) on the Router. +/// It provides a Router getter and modifiers. abstract contract Routable is ITypeAndVersion { IOwnableFunctionsRouter private immutable i_router; @@ -14,7 +14,7 @@ abstract contract Routable is ITypeAndVersion { error OnlyCallableByRouter(); error OnlyCallableByRouterOwner(); - // @dev Initializes the contract. + /// @dev Initializes the contract. constructor(address router) { if (router == address(0)) { revert RouterMustBeSet(); @@ -22,12 +22,12 @@ abstract contract Routable is ITypeAndVersion { i_router = IOwnableFunctionsRouter(router); } - // @notice Return the Router + /// @notice Return the Router function _getRouter() internal view returns (IOwnableFunctionsRouter router) { return i_router; } - // @notice Reverts if called by anyone other than the router. + /// @notice Reverts if called by anyone other than the router. modifier onlyRouter() { if (msg.sender != address(i_router)) { revert OnlyCallableByRouter(); @@ -35,7 +35,7 @@ abstract contract Routable is ITypeAndVersion { _; } - // @notice Reverts if called by anyone other than the router owner. + /// @notice Reverts if called by anyone other than the router owner. modifier onlyRouterOwner() { if (msg.sender != i_router.owner()) { revert OnlyCallableByRouterOwner(); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol index 2ce107c9861..c4bd524b522 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol @@ -10,12 +10,12 @@ import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; import {Address} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Address.sol"; import {EnumerableSet} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; -// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service +/// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, ITypeAndVersion, ConfirmedOwner { using Address for address; using EnumerableSet for EnumerableSet.AddressSet; - // @inheritdoc ITypeAndVersion + /// @inheritdoc ITypeAndVersion string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.0.0"; EnumerableSet.AddressSet private s_allowedSenders; @@ -53,14 +53,14 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // | Configuration | // ================================================================ - // @notice Gets the contracts's configuration - // @return config + /// @notice Gets the contracts's configuration + /// @return config function getConfig() external view returns (Config memory) { return s_config; } - // @notice Sets the contracts's configuration - // @param config - See the contents of the TermsOfServiceAllowList.Config struct for more information + /// @notice Sets the contracts's configuration + /// @param config - See the contents of the TermsOfServiceAllowList.Config struct for more information function updateConfig(Config memory config) public onlyOwner { s_config = config; emit ConfigUpdated(config); @@ -70,12 +70,12 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // | Allow methods | // ================================================================ - // @inheritdoc ITermsOfServiceAllowList + /// @inheritdoc ITermsOfServiceAllowList function getMessage(address acceptor, address recipient) public pure override returns (bytes32) { return keccak256(abi.encodePacked(acceptor, recipient)); } - // @inheritdoc ITermsOfServiceAllowList + /// @inheritdoc ITermsOfServiceAllowList function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external override { if (s_blockedSenders[recipient]) { revert RecipientIsBlocked(); @@ -102,12 +102,12 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, emit AddedAccess(recipient); } - // @inheritdoc ITermsOfServiceAllowList + /// @inheritdoc ITermsOfServiceAllowList function getAllAllowedSenders() external view override returns (address[] memory) { return s_allowedSenders.values(); } - // @inheritdoc IAccessController + /// @inheritdoc IAccessController function hasAccess(address user, bytes calldata /* data */) external view override returns (bool) { if (!s_config.enabled) { return true; @@ -119,7 +119,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // | Block methods | // ================================================================ - // @inheritdoc ITermsOfServiceAllowList + /// @inheritdoc ITermsOfServiceAllowList function isBlockedSender(address sender) external view override returns (bool) { if (!s_config.enabled) { return false; @@ -127,14 +127,14 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, return s_blockedSenders[sender]; } - // @inheritdoc ITermsOfServiceAllowList + /// @inheritdoc ITermsOfServiceAllowList function blockSender(address sender) external override onlyOwner { s_allowedSenders.remove(sender); s_blockedSenders[sender] = true; emit BlockedAccess(sender); } - // @inheritdoc ITermsOfServiceAllowList + /// @inheritdoc ITermsOfServiceAllowList function unblockSender(address sender) external override onlyOwner { s_blockedSenders[sender] = false; emit UnblockedAccess(sender); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol index b83375ee01f..af4daa18bc3 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol @@ -1,40 +1,40 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service +/// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service interface ITermsOfServiceAllowList { - // @notice Return the message data for the proof given to accept the Terms of Service - // @param acceptor - The wallet address that has accepted the Terms of Service on the UI - // @param recipient - The recipient address that the acceptor is taking responsibility for - // @return Hash of the message data + /// @notice Return the message data for the proof given to accept the Terms of Service + /// @param acceptor - The wallet address that has accepted the Terms of Service on the UI + /// @param recipient - The recipient address that the acceptor is taking responsibility for + /// @return Hash of the message data function getMessage(address acceptor, address recipient) external pure returns (bytes32); - // @notice Check if the address is blocked for usage - // @param sender The transaction sender's address - // @return True or false + /// @notice Check if the address is blocked for usage + /// @param sender The transaction sender's address + /// @return True or false function isBlockedSender(address sender) external returns (bool); - // @notice Get a list of all allowed senders - // @dev WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - // to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - // this function has an unbounded cost, and using it as part of a state-changing function may render the function - // uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - // @return addresses - all allowed addresses + /// @notice Get a list of all allowed senders + /// @dev WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + /// to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + /// this function has an unbounded cost, and using it as part of a state-changing function may render the function + /// uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + /// @return addresses - all allowed addresses function getAllAllowedSenders() external view returns (address[] memory); - // @notice Allows access to the sender based on acceptance of the Terms of Service - // @param acceptor - The wallet address that has accepted the Terms of Service on the UI - // @param recipient - The recipient address that the acceptor is taking responsibility for - // @param r - ECDSA signature r data produced by the Chainlink Functions Subscription UI - // @param s - ECDSA signature s produced by the Chainlink Functions Subscription UI - // @param v - ECDSA signature v produced by the Chainlink Functions Subscription UI + /// @notice Allows access to the sender based on acceptance of the Terms of Service + /// @param acceptor - The wallet address that has accepted the Terms of Service on the UI + /// @param recipient - The recipient address that the acceptor is taking responsibility for + /// @param r - ECDSA signature r data produced by the Chainlink Functions Subscription UI + /// @param s - ECDSA signature s produced by the Chainlink Functions Subscription UI + /// @param v - ECDSA signature v produced by the Chainlink Functions Subscription UI function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external; - // @notice Removes a sender's access if already authorized, and disallows re-accepting the Terms of Service - // @param sender - Address of the sender to block + /// @notice Removes a sender's access if already authorized, and disallows re-accepting the Terms of Service + /// @param sender - Address of the sender to block function blockSender(address sender) external; - // @notice Re-allows a previously blocked sender to accept the Terms of Service - // @param sender - Address of the sender to unblock + /// @notice Re-allows a previously blocked sender to accept the Terms of Service + /// @param sender - Address of the sender to unblock function unblockSender(address sender) external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol b/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol index 5feee704ef5..f0f154c07b2 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol @@ -5,9 +5,7 @@ import {FunctionsClient} from "../FunctionsClient.sol"; import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; import {FunctionsRequest} from "../libraries/FunctionsRequest.sol"; -/** - * @title Chainlink Functions example Client contract implementation - */ +/// @title Chainlink Functions example Client contract implementation contract FunctionsClientExample is FunctionsClient, ConfirmedOwner { using FunctionsRequest for FunctionsRequest.Request; @@ -23,13 +21,11 @@ contract FunctionsClientExample is FunctionsClient, ConfirmedOwner { constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {} - /** - * @notice Send a simple request - * @param source JavaScript source code - * @param encryptedSecretsReferences Encrypted secrets payload - * @param args List of arguments accessible from within the source code - * @param subscriptionId Billing ID - */ + /// @notice Send a simple request + /// @param source JavaScript source code + /// @param encryptedSecretsReferences Encrypted secrets payload + /// @param args List of arguments accessible from within the source code + /// @param subscriptionId Billing ID function sendRequest( string calldata source, bytes calldata encryptedSecretsReferences, @@ -44,13 +40,11 @@ contract FunctionsClientExample is FunctionsClient, ConfirmedOwner { s_lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId); } - /** - * @notice Store latest result/error - * @param requestId The request ID, returned by sendRequest() - * @param response Aggregated response from the user code - * @param err Aggregated error from the user code or from the execution pipeline - * Either response or error parameter will be set, but never both - */ + /// @notice Store latest result/error + /// @param requestId The request ID, returned by sendRequest() + /// @param response Aggregated response from the user code + /// @param err Aggregated error from the user code or from the execution pipeline + /// @dev Either response or error parameter will be set, but never both function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override { if (s_lastRequestId != requestId) { revert UnexpectedRequestID(requestId); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol index c9730da899b..6291d05e57c 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol @@ -1,27 +1,27 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -// @title Chainlink Functions DON billing interface. +/// @title Chainlink Functions DON billing interface. interface IFunctionsBilling { - // @notice Return the current conversion from WEI of ETH to LINK from the configured Chainlink data feed - // @return weiPerUnitLink - The amount of WEI in one LINK + /// @notice Return the current conversion from WEI of ETH to LINK from the configured Chainlink data feed + /// @return weiPerUnitLink - The amount of WEI in one LINK function getWeiPerUnitLink() external view returns (uint256); - // @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 + /// @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); - // @notice Determine the fee that will be paid to the Router owner for operating the network - // @return fee - Cost in Juels (1e18) of LINK + /// @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); - // @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 - // @param - data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - // @param - callbackGasLimit Gas limit for the fulfillment callback - // @param - gasPriceWei The blockchain's gas price to estimate with - // @return - billedCost Cost in Juels (1e18) of LINK + /// @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 + /// @param - data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request + /// @param - callbackGasLimit Gas limit for the fulfillment callback + /// @param - gasPriceWei The blockchain's gas price to estimate with + /// @return - billedCost Cost in Juels (1e18) of LINK function estimateCost( uint64 subscriptionId, bytes calldata data, @@ -29,16 +29,16 @@ interface IFunctionsBilling { uint256 gasPriceWei ) external view returns (uint96); - // @notice Remove a request commitment that the Router has determined to be stale - // @param requestId - The request ID to remove + /// @notice Remove a request commitment that the Router has determined to be stale + /// @param requestId - The request ID to remove function deleteCommitment(bytes32 requestId) external; - // @notice Oracle withdraw LINK earned through fulfilling requests - // @notice If amount is 0 the full balance will be withdrawn - // @param recipient where to send the funds - // @param amount amount to withdraw + /// @notice Oracle withdraw LINK earned through fulfilling requests + /// @notice If amount is 0 the full balance will be withdrawn + /// @param recipient where to send the funds + /// @param amount amount to withdraw function oracleWithdraw(address recipient, uint96 amount) external; - // @notice Withdraw all LINK earned by Oracles through fulfilling requests + /// @notice Withdraw all LINK earned by Oracles through fulfilling requests function oracleWithdrawAll() external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol index 5fbee58274e..f28a41666b5 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -// @title Chainlink Functions client interface. +/// @title Chainlink Functions client interface. interface IFunctionsClient { - // @notice Chainlink Functions response handler called by the Functions Router - // during fullilment from the designated transmitter node in an OCR round. - // @param requestId The requestId returned by FunctionsClient.sendRequest(). - // @param response Aggregated response from the request's source code. - // @param err Aggregated error either from the request's source code or from the execution pipeline. - // @dev Either response or error parameter will be set, but never both. + /// @notice Chainlink Functions response handler called by the Functions Router + /// during fullilment from the designated transmitter node in an OCR round. + /// @param requestId The requestId returned by FunctionsClient.sendRequest(). + /// @param response Aggregated response from the request's source code. + /// @param err Aggregated error either from the request's source code or from the execution pipeline. + /// @dev Either response or error parameter will be set, but never both. function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol index 5a0d07415bd..4e2bd703dc4 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol @@ -3,34 +3,34 @@ pragma solidity ^0.8.19; import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; -// @title Chainlink Functions DON Coordinator interface. +/// @title Chainlink Functions DON Coordinator interface. interface IFunctionsCoordinator { - // @notice Returns the DON's threshold encryption public key used to encrypt secrets - // @dev All nodes on the DON have separate key shares of the threshold decryption key - // and nodes must participate in a threshold decryption OCR round to decrypt secrets - // @return thresholdPublicKey the DON's threshold encryption public key + /// @notice Returns the DON's threshold encryption public key used to encrypt secrets + /// @dev All nodes on the DON have separate key shares of the threshold decryption key + /// and nodes must participate in a threshold decryption OCR round to decrypt secrets + /// @return thresholdPublicKey the DON's threshold encryption public key function getThresholdPublicKey() external view returns (bytes memory); - // @notice Sets the DON's threshold encryption public key used to encrypt secrets - // @dev Used to rotate the key - // @param thresholdPublicKey The new public key + /// @notice Sets the DON's threshold encryption public key used to encrypt secrets + /// @dev Used to rotate the key + /// @param thresholdPublicKey The new public key function setThresholdPublicKey(bytes calldata thresholdPublicKey) external; - // @notice Returns the DON's secp256k1 public key that is used to encrypt secrets - // @dev All nodes on the DON have the corresponding private key - // needed to decrypt the secrets encrypted with the public key - // @return publicKey the DON's public key + /// @notice Returns the DON's secp256k1 public key that is used to encrypt secrets + /// @dev All nodes on the DON have the corresponding private key + /// needed to decrypt the secrets encrypted with the public key + /// @return publicKey the DON's public key function getDONPublicKey() external view returns (bytes memory); - // @notice Sets DON's secp256k1 public key used to encrypt secrets - // @dev Used to rotate the key - // @param donPublicKey The new public key + /// @notice Sets DON's secp256k1 public key used to encrypt secrets + /// @dev Used to rotate the key + /// @param donPublicKey The new public key function setDONPublicKey(bytes calldata donPublicKey) external; - // @notice Receives a request to be emitted to the DON for processing - // @param request The request metadata - // @dev see the struct for field descriptions - // @return commitment - The parameters of the request that must be held consistent at response time + /// @notice Receives a request to be emitted to the DON for processing + /// @param request The request metadata + /// @dev see the struct for field descriptions + /// @return commitment - The parameters of the request that must be held consistent at response time function startRequest( FunctionsResponse.RequestMeta calldata request ) external returns (FunctionsResponse.Commitment memory commitment); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol index ebc1dbd4538..5f93aac873e 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol @@ -3,29 +3,29 @@ pragma solidity ^0.8.19; import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; -// @title Chainlink Functions Router interface. +/// @title Chainlink Functions Router interface. interface IFunctionsRouter { - // @notice The identifier of the route to retrieve the address of the access control contract - // The access control contract controls which accounts can manage subscriptions - // @return id - bytes32 id that can be passed to the "getContractById" of the Router + /// @notice The identifier of the route to retrieve the address of the access control contract + /// The access control contract controls which accounts can manage subscriptions + /// @return id - bytes32 id that can be passed to the "getContractById" of the Router function getAllowListId() external view returns (bytes32); - // @notice Set the identifier of the route to retrieve the address of the access control contract - // The access control contract controls which accounts can manage subscriptions + /// @notice Set the identifier of the route to retrieve the address of the access control contract + /// The access control contract controls which accounts can manage subscriptions function setAllowListId(bytes32 allowListId) external; - // @notice Get the flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network - // @return adminFee + /// @notice Get the flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network + /// @return adminFee function getAdminFee() external view returns (uint72 adminFee); - // @notice Sends a request using the provided subscriptionId - // @param subscriptionId - A unique subscription ID allocated by billing system, - // a client can make requests from different contracts referencing the same subscription - // @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request - // @param dataVersion - Gas limit for the fulfillment callback - // @param callbackGasLimit - Gas limit for the fulfillment callback - // @param donId - An identifier used to determine which route to send the request along - // @return requestId - A unique request identifier + /// @notice Sends a request using the provided subscriptionId + /// @param subscriptionId - A unique subscription ID allocated by billing system, + /// a client can make requests from different contracts referencing the same subscription + /// @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request + /// @param dataVersion - Gas limit for the fulfillment callback + /// @param callbackGasLimit - Gas limit for the fulfillment callback + /// @param donId - An identifier used to determine which route to send the request along + /// @return requestId - A unique request identifier function sendRequest( uint64 subscriptionId, bytes calldata data, @@ -34,14 +34,14 @@ interface IFunctionsRouter { bytes32 donId ) external returns (bytes32); - // @notice Sends a request to the proposed contracts - // @param subscriptionId - A unique subscription ID allocated by billing system, - // a client can make requests from different contracts referencing the same subscription - // @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request - // @param dataVersion - Gas limit for the fulfillment callback - // @param callbackGasLimit - Gas limit for the fulfillment callback - // @param donId - An identifier used to determine which route to send the request along - // @return requestId - A unique request identifier + /// @notice Sends a request to the proposed contracts + /// @param subscriptionId - A unique subscription ID allocated by billing system, + /// a client can make requests from different contracts referencing the same subscription + /// @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request + /// @param dataVersion - Gas limit for the fulfillment callback + /// @param callbackGasLimit - Gas limit for the fulfillment callback + /// @param donId - An identifier used to determine which route to send the request along + /// @return requestId - A unique request identifier function sendRequestToProposed( uint64 subscriptionId, bytes calldata data, @@ -50,18 +50,18 @@ interface IFunctionsRouter { bytes32 donId ) external returns (bytes32); - // @notice Fulfill the request by: - // - calling back the data that the Oracle returned to the client contract - // - pay the DON for processing the request - // @dev Only callable by the Coordinator contract that is saved in the commitment - // @param response response data from DON consensus - // @param err error from DON consensus - // @param juelsPerGas - current rate of juels/gas - // @param costWithoutFulfillment - The cost of processing the request (in Juels of LINK ), without fulfillment - // @param transmitter - The Node that transmitted the OCR report - // @param commitment - The parameters of the request that must be held consistent between request and response time - // @return fulfillResult - - // @return callbackGasCostJuels - + /// @notice Fulfill the request by: + /// - calling back the data that the Oracle returned to the client contract + /// - pay the DON for processing the request + /// @dev Only callable by the Coordinator contract that is saved in the commitment + /// @param response response data from DON consensus + /// @param err error from DON consensus + /// @param juelsPerGas - current rate of juels/gas + /// @param costWithoutFulfillment - The cost of processing the request (in Juels of LINK ), without fulfillment + /// @param transmitter - The Node that transmitted the OCR report + /// @param commitment - The parameters of the request that must be held consistent between request and response time + /// @return fulfillResult - + /// @return callbackGasCostJuels - function fulfill( bytes memory response, bytes memory err, @@ -71,39 +71,39 @@ interface IFunctionsRouter { FunctionsResponse.Commitment memory commitment ) external returns (FunctionsResponse.FulfillResult, uint96); - // @notice Validate requested gas limit is below the subscription max. - // @param subscriptionId subscription ID - // @param callbackGasLimit desired callback gas limit + /// @notice Validate requested gas limit is below the subscription max. + /// @param subscriptionId subscription ID + /// @param callbackGasLimit desired callback gas limit function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) external view; - // @notice Get the current contract given an ID - // @param id A bytes32 identifier for the route - // @return contract The current contract address + /// @notice Get the current contract given an ID + /// @param id A bytes32 identifier for the route + /// @return contract The current contract address function getContractById(bytes32 id) external view returns (address); - // @notice Get the proposed next contract given an ID - // @param id A bytes32 identifier for the route - // @return contract The current or proposed contract address + /// @notice Get the proposed next contract given an ID + /// @param id A bytes32 identifier for the route + /// @return contract The current or proposed contract address function getProposedContractById(bytes32 id) external view returns (address); - // @notice Return the latest proprosal set - // @return ids The identifiers of the contracts to update - // @return to The addresses of the contracts that will be updated to + /// @notice Return the latest proprosal set + /// @return ids The identifiers of the contracts to update + /// @return to The addresses of the contracts that will be updated to function getProposedContractSet() external view returns (bytes32[] memory, address[] memory); - // @notice Proposes one or more updates to the contract routes - // @dev Only callable by owner + /// @notice Proposes one or more updates to the contract routes + /// @dev Only callable by owner function proposeContractsUpdate(bytes32[] memory proposalSetIds, address[] memory proposalSetAddresses) external; - // @notice Updates the current contract routes to the proposed contracts - // @dev Only callable by owner + /// @notice Updates the current contract routes to the proposed contracts + /// @dev Only callable by owner function updateContracts() external; - // @dev Puts the system into an emergency stopped state. - // @dev Only callable by owner + /// @dev Puts the system into an emergency stopped state. + /// @dev Only callable by owner function pause() external; - // @dev Takes the system out of an emergency stopped state. - // @dev Only callable by owner + /// @dev Takes the system out of an emergency stopped state. + /// @dev Only callable by owner function unpause() external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol index dacd0f13e62..eafd6f4fe99 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; -// @title Chainlink Functions Subscription interface. +/// @title Chainlink Functions Subscription interface. interface IFunctionsSubscriptions { struct Subscription { uint96 balance; // ═════════╗ Common LINK balance that is controlled by the Router to be used for all consumer requests. @@ -20,9 +20,9 @@ interface IFunctionsSubscriptions { uint64 completedRequests; // ══╝ The number of requests that have successfully completed or timed out } - // @notice Get details about a subscription. - // @param subscriptionId - the ID of the subscription - // @return subscription - see IFunctionsSubscriptions.Subscription for more information on the structure + /// @notice Get details about a subscription. + /// @param subscriptionId - the ID of the subscription + /// @return subscription - see IFunctionsSubscriptions.Subscription for more information on the structure function getSubscription(uint64 subscriptionId) external view returns (Subscription memory); /// @notice Retrieve details about multiple subscriptions using an inclusive range @@ -34,109 +34,107 @@ interface IFunctionsSubscriptions { uint64 subscriptionIdEnd ) external view returns (Subscription[] memory); - // @notice Get details about a consumer of a subscription. - // @param client - the consumer contract address - // @param subscriptionId - the ID of the subscription - // @return consumer - see IFunctionsSubscriptions.Consumer for more information on the structure + /// @notice Get details about a consumer of a subscription. + /// @param client - the consumer contract address + /// @param subscriptionId - the ID of the subscription + /// @return consumer - see IFunctionsSubscriptions.Consumer for more information on the structure function getConsumer(address client, uint64 subscriptionId) external view returns (Consumer memory); - // @notice Get details about the total amount of LINK within the system - // @return totalBalance - total Juels of LINK held by the contract + /// @notice Get details about the total amount of LINK within the system + /// @return totalBalance - total Juels of LINK held by the contract function getTotalBalance() external view returns (uint96); - // @notice Get details about the total number of subscription accounts - // @return count - total number of subscriptions in the system + /// @notice Get details about the total number of subscription accounts + /// @return count - total number of subscriptions in the system function getSubscriptionCount() external view returns (uint64); - // @notice Time out all expired requests: unlocks funds and removes the ability for the request to be fulfilled - // @param requestsToTimeoutByCommitment - A list of request commitments to time out - // @dev The commitment can be found on the "OracleRequest" event created when sending the request. + /// @notice Time out all expired requests: unlocks funds and removes the ability for the request to be fulfilled + /// @param requestsToTimeoutByCommitment - A list of request commitments to time out + /// @dev The commitment can be found on the "OracleRequest" event created when sending the request. function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external; - // @notice Oracle withdraw LINK earned through fulfilling requests - // @notice If amount is 0 the full balance will be withdrawn - // @notice Both signing and transmitting wallets will have a balance to withdraw - // @param recipient where to send the funds - // @param amount amount to withdraw + /// @notice Oracle withdraw LINK earned through fulfilling requests + /// @notice If amount is 0 the full balance will be withdrawn + /// @notice Both signing and transmitting wallets will have a balance to withdraw + /// @param recipient where to send the funds + /// @param amount amount to withdraw function oracleWithdraw(address recipient, uint96 amount) external; - // @notice Owner cancel subscription, sends remaining link directly to the subscription owner. - // @dev Only callable by the Router Owner - // @param subscriptionId subscription id - // @dev notably can be called even if there are pending requests, outstanding ones may fail onchain + /// @notice Owner cancel subscription, sends remaining link directly to the subscription owner. + /// @dev Only callable by the Router Owner + /// @param subscriptionId subscription id + /// @dev notably can be called even if there are pending requests, outstanding ones may fail onchain function ownerCancelSubscription(uint64 subscriptionId) external; - // @notice Recover link sent with transfer instead of transferAndCall. - // @dev Only callable by the Router Owner - // @param to address to send link to + /// @notice Recover link sent with transfer instead of transferAndCall. + /// @dev Only callable by the Router Owner + /// @param to address to send link to function recoverFunds(address to) external; - // @notice Create a new subscription. - // @return subscriptionId - A unique subscription id. - // @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. - // @dev Note to fund the subscription, use transferAndCall. For example - // @dev LINKTOKEN.transferAndCall( - // @dev address(ROUTER), - // @dev amount, - // @dev abi.encode(subscriptionId)); + /// @notice Create a new subscription. + /// @return subscriptionId - A unique subscription id. + /// @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. + /// @dev Note to fund the subscription, use transferAndCall. For example + /// @dev LINKTOKEN.transferAndCall( + /// @dev address(ROUTER), + /// @dev amount, + /// @dev abi.encode(subscriptionId)); function createSubscription() external returns (uint64); - // @notice Create a new subscription and add a consumer. - // @return subscriptionId - A unique subscription id. - // @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. - // @dev Note to fund the subscription, use transferAndCall. For example - // @dev LINKTOKEN.transferAndCall( - // @dev address(ROUTER), - // @dev amount, - // @dev abi.encode(subscriptionId)); + /// @notice Create a new subscription and add a consumer. + /// @return subscriptionId - A unique subscription id. + /// @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. + /// @dev Note to fund the subscription, use transferAndCall. For example + /// @dev LINKTOKEN.transferAndCall( + /// @dev address(ROUTER), + /// @dev amount, + /// @dev abi.encode(subscriptionId)); function createSubscriptionWithConsumer(address consumer) external returns (uint64 subscriptionId); - // @notice Propose a new owner for a subscription. - // @dev Only callable by the Subscription's owner - // @param subscriptionId - ID of the subscription - // @param newOwner - proposed new owner of the subscription + /// @notice Propose a new owner for a subscription. + /// @dev Only callable by the Subscription's owner + /// @param subscriptionId - ID of the subscription + /// @param newOwner - proposed new owner of the subscription function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external; - // @notice Accept an ownership transfer. - // @param subscriptionId - ID of the subscription - // @dev will revert if original owner of subscriptionId has - // not requested that msg.sender become the new owner. + /// @notice Accept an ownership transfer. + /// @param subscriptionId - ID of the subscription + /// @dev will revert if original owner of subscriptionId has not requested that msg.sender become the new owner. function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external; - // @notice Remove a consumer from a Chainlink Functions subscription. - // @dev Only callable by the Subscription's owner - // @param subscriptionId - ID of the subscription - // @param consumer - Consumer to remove from the subscription + /// @notice Remove a consumer from a Chainlink Functions subscription. + /// @dev Only callable by the Subscription's owner + /// @param subscriptionId - ID of the subscription + /// @param consumer - Consumer to remove from the subscription function removeConsumer(uint64 subscriptionId, address consumer) external; - // @notice Add a consumer to a Chainlink Functions subscription. - // @dev Only callable by the Subscription's owner - // @param subscriptionId - ID of the subscription - // @param consumer - New consumer which can use the subscription + /// @notice Add a consumer to a Chainlink Functions subscription. + /// @dev Only callable by the Subscription's owner + /// @param subscriptionId - ID of the subscription + /// @param consumer - New consumer which can use the subscription function addConsumer(uint64 subscriptionId, address consumer) external; - // @notice Cancel a subscription - // @dev Only callable by the Subscription's owner - // @param subscriptionId - ID of the subscription - // @param to - Where to send the remaining LINK to + /// @notice Cancel a subscription + /// @dev Only callable by the Subscription's owner + /// @param subscriptionId - ID of the subscription + /// @param to - Where to send the remaining LINK to function cancelSubscription(uint64 subscriptionId, address to) external; - // @notice Check to see if there exists a request commitment for all consumers for a given sub. - // @param subscriptionId - ID of the subscription - // @return true if there exists at least one unfulfilled request for the subscription, false - // otherwise. - // @dev Looping is bounded to MAX_CONSUMERS*(number of DONs). - // @dev Used to disable subscription canceling while outstanding request are present. + /// @notice Check to see if there exists a request commitment for all consumers for a given sub. + /// @param subscriptionId - ID of the subscription + /// @return true if there exists at least one unfulfilled request for the subscription, false otherwise. + /// @dev Looping is bounded to MAX_CONSUMERS*(number of DONs). + /// @dev Used to disable subscription canceling while outstanding request are present. function pendingRequestExists(uint64 subscriptionId) external view returns (bool); - // @notice Set subscription specific flags for a subscription. - // Each byte of the flag is used to represent a resource tier that the subscription can utilize. - // @param subscriptionId - ID of the subscription - // @param flags - desired flag values + /// @notice Set subscription specific flags for a subscription. + /// Each byte of the flag is used to represent a resource tier that the subscription can utilize. + /// @param subscriptionId - ID of the subscription + /// @param flags - desired flag values function setFlags(uint64 subscriptionId, bytes32 flags) external; - // @notice Get flags for a given subscription. - // @param subscriptionId - ID of the subscription - // @return flags - current flag values + /// @notice Get flags for a given subscription. + /// @param subscriptionId - ID of the subscription + /// @return flags - current flag values function getFlags(uint64 subscriptionId) external view returns (bytes32); } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol index 5a2f85fd32e..39b84a930aa 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.19; import {IFunctionsRouter} from "./IFunctionsRouter.sol"; import {IOwnable} from "../../../../shared/interfaces/IOwnable.sol"; -// @title Chainlink Functions Router interface with Ownability. +/// @title Chainlink Functions Router interface with Ownability. interface IOwnableFunctionsRouter is IOwnable, IFunctionsRouter { } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol index 76b83a998bd..efc3a811e6a 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {CBOR} from "../../../../vendor/solidity-cborutils/v2.0.0/CBOR.sol"; -// @title Library for encoding the input data of a Functions request into CBOR +/// @title Library for encoding the input data of a Functions request into CBOR library FunctionsRequest { using CBOR for CBOR.CBORBuffer; @@ -36,9 +36,9 @@ library FunctionsRequest { error EmptyArgs(); error NoInlineSecrets(); - // @notice Encodes a Request to CBOR encoded bytes - // @param self The request to encode - // @return CBOR encoded bytes + /// @notice Encodes a Request to CBOR encoded bytes + /// @param self The request to encode + /// @return CBOR encoded bytes function encodeCBOR(Request memory self) internal pure returns (bytes memory) { CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE); @@ -82,12 +82,12 @@ library FunctionsRequest { return buffer.buf.buf; } - // @notice Initializes a Chainlink Functions Request - // @dev Sets the codeLocation and code on the request - // @param self The uninitialized request - // @param codeLocation The user provided source code location - // @param language The programming language of the user code - // @param source The user provided source code or a url + /// @notice Initializes a Chainlink Functions Request + /// @dev Sets the codeLocation and code on the request + /// @param self The uninitialized request + /// @param codeLocation The user provided source code location + /// @param language The programming language of the user code + /// @param source The user provided source code or a url function initializeRequest( Request memory self, Location codeLocation, @@ -101,17 +101,17 @@ library FunctionsRequest { self.source = source; } - // @notice Initializes a Chainlink Functions Request - // @dev Simplified version of initializeRequest for PoC - // @param self The uninitialized request - // @param javaScriptSource The user provided JS code (must not be empty) + /// @notice Initializes a Chainlink Functions Request + /// @dev Simplified version of initializeRequest for PoC + /// @param self The uninitialized request + /// @param javaScriptSource The user provided JS code (must not be empty) function initializeRequestForInlineJavaScript(Request memory self, string memory javaScriptSource) internal pure { initializeRequest(self, Location.Inline, CodeLanguage.JavaScript, javaScriptSource); } - // @notice Adds Remote user encrypted secrets to a Request - // @param self The initialized request - // @param encryptedSecretsReference Encrypted comma-separated string of URLs pointing to off-chain secrets + /// @notice Adds Remote user encrypted secrets to a Request + /// @param self The initialized request + /// @param encryptedSecretsReference Encrypted comma-separated string of URLs pointing to off-chain secrets function addSecretsReference(Request memory self, bytes memory encryptedSecretsReference) internal pure { if (encryptedSecretsReference.length == 0) revert EmptySecrets(); @@ -119,10 +119,10 @@ library FunctionsRequest { self.encryptedSecretsReference = encryptedSecretsReference; } - // @notice Adds DON-hosted secrets reference to a Request - // @param self The initialized request - // @param slotID Slot ID of the user's secrets hosted on DON - // @param version User data version (for the slotID) + /// @notice Adds DON-hosted secrets reference to a Request + /// @param self The initialized request + /// @param slotID Slot ID of the user's secrets hosted on DON + /// @param version User data version (for the slotID) function addDONHostedSecrets(Request memory self, uint8 slotID, uint64 version) internal pure { CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE); @@ -135,18 +135,18 @@ library FunctionsRequest { self.encryptedSecretsReference = buffer.buf.buf; } - // @notice Sets args for the user run function - // @param self The initialized request - // @param args The array of string args (must not be empty) + /// @notice Sets args for the user run function + /// @param self The initialized request + /// @param args The array of string args (must not be empty) function setArgs(Request memory self, string[] memory args) internal pure { if (args.length == 0) revert EmptyArgs(); self.args = args; } - // @notice Sets bytes args for the user run function - // @param self The initialized request - // @param args The array of bytes args (must not be empty) + /// @notice Sets bytes args for the user run function + /// @param self The initialized request + /// @param args The array of bytes args (must not be empty) function setBytesArgs(Request memory self, bytes[] memory args) internal pure { if (args.length == 0) revert EmptyArgs(); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol index 71e731b2e33..31a33169226 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {IFunctionsSubscriptions} from "../interfaces/IFunctionsSubscriptions.sol"; -// @title Library of types that are used for fulfillment of a Functions request +/// @title Library of types that are used for fulfillment of a Functions request library FunctionsResponse { // Used to send request information from the Router to the Coordinator struct RequestMeta { From f678a4ca0375aaef2cff45dc90995875b5b6c8ef Mon Sep 17 00:00:00 2001 From: Domino Valdano <2644901+reductionista@users.noreply.github.com> Date: Fri, 8 Sep 2023 17:42:56 -0700 Subject: [PATCH 80/88] Pass de-duped block list to fillRemainingBlocks() (#10554) This avoids us requesting the same block multiple times from the rpc server --- core/chains/evm/logpoller/log_poller.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 69a3143859f..e4ad8dcdfaa 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -657,7 +657,7 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error { } } if batchSize == 1 { - lp.lggr.Criticalw("Too many log results in a single block, failed to retrieve logs! Node may run in a degraded state unless LogBackfillBatchSize is increased", "err", err, "from", from, "to", to, "LogBackfillBatchSize", lp.backfillBatchSize) + lp.lggr.Criticalw("Too many log results in a single block, failed to retrieve logs! Node may be running in a degraded state.", "err", err, "from", from, "to", to, "LogBackfillBatchSize", lp.backfillBatchSize) return err } batchSize /= 2 @@ -1043,7 +1043,7 @@ func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts } // Fill any remaining blocks from the client. - blocksFoundFromRPC, err := lp.fillRemainingBlocksFromRPC(ctx, numbers, blocksFound) + blocksFoundFromRPC, err := lp.fillRemainingBlocksFromRPC(ctx, blocksRequested, blocksFound) if err != nil { return nil, err } @@ -1069,12 +1069,12 @@ func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts func (lp *logPoller) fillRemainingBlocksFromRPC( ctx context.Context, - blocksRequested []uint64, + blocksRequested map[uint64]struct{}, blocksFound map[uint64]LogPollerBlock, ) (map[uint64]LogPollerBlock, error) { var reqs []rpc.BatchElem var remainingBlocks []uint64 - for _, num := range blocksRequested { + for num := range blocksRequested { if _, ok := blocksFound[num]; !ok { req := rpc.BatchElem{ Method: "eth_getBlockByNumber", From ecd650fad8db78c7488594eada33df3bf30f1a12 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Sat, 9 Sep 2023 11:59:23 -0400 Subject: [PATCH 81/88] update streams lookup contracts (#10524) * update streams lookup contracts * update go wrappers * update contracts * update contracts * prettier --- .../src/v0.8/tests/StreamsLookupUpkeep.sol | 39 +++++++++---------- .../tests/VerifiableLoadLogTriggerUpkeep.sol | 12 +++++- .../VerifiableLoadStreamsLookupUpkeep.sol | 10 ++++- .../streams_lookup_upkeep_wrapper.go | 8 ++-- ...ifiable_load_log_trigger_upkeep_wrapper.go | 2 +- ...able_load_streams_lookup_upkeep_wrapper.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 6 +-- 7 files changed, 45 insertions(+), 34 deletions(-) diff --git a/contracts/src/v0.8/tests/StreamsLookupUpkeep.sol b/contracts/src/v0.8/tests/StreamsLookupUpkeep.sol index 8cdcf71178d..9b28875020d 100644 --- a/contracts/src/v0.8/tests/StreamsLookupUpkeep.sol +++ b/contracts/src/v0.8/tests/StreamsLookupUpkeep.sol @@ -15,15 +15,7 @@ interface IVerifierProxy { } contract StreamsLookupUpkeep is AutomationCompatibleInterface, StreamsLookupCompatibleInterface { - event MercuryPerformEvent( - address indexed sender, - uint256 indexed blockNumber, - bytes v0, - bytes v1, - bytes verifiedV0, - bytes verifiedV1, - bytes ed - ); + event MercuryPerformEvent(address indexed sender, uint256 indexed blockNumber, bytes v0, bytes verifiedV0, bytes ed); ArbSys internal constant ARB_SYS = ArbSys(0x0000000000000000000000000000000000000064); // keep these in sync with verifier proxy in RDD @@ -53,12 +45,13 @@ contract StreamsLookupUpkeep is AutomationCompatibleInterface, StreamsLookupComp initialBlock = 0; counter = 0; useArbBlock = _useArbBlock; - feedParamKey = "feedIdHex"; // feedIDs for v0.3 - timeParamKey = "blockNumber"; // timestamp + feedParamKey = "feedIDs"; // feedIDs for v0.3 + timeParamKey = "timestamp"; // timestamp // search feeds in notion: "Schema and Feed ID Registry" feeds = [ - "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", // ETH / USD in production testnet - "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000" // BTC / USD in production testnet + //"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", // ETH / USD in production testnet v0.2 + //"0x4254432d5553442d415242495452554d2d544553544e45540000000000000000" // BTC / USD in production testnet v0.2 + "0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c" // ETH / USD in staging testnet v0.3 ]; staging = _staging; verify = _verify; @@ -99,15 +92,21 @@ contract StreamsLookupUpkeep is AutomationCompatibleInterface, StreamsLookupComp if (!eligible()) { return (false, data); } - uint256 blockNumber; - if (useArbBlock) { - blockNumber = ARB_SYS.arbBlockNumber(); + uint256 timeParam; + if (keccak256(abi.encodePacked(timeParamKey)) == keccak256(abi.encodePacked("feedIdHex"))) { + if (useArbBlock) { + timeParam = ARB_SYS.arbBlockNumber(); + } else { + timeParam = block.number; + } } else { - blockNumber = block.number; + // assume this will be feedIDs for v0.3 + timeParam = block.timestamp; } + // encode ARB_SYS as extraData to verify that it is provided to checkCallback correctly. // in reality, this can be any data or empty - revert StreamsLookup(feedParamKey, feeds, timeParamKey, blockNumber, abi.encodePacked(address(ARB_SYS))); + revert StreamsLookup(feedParamKey, feeds, timeParamKey, timeParam, abi.encodePacked(address(ARB_SYS))); } function performUpkeep(bytes calldata performData) external { @@ -129,13 +128,11 @@ contract StreamsLookupUpkeep is AutomationCompatibleInterface, StreamsLookupComp if (verify) { if (staging) { v0 = STAGING_TESTNET_VERIFIER_PROXY.verify(values[0]); - v1 = STAGING_TESTNET_VERIFIER_PROXY.verify(values[1]); } else { v0 = PRODUCTION_TESTNET_VERIFIER_PROXY.verify(values[0]); - v1 = PRODUCTION_TESTNET_VERIFIER_PROXY.verify(values[1]); } } - emit MercuryPerformEvent(msg.sender, blockNumber, values[0], values[1], v0, v1, extraData); + emit MercuryPerformEvent(msg.sender, blockNumber, values[0], v0, extraData); } function eligible() public view returns (bool) { diff --git a/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol b/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol index 355be69d250..02ad2ef2d45 100644 --- a/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol +++ b/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol @@ -54,12 +54,20 @@ contract VerifiableLoadLogTriggerUpkeep is VerifiableLoadBase, StreamsLookupComp dummyMap[blockhash(blockNum)] = false; } + uint256 timeParam; + if (keccak256(abi.encodePacked(timeParamKey)) == keccak256(abi.encodePacked("feedIdHex"))) { + timeParam = blockNum; + } else { + // assume this will be feedIDs for v0.3 + timeParam = block.timestamp; + } + if (useMercury) { - revert StreamsLookup(feedParamKey, feedsHex, timeParamKey, blockNum, abi.encode(upkeepId, blockNum, addr)); + revert StreamsLookup(feedParamKey, feedsHex, timeParamKey, timeParam, abi.encode(upkeepId, blockNum, addr)); } // if we don't use mercury, create a perform data which resembles the output of checkCallback - bytes[] memory values = new bytes[](2); + bytes[] memory values = new bytes[](feedsHex.length); bytes memory extraData = abi.encode(upkeepId, blockNum, addr); return (true, abi.encode(values, extraData)); } diff --git a/contracts/src/v0.8/tests/VerifiableLoadStreamsLookupUpkeep.sol b/contracts/src/v0.8/tests/VerifiableLoadStreamsLookupUpkeep.sol index 63dd813e1cd..451de7aebdb 100644 --- a/contracts/src/v0.8/tests/VerifiableLoadStreamsLookupUpkeep.sol +++ b/contracts/src/v0.8/tests/VerifiableLoadStreamsLookupUpkeep.sol @@ -34,7 +34,15 @@ contract VerifiableLoadStreamsLookupUpkeep is VerifiableLoadBase, StreamsLookupC return (false, pData); } - revert StreamsLookup(feedParamKey, feedsHex, timeParamKey, blockNum, abi.encode(upkeepId)); + uint256 timeParam; + if (keccak256(abi.encodePacked(timeParamKey)) == keccak256(abi.encodePacked("feedIdHex"))) { + timeParam = blockNum; + } else { + // assume this will be feedIDs for v0.3 + timeParam = block.timestamp; + } + + revert StreamsLookup(feedParamKey, feedsHex, timeParamKey, timeParam, abi.encode(upkeepId)); } function performUpkeep(bytes calldata performData) external { diff --git a/core/gethwrappers/generated/streams_lookup_upkeep_wrapper/streams_lookup_upkeep_wrapper.go b/core/gethwrappers/generated/streams_lookup_upkeep_wrapper/streams_lookup_upkeep_wrapper.go index e9d48584339..0ef24e516ec 100644 --- a/core/gethwrappers/generated/streams_lookup_upkeep_wrapper/streams_lookup_upkeep_wrapper.go +++ b/core/gethwrappers/generated/streams_lookup_upkeep_wrapper/streams_lookup_upkeep_wrapper.go @@ -31,8 +31,8 @@ var ( ) var StreamsLookupUpkeepMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_useArbBlock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_staging\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_verify\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v1\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verifiedV0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verifiedV1\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ed\",\"type\":\"bytes\"}],\"name\":\"MercuryPerformEvent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"callbackReturnBool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feeds\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setCallbackReturnBool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setShouldRevertCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shouldRevertCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staging\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbBlock\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001b9c38038062001b9c833981016040819052620000349162000232565b60008581556001859055600281905560038190556004558215156080526040805180820190915260098152680cccacac892c890caf60bb1b602082015260069062000080908262000335565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b6020820152600790620000b2908262000335565b50604051806040016040528060405180608001604052806042815260200162001b1860429139815260200160405180608001604052806042815260200162001b5a6042913990526200010990600590600262000145565b506008805463ff000000199215156101000261ff00199415159490941661ffff1990911617929092171663010000001790555062000401915050565b82805482825590600052602060002090810192821562000190579160200282015b828111156200019057825182906200017f908262000335565b509160200191906001019062000166565b506200019e929150620001a2565b5090565b808211156200019e576000620001b98282620001c3565b50600101620001a2565b508054620001d190620002a6565b6000825580601f10620001e2575050565b601f01602090049060005260206000209081019062000202919062000205565b50565b5b808211156200019e576000815560010162000206565b805180151581146200022d57600080fd5b919050565b600080600080600060a086880312156200024b57600080fd5b855194506020860151935062000264604087016200021c565b925062000274606087016200021c565b915062000284608087016200021c565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620002bb57607f821691505b602082108103620002dc57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200033057600081815260208120601f850160051c810160208610156200030b5750805b601f850160051c820191505b818110156200032c5782815560010162000317565b5050505b505050565b81516001600160401b0381111562000351576200035162000290565b6200036981620003628454620002a6565b84620002e2565b602080601f831160018114620003a15760008415620003885750858301515b600019600386901b1c1916600185901b1785556200032c565b600085815260208120601f198616915b82811015620003d257888601518255948401946001909101908401620003b1565b5085821015620003f15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516116e662000432600039600081816103070152818161039001528181610a560152610bbe01526116e66000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c80636e04ff0d116100d8578063947a36fb1161008c578063d826f88f11610066578063d826f88f1461035e578063d832d92f14610372578063fc735e991461037a57600080fd5b8063947a36fb14610345578063afb28d1f1461034e578063c98f10b01461035657600080fd5b806386b728e2116100bd57806386b728e21461030257806386e330af14610329578063917d895f1461033c57600080fd5b80636e04ff0d146102dc5780638340507c146102ef57600080fd5b80634a5479f31161013a5780635b48391a116101145780635b48391a1461028357806361bc221a146102ca5780636250a13a146102d357600080fd5b80634a5479f3146101fc5780634b56a42e1461021c5780634bdb38621461023d57600080fd5b80631d1970b71161016b5780631d1970b7146101c35780632cb15864146101d05780634585e33b146101e757600080fd5b806302be021f14610187578063102d538b146101af575b600080fd5b60085461019a9062010000900460ff1681565b60405190151581526020015b60405180910390f35b60085461019a906301000000900460ff1681565b60085461019a9060ff1681565b6101d960035481565b6040519081526020016101a6565b6101fa6101f5366004610d52565b61038c565b005b61020f61020a366004610dc4565b610873565b6040516101a69190610e4b565b61022f61022a366004610fa3565b61091f565b6040516101a6929190611077565b6101fa61024b36600461109a565b6008805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b6101fa61029136600461109a565b600880549115156301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff909216919091179055565b6101d960045481565b6101d960005481565b61022f6102ea366004610d52565b6109fa565b6101fa6102fd3660046110bc565b610b59565b61019a7f000000000000000000000000000000000000000000000000000000000000000081565b6101fa610337366004611109565b610b77565b6101d960025481565b6101d960015481565b61020f610b8e565b61020f610b9b565b6101fa600060028190556003819055600455565b61019a610ba8565b60085461019a90610100900460ff1681565b60007f00000000000000000000000000000000000000000000000000000000000000001561042b57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610400573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042491906111ba565b905061042e565b50435b60035460000361043e5760038190555b60008061044d84860186610fa3565b60028590556004549193509150610465906001611202565b600455604080516020808201835260008083528351918201909352918252600854909190610100900460ff16156107df5760085460ff1615610642577360448b880c9f3b501af3f343da9284148bd7d77c73ffffffffffffffffffffffffffffffffffffffff16638e760afe856000815181106104e4576104e461121b565b60200260200101516040518263ffffffff1660e01b81526004016105089190610e4b565b6000604051808303816000875af1158015610527573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261056d919081019061124a565b91507360448b880c9f3b501af3f343da9284148bd7d77c73ffffffffffffffffffffffffffffffffffffffff16638e760afe856001815181106105b2576105b261121b565b60200260200101516040518263ffffffff1660e01b81526004016105d69190610e4b565b6000604051808303816000875af11580156105f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261063b919081019061124a565b90506107df565b7309dff56a4ff44e0f4436260a04f5cfa65636a48173ffffffffffffffffffffffffffffffffffffffff16638e760afe856000815181106106855761068561121b565b60200260200101516040518263ffffffff1660e01b81526004016106a99190610e4b565b6000604051808303816000875af11580156106c8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261070e919081019061124a565b91507309dff56a4ff44e0f4436260a04f5cfa65636a48173ffffffffffffffffffffffffffffffffffffffff16638e760afe856001815181106107535761075361121b565b60200260200101516040518263ffffffff1660e01b81526004016107779190610e4b565b6000604051808303816000875af1158015610796573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526107dc919081019061124a565b90505b843373ffffffffffffffffffffffffffffffffffffffff167f1c85d6186f024e964616014c8247533455ec5129a5095711202292f8a7ea1d548660008151811061082b5761082b61121b565b6020026020010151876001815181106108465761084661121b565b60200260200101518686896040516108629594939291906112c1565b60405180910390a350505050505050565b6005818154811061088357600080fd5b90600052602060002001600091509050805461089e9061132e565b80601f01602080910402602001604051908101604052809291908181526020018280546108ca9061132e565b80156109175780601f106108ec57610100808354040283529160200191610917565b820191906000526020600020905b8154815290600101906020018083116108fa57829003601f168201915b505050505081565b60085460009060609062010000900460ff161561099d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f73686f756c6452657665727443616c6c6261636b20697320747275650000000060448201526064015b60405180910390fd5b600084846040516020016109b2929190611381565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526008546301000000900460ff1693509150505b9250929050565b60006060610a06610ba8565b610a52576000848481818080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509597509195506109f3945050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015610af157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aea91906111ba565b9050610af4565b50435b604080516c6400000000000000000000000060208201528151601481830301815260348201928390527ff055e4a200000000000000000000000000000000000000000000000000000000909252610994916006916005916007918691906038016114a7565b6006610b6583826115ac565b506007610b7282826115ac565b505050565b8051610b8a906005906020840190610c8d565b5050565b6006805461089e9061132e565b6007805461089e9061132e565b6000600354600003610bba5750600190565b60007f000000000000000000000000000000000000000000000000000000000000000015610c5957606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5291906111ba565b9050610c5c565b50435b600054600354610c6c90836116c6565b108015610c875750600154600254610c8490836116c6565b10155b91505090565b828054828255906000526020600020908101928215610cd3579160200282015b82811115610cd35782518290610cc390826115ac565b5091602001919060010190610cad565b50610cdf929150610ce3565b5090565b80821115610cdf576000610cf78282610d00565b50600101610ce3565b508054610d0c9061132e565b6000825580601f10610d1c575050565b601f016020900490600052602060002090810190610d3a9190610d3d565b50565b5b80821115610cdf5760008155600101610d3e565b60008060208385031215610d6557600080fd5b823567ffffffffffffffff80821115610d7d57600080fd5b818501915085601f830112610d9157600080fd5b813581811115610da057600080fd5b866020828501011115610db257600080fd5b60209290920196919550909350505050565b600060208284031215610dd657600080fd5b5035919050565b60005b83811015610df8578181015183820152602001610de0565b50506000910152565b60008151808452610e19816020860160208601610ddd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610e5e6020830184610e01565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610edb57610edb610e65565b604052919050565b600067ffffffffffffffff821115610efd57610efd610e65565b5060051b60200190565b600067ffffffffffffffff821115610f2157610f21610e65565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112610f5e57600080fd5b8135610f71610f6c82610f07565b610e94565b818152846020838601011115610f8657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215610fb657600080fd5b823567ffffffffffffffff80821115610fce57600080fd5b818501915085601f830112610fe257600080fd5b81356020610ff2610f6c83610ee3565b82815260059290921b8401810191818101908984111561101157600080fd5b8286015b848110156110495780358681111561102d5760008081fd5b61103b8c86838b0101610f4d565b845250918301918301611015565b509650508601359250508082111561106057600080fd5b5061106d85828601610f4d565b9150509250929050565b82151581526040602082015260006110926040830184610e01565b949350505050565b6000602082840312156110ac57600080fd5b81358015158114610e5e57600080fd5b600080604083850312156110cf57600080fd5b823567ffffffffffffffff808211156110e757600080fd5b6110f386838701610f4d565b9350602085013591508082111561106057600080fd5b6000602080838503121561111c57600080fd5b823567ffffffffffffffff8082111561113457600080fd5b818501915085601f83011261114857600080fd5b8135611156610f6c82610ee3565b81815260059190911b8301840190848101908883111561117557600080fd5b8585015b838110156111ad578035858111156111915760008081fd5b61119f8b89838a0101610f4d565b845250918601918601611179565b5098975050505050505050565b6000602082840312156111cc57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115611215576112156111d3565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561125c57600080fd5b815167ffffffffffffffff81111561127357600080fd5b8201601f8101841361128457600080fd5b8051611292610f6c82610f07565b8181528560208385010111156112a757600080fd5b6112b8826020830160208601610ddd565b95945050505050565b60a0815260006112d460a0830188610e01565b82810360208401526112e68188610e01565b905082810360408401526112fa8187610e01565b9050828103606084015261130e8186610e01565b905082810360808401526113228185610e01565b98975050505050505050565b600181811c9082168061134257607f821691505b60208210810361137b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156113f6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08887030185526113e4868351610e01565b955093820193908201906001016113aa565b5050858403818701525050506112b88185610e01565b600081546114198161132e565b808552602060018381168015611436576001811461146e5761149c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061149c565b866000528260002060005b858110156114945781548a8201860152908301908401611479565b890184019650505b505050505092915050565b60a0815260006114ba60a083018861140c565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b8381101561152c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261151a838361140c565b948601949250600191820191016114e1565b50508681036040880152611540818b61140c565b94505050505084606084015282810360808401526113228185610e01565b601f821115610b7257600081815260208120601f850160051c810160208610156115855750805b601f850160051c820191505b818110156115a457828155600101611591565b505050505050565b815167ffffffffffffffff8111156115c6576115c6610e65565b6115da816115d4845461132e565b8461155e565b602080601f83116001811461162d57600084156115f75750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556115a4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561167a5788860151825594840194600190910190840161165b565b50858210156116b657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b81810381811115611215576112156111d356fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_useArbBlock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_staging\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_verify\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verifiedV0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ed\",\"type\":\"bytes\"}],\"name\":\"MercuryPerformEvent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"callbackReturnBool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feeds\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setCallbackReturnBool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setShouldRevertCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shouldRevertCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staging\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbBlock\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001a6a38038062001a6a83398101604081905262000034916200020f565b60008581556001859055600281905560038190556004558215156080526040805180820190915260078152666665656449447360c81b60208201526006906200007e908262000312565b50604080518082019091526009815268074696d657374616d760bc1b6020820152600790620000ae908262000312565b50604051806020016040528060405180608001604052806042815260200162001a28604291399052620000e690600590600162000122565b506008805463ff000000199215156101000261ff00199415159490941661ffff19909116179290921716630100000017905550620003de915050565b8280548282559060005260206000209081019282156200016d579160200282015b828111156200016d57825182906200015c908262000312565b509160200191906001019062000143565b506200017b9291506200017f565b5090565b808211156200017b576000620001968282620001a0565b506001016200017f565b508054620001ae9062000283565b6000825580601f10620001bf575050565b601f016020900490600052602060002090810190620001df9190620001e2565b50565b5b808211156200017b5760008155600101620001e3565b805180151581146200020a57600080fd5b919050565b600080600080600060a086880312156200022857600080fd5b85519450602086015193506200024160408701620001f9565b92506200025160608701620001f9565b91506200026160808701620001f9565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200029857607f821691505b602082108103620002b957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200030d57600081815260208120601f850160051c81016020861015620002e85750805b601f850160051c820191505b818110156200030957828155600101620002f4565b5050505b505050565b81516001600160401b038111156200032e576200032e6200026d565b62000346816200033f845462000283565b84620002bf565b602080601f8311600181146200037e5760008415620003655750858301515b600019600386901b1c1916600185901b17855562000309565b600085815260208120601f198616915b82811015620003af578886015182559484019460019091019084016200038e565b5085821015620003ce5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516116196200040f60003960008181610307015281816103900152818161090c0152610a7b01526116196000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c80636e04ff0d116100d8578063947a36fb1161008c578063d826f88f11610066578063d826f88f1461035e578063d832d92f14610372578063fc735e991461037a57600080fd5b8063947a36fb14610345578063afb28d1f1461034e578063c98f10b01461035657600080fd5b806386b728e2116100bd57806386b728e21461030257806386e330af14610329578063917d895f1461033c57600080fd5b80636e04ff0d146102dc5780638340507c146102ef57600080fd5b80634a5479f31161013a5780635b48391a116101145780635b48391a1461028357806361bc221a146102ca5780636250a13a146102d357600080fd5b80634a5479f3146101fc5780634b56a42e1461021c5780634bdb38621461023d57600080fd5b80631d1970b71161016b5780631d1970b7146101c35780632cb15864146101d05780634585e33b146101e757600080fd5b806302be021f14610187578063102d538b146101af575b600080fd5b60085461019a9062010000900460ff1681565b60405190151581526020015b60405180910390f35b60085461019a906301000000900460ff1681565b60085461019a9060ff1681565b6101d960035481565b6040519081526020016101a6565b6101fa6101f5366004610c0f565b61038c565b005b61020f61020a366004610c81565b6106b9565b6040516101a69190610d08565b61022f61022a366004610e60565b610765565b6040516101a6929190610f34565b6101fa61024b366004610f57565b6008805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b6101fa610291366004610f57565b600880549115156301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff909216919091179055565b6101d960045481565b6101d960005481565b61022f6102ea366004610c0f565b610840565b6101fa6102fd366004610f79565b610a16565b61019a7f000000000000000000000000000000000000000000000000000000000000000081565b6101fa610337366004610fc6565b610a34565b6101d960025481565b6101d960015481565b61020f610a4b565b61020f610a58565b6101fa600060028190556003819055600455565b61019a610a65565b60085461019a90610100900460ff1681565b60007f00000000000000000000000000000000000000000000000000000000000000001561042b57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190611077565b905061042e565b50435b60035460000361043e5760038190555b60008061044d84860186610e60565b600285905560045491935091506104659060016110bf565b600455604080516020808201835260008083528351918201909352918252600854909190610100900460ff16156106435760085460ff1615610574577360448b880c9f3b501af3f343da9284148bd7d77c73ffffffffffffffffffffffffffffffffffffffff16638e760afe856000815181106104e4576104e46110d8565b60200260200101516040518263ffffffff1660e01b81526004016105089190610d08565b6000604051808303816000875af1158015610527573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261056d9190810190611107565b9150610643565b7309dff56a4ff44e0f4436260a04f5cfa65636a48173ffffffffffffffffffffffffffffffffffffffff16638e760afe856000815181106105b7576105b76110d8565b60200260200101516040518263ffffffff1660e01b81526004016105db9190610d08565b6000604051808303816000875af11580156105fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106409190810190611107565b91505b843373ffffffffffffffffffffffffffffffffffffffff167ff0f72c0b235fc8687d6a67c02ca543473a3cef8a18b48490f10e475a8dda13908660008151811061068f5761068f6110d8565b602002602001015185876040516106a89392919061117e565b60405180910390a350505050505050565b600581815481106106c957600080fd5b9060005260206000200160009150905080546106e4906111c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610710906111c1565b801561075d5780601f106107325761010080835404028352916020019161075d565b820191906000526020600020905b81548152906001019060200180831161074057829003601f168201915b505050505081565b60085460009060609062010000900460ff16156107e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f73686f756c6452657665727443616c6c6261636b20697320747275650000000060448201526064015b60405180910390fd5b600084846040516020016107f8929190611214565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526008546301000000900460ff1693509150505b9250929050565b6000606061084c610a65565b610898576000848481818080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250959750919550610839945050505050565b6040517f666565644964486578000000000000000000000000000000000000000000000060208201526000906029016040516020818303038152906040528051906020012060076040516020016108ef919061129f565b60405160208183030381529060405280519060200120036109ae577f0000000000000000000000000000000000000000000000000000000000000000156109a757606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a09190611077565b90506109b1565b50436109b1565b50425b604080516c6400000000000000000000000060208201528151601481830301815260348201928390527ff055e4a2000000000000000000000000000000000000000000000000000000009092526107da916006916005916007918691906038016113ce565b6006610a2283826114df565b506007610a2f82826114df565b505050565b8051610a47906005906020840190610b4a565b5050565b600680546106e4906111c1565b600780546106e4906111c1565b6000600354600003610a775750600190565b60007f000000000000000000000000000000000000000000000000000000000000000015610b1657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0f9190611077565b9050610b19565b50435b600054600354610b2990836115f9565b108015610b445750600154600254610b4190836115f9565b10155b91505090565b828054828255906000526020600020908101928215610b90579160200282015b82811115610b905782518290610b8090826114df565b5091602001919060010190610b6a565b50610b9c929150610ba0565b5090565b80821115610b9c576000610bb48282610bbd565b50600101610ba0565b508054610bc9906111c1565b6000825580601f10610bd9575050565b601f016020900490600052602060002090810190610bf79190610bfa565b50565b5b80821115610b9c5760008155600101610bfb565b60008060208385031215610c2257600080fd5b823567ffffffffffffffff80821115610c3a57600080fd5b818501915085601f830112610c4e57600080fd5b813581811115610c5d57600080fd5b866020828501011115610c6f57600080fd5b60209290920196919550909350505050565b600060208284031215610c9357600080fd5b5035919050565b60005b83811015610cb5578181015183820152602001610c9d565b50506000910152565b60008151808452610cd6816020860160208601610c9a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610d1b6020830184610cbe565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d9857610d98610d22565b604052919050565b600067ffffffffffffffff821115610dba57610dba610d22565b5060051b60200190565b600067ffffffffffffffff821115610dde57610dde610d22565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112610e1b57600080fd5b8135610e2e610e2982610dc4565b610d51565b818152846020838601011115610e4357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215610e7357600080fd5b823567ffffffffffffffff80821115610e8b57600080fd5b818501915085601f830112610e9f57600080fd5b81356020610eaf610e2983610da0565b82815260059290921b84018101918181019089841115610ece57600080fd5b8286015b84811015610f0657803586811115610eea5760008081fd5b610ef88c86838b0101610e0a565b845250918301918301610ed2565b5096505086013592505080821115610f1d57600080fd5b50610f2a85828601610e0a565b9150509250929050565b8215158152604060208201526000610f4f6040830184610cbe565b949350505050565b600060208284031215610f6957600080fd5b81358015158114610d1b57600080fd5b60008060408385031215610f8c57600080fd5b823567ffffffffffffffff80821115610fa457600080fd5b610fb086838701610e0a565b93506020850135915080821115610f1d57600080fd5b60006020808385031215610fd957600080fd5b823567ffffffffffffffff80821115610ff157600080fd5b818501915085601f83011261100557600080fd5b8135611013610e2982610da0565b81815260059190911b8301840190848101908883111561103257600080fd5b8585015b8381101561106a5780358581111561104e5760008081fd5b61105c8b89838a0101610e0a565b845250918601918601611036565b5098975050505050505050565b60006020828403121561108957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156110d2576110d2611090565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561111957600080fd5b815167ffffffffffffffff81111561113057600080fd5b8201601f8101841361114157600080fd5b805161114f610e2982610dc4565b81815285602083850101111561116457600080fd5b611175826020830160208601610c9a565b95945050505050565b6060815260006111916060830186610cbe565b82810360208401526111a38186610cbe565b905082810360408401526111b78185610cbe565b9695505050505050565b600181811c908216806111d557607f821691505b60208210810361120e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611289577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552611277868351610cbe565b9550938201939082019060010161123d565b5050858403818701525050506111758185610cbe565b60008083546112ad816111c1565b600182811680156112c557600181146112f857611327565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450611327565b8760005260208060002060005b8581101561131e5781548a820152908401908201611305565b50505082870194505b50929695505050505050565b60008154611340816111c1565b80855260206001838116801561135d5760018114611395576113c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b89010195506113c3565b866000528260002060005b858110156113bb5781548a82018601529083019084016113a0565b890184019650505b505050505092915050565b60a0815260006113e160a0830188611333565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015611453577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526114418383611333565b94860194925060019182019101611408565b50508681036040880152611467818b611333565b94505050505084606084015282810360808401526114858185610cbe565b98975050505050505050565b601f821115610a2f57600081815260208120601f850160051c810160208610156114b85750805b601f850160051c820191505b818110156114d7578281556001016114c4565b505050505050565b815167ffffffffffffffff8111156114f9576114f9610d22565b61150d8161150784546111c1565b84611491565b602080601f831160018114611560576000841561152a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556114d7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156115ad5788860151825594840194600190910190840161158e565b50858210156115e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b818103818111156110d2576110d261109056fea164736f6c6343000810000a307830303032386339313564366166306664363662626132643066633934303532323662636138643638303633333331323161376439383332313033643135363363", } var StreamsLookupUpkeepABI = StreamsLookupUpkeepMetaData.ABI @@ -661,9 +661,7 @@ type StreamsLookupUpkeepMercuryPerformEvent struct { Sender common.Address BlockNumber *big.Int V0 []byte - V1 []byte VerifiedV0 []byte - VerifiedV1 []byte Ed []byte Raw types.Log } @@ -749,7 +747,7 @@ func (_StreamsLookupUpkeep *StreamsLookupUpkeep) ParseLog(log types.Log) (genera } func (StreamsLookupUpkeepMercuryPerformEvent) Topic() common.Hash { - return common.HexToHash("0x1c85d6186f024e964616014c8247533455ec5129a5095711202292f8a7ea1d54") + return common.HexToHash("0xf0f72c0b235fc8687d6a67c02ca543473a3cef8a18b48490f10e475a8dda1390") } func (_StreamsLookupUpkeep *StreamsLookupUpkeep) Address() common.Address { diff --git a/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go index d88f15f96a2..a839e5d55d4 100644 --- a/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go +++ b/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go @@ -56,7 +56,7 @@ type Log struct { var VerifiableLoadLogTriggerUpkeepMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_useMercury\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmittedAgain\",\"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\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"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\"}],\"name\":\"batchPreparingUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"}],\"name\":\"batchPreparingUpkeepsSimple\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"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\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedAgainSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDsDeployedByThisContract\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getAllActiveUpkeepIDsOnRegistry\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"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\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"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\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepInfo\",\"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\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"name\":\"\",\"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\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"logNum\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"_log\",\"type\":\"uint8\"}],\"name\":\"setLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"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\"}],\"name\":\"updateLogTriggerConfig1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"updateLogTriggerConfig2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useMercury\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080527fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d60a0526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460e0526101c0604052604261014081815261010091829190620065b6610160398152602001604051806080016040528060428152602001620065f8604291399052620000be906016906002620003de565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000ee90826200055a565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b60208201526018906200012090826200055a565b503480156200012e57600080fd5b506040516200663a3803806200663a833981016040819052620001519162000652565b82823380600081620001aa5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001dd57620001dd8162000333565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200023a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200026091906200069e565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec9190620006cf565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560c052506019805461ffff191691151561ff00191691909117905550620006f69050565b336001600160a01b038216036200038d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620001a1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821562000429579160200282015b828111156200042957825182906200041890826200055a565b5091602001919060010190620003ff565b50620004379291506200043b565b5090565b80821115620004375760006200045282826200045c565b506001016200043b565b5080546200046a90620004cb565b6000825580601f106200047b575050565b601f0160209004906000526020600020908101906200049b91906200049e565b50565b5b808211156200043757600081556001016200049f565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004e057607f821691505b6020821081036200050157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200055557600081815260208120601f850160051c81016020861015620005305750805b601f850160051c820191505b8181101562000551578281556001016200053c565b5050505b505050565b81516001600160401b03811115620005765762000576620004b5565b6200058e81620005878454620004cb565b8462000507565b602080601f831160018114620005c65760008415620005ad5750858301515b600019600386901b1c1916600185901b17855562000551565b600085815260208120601f198616915b82811015620005f757888601518255948401946001909101908401620005d6565b5085821015620006165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200049b57600080fd5b805180151581146200064d57600080fd5b919050565b6000806000606084860312156200066857600080fd5b8351620006758162000626565b925062000685602085016200063c565b915062000695604085016200063c565b90509250925092565b60008060408385031215620006b257600080fd5b8251620006bf8162000626565b6020939093015192949293505050565b600060208284031215620006e257600080fd5b8151620006ef8162000626565b9392505050565b60805160a05160c05160e051615e5c6200075a600039600081816105b901526124af015260008181610a2d0152613ff00152600081816108a601528181611fa80152613a3e015260008181610dca01528181611f780152613a130152615e5c6000f3fe6080604052600436106105265760003560e01c80637b103999116102af578063af953a4a11610179578063daee1aeb116100d6578063e83ce5581161008a578063fa333dfb1161006f578063fa333dfb14611066578063fba7ffa314611119578063fcdc1f631461114657600080fd5b8063e83ce55814611027578063f2fde38b1461104657600080fd5b8063de818253116100bb578063de81825314610f90578063e0114adb14610fe4578063e45530831461101157600080fd5b8063daee1aeb14610f50578063dbef701e14610f7057600080fd5b8063c41c815b1161012d578063d4c2490011610112578063d4c2490014610ef0578063d6051a7214610f10578063da6cba4714610f3057600080fd5b8063c41c815b14610ec1578063c98f10b014610edb57600080fd5b8063b657bc9c1161015e578063b657bc9c14610e61578063becde0e114610e81578063c041982214610ea157600080fd5b8063af953a4a14610e2c578063afb28d1f14610e4c57600080fd5b8063948108f7116102275780639d385eaa116101db578063a6548248116101c0578063a654824814610db8578063a6b5947514610dec578063a72aa27e14610e0c57600080fd5b80639d385eaa14610d785780639d6f1cc714610d9857600080fd5b80639ac542eb1161020c5780639ac542eb14610cf05780639b42935414610d1a5780639b51fb0d14610d4757600080fd5b8063948108f714610cb057806396cebc7c14610cd057600080fd5b806386e330af1161027e5780638da5cb5b116102635780638da5cb5b14610c385780638fcb3fba14610c63578063924ca57814610c9057600080fd5b806386e330af14610bf8578063873c758614610c1857600080fd5b80637b10399914610b6b5780637e7a46dc14610b985780638243444a14610bb85780638340507c14610bd857600080fd5b806345d2ec17116103f057806360457ff51161036857806373644cce1161031c578063776898c811610301578063776898c814610b1657806379ba509714610b3657806379ea994314610b4b57600080fd5b806373644cce14610abc5780637672130314610ae957600080fd5b8063642f6cef1161034d578063642f6cef14610a1b57806369cdbadb14610a5f5780637145f11b14610a8c57600080fd5b806360457ff5146109c9578063636092e8146109f657600080fd5b80635147cd59116103bf57806357970e93116103a457806357970e93146109675780635d4ee7f3146109945780635f17e616146109a957600080fd5b80635147cd591461091557806351c98be31461094757600080fd5b806345d2ec1714610867578063469820931461089457806346e7a63e146108c85780634b56a42e146108f557600080fd5b806320e3dbd41161049e5780632b20e397116104525780633ebe8d6c116104375780633ebe8d6c146107f957806340691db4146108195780634585e33b1461084757600080fd5b80632b20e3971461077a578063328ffd11146107cc57600080fd5b806328c4b57b1161048357806328c4b57b1461070d57806329e0a8411461072d5780632a9032d31461075a57600080fd5b806320e3dbd4146106cd5780632636aecf146106ed57600080fd5b806319d97a94116104f55780631e010439116104da5780631e0104391461063b578063206c32e814610678578063207b6516146106ad57600080fd5b806319d97a94146105ee5780631cdde2511461061b57600080fd5b806306c1cc0014610532578063077ac621146105545780630b7d33e61461058757806312c55027146105a757600080fd5b3661052d57005b600080fd5b34801561053e57600080fd5b5061055261054d366004614772565b611173565b005b34801561056057600080fd5b5061057461056f366004614825565b6113c2565b6040519081526020015b60405180910390f35b34801561059357600080fd5b506105526105a236600461485a565b611400565b3480156105b357600080fd5b506105db7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161057e565b3480156105fa57600080fd5b5061060e6106093660046148a1565b61148e565b60405161057e9190614928565b34801561062757600080fd5b5061055261063636600461495d565b61154b565b34801561064757600080fd5b5061065b6106563660046148a1565b611688565b6040516bffffffffffffffffffffffff909116815260200161057e565b34801561068457600080fd5b506106986106933660046149c2565b61171d565b6040805192835260208301919091520161057e565b3480156106b957600080fd5b5061060e6106c83660046148a1565b6117a0565b3480156106d957600080fd5b506105526106e83660046149ee565b6117f8565b3480156106f957600080fd5b50610552610708366004614a50565b6119c2565b34801561071957600080fd5b50610574610728366004614aca565b611c8b565b34801561073957600080fd5b5061074d6107483660046148a1565b611cf6565b60405161057e9190614af6565b34801561076657600080fd5b50610552610775366004614c37565b611dfb565b34801561078657600080fd5b506011546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161057e565b3480156107d857600080fd5b506105746107e73660046148a1565b60036020526000908152604090205481565b34801561080557600080fd5b506105746108143660046148a1565b611edc565b34801561082557600080fd5b50610839610834366004614c79565b611f45565b60405161057e929190614cdc565b34801561085357600080fd5b50610552610862366004614d39565b6123a9565b34801561087357600080fd5b506108876108823660046149c2565b6125f8565b60405161057e9190614d6f565b3480156108a057600080fd5b506105747f000000000000000000000000000000000000000000000000000000000000000081565b3480156108d457600080fd5b506105746108e33660046148a1565b600a6020526000908152604090205481565b34801561090157600080fd5b50610839610910366004614dd7565b612667565b34801561092157600080fd5b506109356109303660046148a1565b6126bb565b60405160ff909116815260200161057e565b34801561095357600080fd5b50610552610962366004614e94565b61274f565b34801561097357600080fd5b506012546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b3480156109a057600080fd5b506105526127f3565b3480156109b557600080fd5b506105526109c4366004614eeb565b61292e565b3480156109d557600080fd5b506105746109e43660046148a1565b60076020526000908152604090205481565b348015610a0257600080fd5b5060155461065b906bffffffffffffffffffffffff1681565b348015610a2757600080fd5b50610a4f7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161057e565b348015610a6b57600080fd5b50610574610a7a3660046148a1565b60086020526000908152604090205481565b348015610a9857600080fd5b50610a4f610aa73660046148a1565b600b6020526000908152604090205460ff1681565b348015610ac857600080fd5b50610574610ad73660046148a1565b6000908152600c602052604090205490565b348015610af557600080fd5b50610574610b043660046148a1565b60046020526000908152604090205481565b348015610b2257600080fd5b50610a4f610b313660046148a1565b6129fb565b348015610b4257600080fd5b50610552612a4d565b348015610b5757600080fd5b506107a7610b663660046148a1565b612b4a565b348015610b7757600080fd5b506013546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b348015610ba457600080fd5b50610552610bb3366004614f0d565b612bde565b348015610bc457600080fd5b50610552610bd3366004614f0d565b612c6f565b348015610be457600080fd5b50610552610bf3366004614f59565b612cc9565b348015610c0457600080fd5b50610552610c13366004614fa6565b612ce7565b348015610c2457600080fd5b50610887610c33366004614eeb565b612cfa565b348015610c4457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166107a7565b348015610c6f57600080fd5b50610574610c7e3660046148a1565b60056020526000908152604090205481565b348015610c9c57600080fd5b50610552610cab366004614eeb565b612db7565b348015610cbc57600080fd5b50610552610ccb366004615057565b612ffc565b348015610cdc57600080fd5b50610552610ceb366004615087565b613114565b348015610cfc57600080fd5b50601554610935906c01000000000000000000000000900460ff1681565b348015610d2657600080fd5b50610552610d35366004614eeb565b60009182526009602052604090912055565b348015610d5357600080fd5b506105db610d623660046148a1565b600e6020526000908152604090205461ffff1681565b348015610d8457600080fd5b50610887610d933660046148a1565b61331e565b348015610da457600080fd5b5061060e610db33660046148a1565b613380565b348015610dc457600080fd5b506105747f000000000000000000000000000000000000000000000000000000000000000081565b348015610df857600080fd5b50610552610e07366004614aca565b61342c565b348015610e1857600080fd5b50610552610e273660046150a4565b613495565b348015610e3857600080fd5b50610552610e473660046148a1565b613540565b348015610e5857600080fd5b5061060e6135c6565b348015610e6d57600080fd5b5061065b610e7c3660046148a1565b6135d3565b348015610e8d57600080fd5b50610552610e9c366004614c37565b61362b565b348015610ead57600080fd5b50610887610ebc366004614eeb565b6136c5565b348015610ecd57600080fd5b50601954610a4f9060ff1681565b348015610ee757600080fd5b5061060e6137c2565b348015610efc57600080fd5b50610552610f0b3660046150c9565b6137cf565b348015610f1c57600080fd5b50610698610f2b366004614eeb565b61384e565b348015610f3c57600080fd5b50610552610f4b3660046150ee565b6138b7565b348015610f5c57600080fd5b50610552610f6b366004614c37565b613c1e565b348015610f7c57600080fd5b50610574610f8b366004614eeb565b613ce9565b348015610f9c57600080fd5b50610552610fab366004615087565b6019805460ff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b348015610ff057600080fd5b50610574610fff3660046148a1565b60096020526000908152604090205481565b34801561101d57600080fd5b5061057460145481565b34801561103357600080fd5b5060195461093590610100900460ff1681565b34801561105257600080fd5b506105526110613660046149ee565b613d1a565b34801561107257600080fd5b5061060e611081366004615156565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b34801561112557600080fd5b506105746111343660046148a1565b60066020526000908152604090205481565b34801561115257600080fd5b506105746111613660046148a1565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690611259908c16886151de565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af11580156112d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fb9190615222565b5060008860ff1667ffffffffffffffff81111561131a5761131a614614565b604051908082528060200260200182016040528015611343578160200160208202803683370190505b50905060005b8960ff168160ff1610156113b657600061136284613d2e565b905080838360ff168151811061137a5761137a61523d565b602090810291909101810191909152600091825260088152604080832088905560079091529020849055806113ae8161526c565b915050611349565b50505050505050505050565b600d60205282600052604060002060205281600052604060002081815481106113ea57600080fd5b9060005260206000200160009250925050505481565b6013546040517f0b7d33e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690630b7d33e690611458908590859060040161528b565b600060405180830381600087803b15801561147257600080fd5b505af1158015611486573d6000803e3d6000fd5b505050505050565b6013546040517f19d97a940000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff16906319d97a94906024015b600060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261154591908101906152f1565b92915050565b6013546040517ffa333dfb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015260ff8816602483015260448201879052606482018690526084820185905260a4820184905290911690634ee88d35908990309063fa333dfb9060c401600060405180830381865afa1580156115ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261163091908101906152f1565b6040518363ffffffff1660e01b815260040161164d92919061528b565b600060405180830381600087803b15801561166757600080fd5b505af115801561167b573d6000803e3d6000fd5b5050505050505050505050565b6013546040517f1e0104390000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690631e010439906024015b602060405180830381865afa1580156116f9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190615331565b6000828152600d6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561178157602002820191906000526020600020905b81548152602001906001019080831161176d575b50505050509050611793818251613dfc565b92509250505b9250929050565b6013546040517f207b65160000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063207b6516906024016114e2565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa15801561188e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b29190615359565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015611955573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119799190615387565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b8560005b81811015611c805760008989838181106119e2576119e261523d565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001611a1b91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611a4792919061528b565b600060405180830381600087803b158015611a6157600080fd5b505af1158015611a75573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015611aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0f91906153a4565b90508060ff16600103611c6b576040517ffa333dfb000000000000000000000000000000000000000000000000000000008152306004820181905260ff8b166024830152604482018a9052606482018890526084820188905260a4820187905260009163fa333dfb9060c401600060405180830381865afa158015611b98573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bde91908101906152f1565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590611c37908690859060040161528b565b600060405180830381600087803b158015611c5157600080fd5b505af1158015611c65573d6000803e3d6000fd5b50505050505b50508080611c78906153c1565b9150506119c6565b505050505050505050565b6000838152600c602090815260408083208054825181850281018501909352808352611cec93830182828015611ce057602002820191906000526020600020905b815481526020019060010190808311611ccc575b50505050508484613e81565b90505b9392505050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c7c3a19a90602401600060405180830381865afa158015611db5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611545919081019061541c565b8060005b818160ff161015611ed65760135473ffffffffffffffffffffffffffffffffffffffff1663c8048022858560ff8516818110611e3d57611e3d61523d565b905060200201356040518263ffffffff1660e01b8152600401611e6291815260200190565b600060405180830381600087803b158015611e7c57600080fd5b505af1158015611e90573d6000803e3d6000fd5b50505050611ec384848360ff16818110611eac57611eac61523d565b90506020020135600f613fe090919063ffffffff16565b5080611ece8161526c565b915050611dff565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611f3d576000858152600d6020908152604080832061ffff85168452909152902054611f29908361553b565b915080611f358161554e565b915050611ef2565b509392505050565b6000606060005a90506000611f58613fec565b9050600085806020019051810190611f70919061556f565b6019549091507f000000000000000000000000000000000000000000000000000000000000000090610100900460ff1615611fc857507f00000000000000000000000000000000000000000000000000000000000000005b80611fd660c08a018a615588565b6000818110611fe757611fe761523d565b905060200201350361234757600061200260c08a018a615588565b60018181106120135761201361523d565b9050602002013560405160200161202c91815260200190565b6040516020818303038152906040529050600081806020019051810190612053919061556f565b90508381146120c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f75706b6565702069647320646f6e2774206d617463680000000000000000000060448201526064015b60405180910390fd5b60006120d260c08c018c615588565b60028181106120e3576120e361523d565b905060200201356040516020016120fc91815260200190565b6040516020818303038152906040529050600081806020019051810190612123919061556f565b9050600061213460c08e018e615588565b60038181106121455761214561523d565b9050602002013560405160200161215e91815260200190565b60405160208183030381529060405290506000818060200190518101906121859190615387565b6000868152600860205260409020549091505b805a6121a4908d6155f0565b6121b090613a9861553b565b10156121f15783406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612198565b60195460ff161561229957604080516020810188905290810185905273ffffffffffffffffffffffffffffffffffffffff831660608201526017906016906018908790608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527ff055e4a20000000000000000000000000000000000000000000000000000000082526120ba95949392916004016156f1565b60408051600280825260608201909252600091816020015b60608152602001906001900390816122b15790505060408051602081018a905290810187905273ffffffffffffffffffffffffffffffffffffffff851660608201529091506000906080016040516020818303038152906040529050600182826040516020016123229291906157b4565b6040516020818303038152906040529e509e5050505050505050505050505050611799565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f756e6578706563746564206576656e742073696700000000000000000000000060448201526064016120ba565b60005a90506000806123bd84860186614dd7565b915091506000806000838060200190518101906123da9190615848565b6000838152600560209081526040808320546004909252822054949750929550909350909190612408613fec565b90508260000361242857600086815260056020526040902081905561256c565b600061243486836155f0565b6000888152600e6020908152604080832054600d835281842061ffff9091168085529083528184208054835181860281018601909452808452959650909491929091908301828280156124a657602002820191906000526020600020905b815481526020019060010190808311612492575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff1681510361252157816124e38161554e565b60008b8152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000888152600d6020908152604080832061ffff9094168352928152828220805460018181018355918452828420018590558a8352600c8252928220805493840181558252902001555b60008681526006602052604081205461258690600161553b565b60008881526006602090815260408083208490556004909152902083905590506125b08783612db7565b6040513090839089907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a46125ea878b8461342c565b505050505050505050505050565b6000828152600d6020908152604080832061ffff8516845282529182902080548351818402810184019094528084526060939283018282801561265a57602002820191906000526020600020905b815481526020019060010190808311612646575b5050505050905092915050565b60006060600084846040516020016126809291906157b4565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b6013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690635147cd5990602401602060405180830381865afa15801561272b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154591906153a4565b8160005b818110156127ec5730635f17e6168686848181106127735761277361523d565b90506020020135856040518363ffffffff1660e01b81526004016127a792919091825263ffffffff16602082015260400190565b600060405180830381600087803b1580156127c157600080fd5b505af11580156127d5573d6000803e3d6000fd5b5050505080806127e4906153c1565b915050612753565b5050505050565b6127fb61408e565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561286a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061288e919061556f565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015612906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061292a9190615222565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c909152812061296691614513565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff16116129c2576000848152600d6020908152604080832061ffff8516845290915281206129b091614513565b806129ba8161554e565b91505061297b565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000818152600560205260408120548103612a1857506001919050565b600082815260036020908152604080832054600490925290912054612a3b613fec565b612a4591906155f0565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016120ba565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517f79ea99430000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff16906379ea994390602401602060405180830381865afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190615387565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b590612c3890869086908690600401615876565b600060405180830381600087803b158015612c5257600080fd5b505af1158015612c66573d6000803e3d6000fd5b50505050505050565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634ee88d3590612c3890869086908690600401615876565b6017612cd58382615910565b506018612ce28282615910565b505050565b805161292a906016906020840190614531565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260609173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612d71573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611cef9190810190615a2a565b601454600083815260026020526040902054612dd390836155f0565b111561292a576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612e49573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612e8f919081019061541c565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa158015612f04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f289190615331565b601554909150612f4c9082906c01000000000000000000000000900460ff166151de565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611ed657601554612f8f9085906bffffffffffffffffffffffff16612ffc565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af1158015613084573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a89190615222565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401611458565b6040517fc04198220000000000000000000000000000000000000000000000000000000081526000600482018190526024820181905290309063c041982290604401600060405180830381865afa158015613173573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526131b99190810190615a2a565b805190915060006131c8613fec565b905060005b828110156127ec5760008482815181106131e9576131e961523d565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015613269573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061328d91906153a4565b90508060ff16600103613309578660ff166000036132d9576040513090859084907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4613309565b6040513090859084907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a45b50508080613316906153c1565b9150506131cd565b6000818152600c602090815260409182902080548351818402810184019094528084526060939283018282801561337457602002820191906000526020600020905b815481526020019060010190808311613360575b50505050509050919050565b6016818154811061339057600080fd5b9060005260206000200160009150905080546133ab90615603565b80601f01602080910402602001604051908101604052809291908181526020018280546133d790615603565b80156134245780601f106133f957610100808354040283529160200191613424565b820191906000526020600020905b81548152906001019060200180831161340757829003601f168201915b505050505081565b6000838152600760205260409020545b805a61344890856155f0565b6134549061271061553b565b1015611ed65781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905561343c565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b15801561350d57600080fd5b505af1158015613521573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b1580156135b257600080fd5b505af11580156127ec573d6000803e3d6000fd5b601780546133ab90615603565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff169063b657bc9c906024016116dc565b8060005b818163ffffffff161015611ed6573063af953a4a858563ffffffff851681811061365b5761365b61523d565b905060200201356040518263ffffffff1660e01b815260040161368091815260200190565b600060405180830381600087803b15801561369a57600080fd5b505af11580156136ae573d6000803e3d6000fd5b5050505080806136bd90615abb565b91505061362f565b606060006136d3600f614111565b905080841061370e576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036137235761372084826155f0565b92505b60008367ffffffffffffffff81111561373e5761373e614614565b604051908082528060200260200182016040528015613767578160200160208202803683370190505b50905060005b848110156137b95761378a613782828861553b565b600f9061411b565b82828151811061379c5761379c61523d565b6020908102919091010152806137b1816153c1565b91505061376d565b50949350505050565b601880546133ab90615603565b60006137d9613fec565b90508160ff1660000361381a576040513090829085907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4505050565b6040513090829085907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a4505050565b6000828152600c602090815260408083208054825181850281018501909352808352849384939291908301828280156138a657602002820191906000526020600020905b815481526020019060010190808311613892575b505050505090506117938185613dfc565b8260005b818110156114865760008686838181106138d7576138d761523d565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161391091815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161393c92919061528b565b600060405180830381600087803b15801561395657600080fd5b505af115801561396a573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa1580156139e0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a0491906153a4565b90508060ff16600103613c09577f000000000000000000000000000000000000000000000000000000000000000060ff871615613a5e57507f00000000000000000000000000000000000000000000000000000000000000005b60003073ffffffffffffffffffffffffffffffffffffffff1663fa333dfb30898588604051602001613a9291815260200190565b604051602081830303815290604052613aaa90615ad4565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff909416600485015260ff90921660248401526044830152606482015260006084820181905260a482015260c401600060405180830381865afa158015613b35573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052613b7b91908101906152f1565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590613bd4908790859060040161528b565b600060405180830381600087803b158015613bee57600080fd5b505af1158015613c02573d6000803e3d6000fd5b5050505050505b50508080613c16906153c1565b9150506138bb565b8060005b81811015611ed6576000848483818110613c3e57613c3e61523d565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001613c7791815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401613ca392919061528b565b600060405180830381600087803b158015613cbd57600080fd5b505af1158015613cd1573d6000803e3d6000fd5b50505050508080613ce1906153c1565b915050613c22565b600c6020528160005260406000208181548110613d0557600080fd5b90600052602060002001600091509150505481565b613d2261408e565b613d2b81614127565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190613d89908690600401615b16565b6020604051808303816000875af1158015613da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dcc919061556f565b9050613dd9600f8261421c565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b815160009081908190841580613e125750808510155b15613e1b578094505b60008092505b85831015613e7757866001613e3685856155f0565b613e4091906155f0565b81518110613e5057613e5061523d565b602002602001015181613e63919061553b565b905082613e6f816153c1565b935050613e21565b9694955050505050565b82516000908190831580613e955750808410155b15613e9e578093505b60008467ffffffffffffffff811115613eb957613eb9614614565b604051908082528060200260200182016040528015613ee2578160200160208202803683370190505b509050600092505b84831015613f5057866001613eff85856155f0565b613f0991906155f0565b81518110613f1957613f1961523d565b6020026020010151818481518110613f3357613f3361523d565b602090810291909101015282613f48816153c1565b935050613eea565b613f6981600060018451613f6491906155f0565b614228565b85606403613fa2578060018251613f8091906155f0565b81518110613f9057613f9061523d565b60200260200101519350505050611cef565b806064825188613fb29190615c68565b613fbc9190615cd4565b81518110613fcc57613fcc61523d565b602002602001015193505050509392505050565b6000611cef83836143a0565b60007f00000000000000000000000000000000000000000000000000000000000000001561408957606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614060573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614084919061556f565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff16331461410f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016120ba565b565b6000611545825490565b6000611cef838361449a565b3373ffffffffffffffffffffffffffffffffffffffff8216036141a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016120ba565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611cef83836144c4565b8181808203614238575050505050565b60008560026142478787615ce8565b6142519190615d08565b61425b9087615d70565b8151811061426b5761426b61523d565b602002602001015190505b81831361437a575b808684815181106142915761429161523d565b602002602001015110156142b157826142a981615d98565b93505061427e565b8582815181106142c3576142c361523d565b60200260200101518110156142e457816142dc81615dc9565b9250506142b1565b818313614375578582815181106142fd576142fd61523d565b60200260200101518684815181106143175761431761523d565b60200260200101518785815181106143315761433161523d565b6020026020010188858151811061434a5761434a61523d565b6020908102919091010191909152528261436381615d98565b935050818061437190615dc9565b9250505b614276565b8185121561438d5761438d868684614228565b8383121561148657611486868486614228565b600081815260018301602052604081205480156144895760006143c46001836155f0565b85549091506000906143d8906001906155f0565b905081811461443d5760008660000182815481106143f8576143f861523d565b906000526020600020015490508087600001848154811061441b5761441b61523d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061444e5761444e615e20565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611545565b6000915050611545565b5092915050565b60008260000182815481106144b1576144b161523d565b9060005260206000200154905092915050565b600081815260018301602052604081205461450b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611545565b506000611545565b5080546000825590600052602060002090810190613d2b9190614587565b828054828255906000526020600020908101928215614577579160200282015b8281111561457757825182906145679082615910565b5091602001919060010190614551565b5061458392915061459c565b5090565b5b808211156145835760008155600101614588565b808211156145835760006145b082826145b9565b5060010161459c565b5080546145c590615603565b6000825580601f106145d5575050565b601f016020900490600052602060002090810190613d2b9190614587565b60ff81168114613d2b57600080fd5b63ffffffff81168114613d2b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561466757614667614614565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156146b4576146b4614614565b604052919050565b600067ffffffffffffffff8211156146d6576146d6614614565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261471357600080fd5b8135614726614721826146bc565b61466d565b81815284602083860101111561473b57600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff81168114613d2b57600080fd5b600080600080600080600060e0888a03121561478d57600080fd5b8735614798816145f3565b965060208801356147a881614602565b955060408801356147b8816145f3565b9450606088013567ffffffffffffffff8111156147d457600080fd5b6147e08a828b01614702565b94505060808801356147f181614758565b9699959850939692959460a0840135945060c09093013592915050565b803561ffff8116811461482057600080fd5b919050565b60008060006060848603121561483a57600080fd5b8335925061484a6020850161480e565b9150604084013590509250925092565b6000806040838503121561486d57600080fd5b82359150602083013567ffffffffffffffff81111561488b57600080fd5b61489785828601614702565b9150509250929050565b6000602082840312156148b357600080fd5b5035919050565b60005b838110156148d55781810151838201526020016148bd565b50506000910152565b600081518084526148f68160208601602086016148ba565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cef60208301846148de565b73ffffffffffffffffffffffffffffffffffffffff81168114613d2b57600080fd5b600080600080600080600060e0888a03121561497857600080fd5b87359650602088013561498a8161493b565b9550604088013561499a816145f3565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080604083850312156149d557600080fd5b823591506149e56020840161480e565b90509250929050565b600060208284031215614a0057600080fd5b8135611cef8161493b565b60008083601f840112614a1d57600080fd5b50813567ffffffffffffffff811115614a3557600080fd5b6020830191508360208260051b850101111561179957600080fd5b600080600080600080600060c0888a031215614a6b57600080fd5b873567ffffffffffffffff811115614a8257600080fd5b614a8e8a828b01614a0b565b9098509650506020880135614aa2816145f3565b96999598509596604081013596506060810135956080820135955060a0909101359350915050565b600080600060608486031215614adf57600080fd5b505081359360208301359350604090920135919050565b60208152614b1d60208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614b36604084018263ffffffff169052565b506040830151610140806060850152614b536101608501836148de565b91506060850151614b7460808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614be0818701836bffffffffffffffffffffffff169052565b8601519050610120614bf58682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001838701529050614c2d83826148de565b9695505050505050565b60008060208385031215614c4a57600080fd5b823567ffffffffffffffff811115614c6157600080fd5b614c6d85828601614a0b565b90969095509350505050565b60008060408385031215614c8c57600080fd5b823567ffffffffffffffff80821115614ca457600080fd5b908401906101008287031215614cb957600080fd5b90925060208401359080821115614ccf57600080fd5b5061489785828601614702565b8215158152604060208201526000611cec60408301846148de565b60008083601f840112614d0957600080fd5b50813567ffffffffffffffff811115614d2157600080fd5b60208301915083602082850101111561179957600080fd5b60008060208385031215614d4c57600080fd5b823567ffffffffffffffff811115614d6357600080fd5b614c6d85828601614cf7565b6020808252825182820181905260009190848201906040850190845b81811015614da757835183529284019291840191600101614d8b565b50909695505050505050565b600067ffffffffffffffff821115614dcd57614dcd614614565b5060051b60200190565b60008060408385031215614dea57600080fd5b823567ffffffffffffffff80821115614e0257600080fd5b818501915085601f830112614e1657600080fd5b81356020614e2661472183614db3565b82815260059290921b84018101918181019089841115614e4557600080fd5b8286015b84811015614e7d57803586811115614e615760008081fd5b614e6f8c86838b0101614702565b845250918301918301614e49565b5096505086013592505080821115614ccf57600080fd5b600080600060408486031215614ea957600080fd5b833567ffffffffffffffff811115614ec057600080fd5b614ecc86828701614a0b565b9094509250506020840135614ee081614602565b809150509250925092565b60008060408385031215614efe57600080fd5b50508035926020909101359150565b600080600060408486031215614f2257600080fd5b83359250602084013567ffffffffffffffff811115614f4057600080fd5b614f4c86828701614cf7565b9497909650939450505050565b60008060408385031215614f6c57600080fd5b823567ffffffffffffffff80821115614f8457600080fd5b614f9086838701614702565b93506020850135915080821115614ccf57600080fd5b60006020808385031215614fb957600080fd5b823567ffffffffffffffff80821115614fd157600080fd5b818501915085601f830112614fe557600080fd5b8135614ff361472182614db3565b81815260059190911b8301840190848101908883111561501257600080fd5b8585015b8381101561504a5780358581111561502e5760008081fd5b61503c8b89838a0101614702565b845250918601918601615016565b5098975050505050505050565b6000806040838503121561506a57600080fd5b82359150602083013561507c81614758565b809150509250929050565b60006020828403121561509957600080fd5b8135611cef816145f3565b600080604083850312156150b757600080fd5b82359150602083013561507c81614602565b600080604083850312156150dc57600080fd5b82359150602083013561507c816145f3565b6000806000806060858703121561510457600080fd5b843567ffffffffffffffff81111561511b57600080fd5b61512787828801614a0b565b909550935050602085013561513b816145f3565b9150604085013561514b816145f3565b939692955090935050565b60008060008060008060c0878903121561516f57600080fd5b863561517a8161493b565b9550602087013561518a816145f3565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80831681851681830481118215151615615209576152096151af565b02949350505050565b8051801515811461482057600080fd5b60006020828403121561523457600080fd5b611cef82615212565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103615282576152826151af565b60010192915050565b828152604060208201526000611cec60408301846148de565b600082601f8301126152b557600080fd5b81516152c3614721826146bc565b8181528460208386010111156152d857600080fd5b6152e98260208301602087016148ba565b949350505050565b60006020828403121561530357600080fd5b815167ffffffffffffffff81111561531a57600080fd5b6152e9848285016152a4565b805161482081614758565b60006020828403121561534357600080fd5b8151611cef81614758565b80516148208161493b565b6000806040838503121561536c57600080fd5b82516153778161493b565b6020939093015192949293505050565b60006020828403121561539957600080fd5b8151611cef8161493b565b6000602082840312156153b657600080fd5b8151611cef816145f3565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153f2576153f26151af565b5060010190565b805161482081614602565b805167ffffffffffffffff8116811461482057600080fd5b60006020828403121561542e57600080fd5b815167ffffffffffffffff8082111561544657600080fd5b90830190610140828603121561545b57600080fd5b615463614643565b61546c8361534e565b815261547a602084016153f9565b602082015260408301518281111561549157600080fd5b61549d878286016152a4565b6040830152506154af60608401615326565b60608201526154c06080840161534e565b60808201526154d160a08401615404565b60a08201526154e260c084016153f9565b60c08201526154f360e08401615326565b60e0820152610100615506818501615212565b90820152610120838101518381111561551e57600080fd5b61552a888287016152a4565b918301919091525095945050505050565b80820180821115611545576115456151af565b600061ffff808316818103615565576155656151af565b6001019392505050565b60006020828403121561558157600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155bd57600080fd5b83018035915067ffffffffffffffff8211156155d857600080fd5b6020019150600581901b360382131561179957600080fd5b81810381811115611545576115456151af565b600181811c9082168061561757607f821691505b602082108103615650577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000815461566381615603565b80855260206001838116801561568057600181146156b8576156e6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b89010195506156e6565b866000528260002060005b858110156156de5781548a82018601529083019084016156c3565b890184019650505b505050505092915050565b60a08152600061570460a0830188615656565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015615776577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526157648383615656565b9486019492506001918201910161572b565b5050868103604088015261578a818b615656565b94505050505084606084015282810360808401526157a881856148de565b98975050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015615829577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08887030185526158178683516148de565b955093820193908201906001016157dd565b50508584038187015250505061583f81856148de565b95945050505050565b60008060006060848603121561585d57600080fd5b83519250602084015191506040840151614ee08161493b565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b601f821115612ce257600081815260208120601f850160051c810160208610156158f15750805b601f850160051c820191505b81811015611486578281556001016158fd565b815167ffffffffffffffff81111561592a5761592a614614565b61593e816159388454615603565b846158ca565b602080601f831160018114615991576000841561595b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611486565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156159de578886015182559484019460019091019084016159bf565b5085821015615a1a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808385031215615a3d57600080fd5b825167ffffffffffffffff811115615a5457600080fd5b8301601f81018513615a6557600080fd5b8051615a7361472182614db3565b81815260059190911b82018301908381019087831115615a9257600080fd5b928401925b82841015615ab057835182529284019290840190615a97565b979650505050505050565b600063ffffffff808316818103615565576155656151af565b80516020808301519190811015615650577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b6020815260008251610140806020850152615b356101608501836148de565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080868503016040870152615b7184836148de565b935060408701519150615b9c606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e0870152615bfd84836148de565b935060e08701519150610100818786030181880152615c1c85846148de565b945080880151925050610120818786030181880152615c3b85846148de565b94508088015192505050615c5e828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ca057615ca06151af565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ce357615ce3615ca5565b500490565b8181036000831280158383131683831282161715614493576144936151af565b600082615d1757615d17615ca5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d6b57615d6b6151af565b500590565b8082018281126000831280158216821582161715615d9057615d906151af565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153f2576153f26151af565b60007f80000000000000000000000000000000000000000000000000000000000000008203615dfa57615dfa6151af565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", + Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080527fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d60a0526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460e0526101c0604052604261014081815261010091829190620066ec6101603981526020016040518060800160405280604281526020016200672e604291399052620000be906016906002620003de565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000ee90826200055a565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b60208201526018906200012090826200055a565b503480156200012e57600080fd5b506040516200677038038062006770833981016040819052620001519162000652565b82823380600081620001aa5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001dd57620001dd8162000333565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200023a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200026091906200069e565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec9190620006cf565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560c052506019805461ffff191691151561ff00191691909117905550620006f69050565b336001600160a01b038216036200038d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620001a1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821562000429579160200282015b828111156200042957825182906200041890826200055a565b5091602001919060010190620003ff565b50620004379291506200043b565b5090565b80821115620004375760006200045282826200045c565b506001016200043b565b5080546200046a90620004cb565b6000825580601f106200047b575050565b601f0160209004906000526020600020908101906200049b91906200049e565b50565b5b808211156200043757600081556001016200049f565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004e057607f821691505b6020821081036200050157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200055557600081815260208120601f850160051c81016020861015620005305750805b601f850160051c820191505b8181101562000551578281556001016200053c565b5050505b505050565b81516001600160401b03811115620005765762000576620004b5565b6200058e81620005878454620004cb565b8462000507565b602080601f831160018114620005c65760008415620005ad5750858301515b600019600386901b1c1916600185901b17855562000551565b600085815260208120601f198616915b82811015620005f757888601518255948401946001909101908401620005d6565b5085821015620006165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200049b57600080fd5b805180151581146200064d57600080fd5b919050565b6000806000606084860312156200066857600080fd5b8351620006758162000626565b925062000685602085016200063c565b915062000695604085016200063c565b90509250925092565b60008060408385031215620006b257600080fd5b8251620006bf8162000626565b6020939093015192949293505050565b600060208284031215620006e257600080fd5b8151620006ef8162000626565b9392505050565b60805160a05160c05160e051615f926200075a600039600081816105b90152612551015260008181610a2d01526140920152600081816108a601528181611fa80152613ae0015260008181610dca01528181611f780152613ab50152615f926000f3fe6080604052600436106105265760003560e01c80637b103999116102af578063af953a4a11610179578063daee1aeb116100d6578063e83ce5581161008a578063fa333dfb1161006f578063fa333dfb14611066578063fba7ffa314611119578063fcdc1f631461114657600080fd5b8063e83ce55814611027578063f2fde38b1461104657600080fd5b8063de818253116100bb578063de81825314610f90578063e0114adb14610fe4578063e45530831461101157600080fd5b8063daee1aeb14610f50578063dbef701e14610f7057600080fd5b8063c41c815b1161012d578063d4c2490011610112578063d4c2490014610ef0578063d6051a7214610f10578063da6cba4714610f3057600080fd5b8063c41c815b14610ec1578063c98f10b014610edb57600080fd5b8063b657bc9c1161015e578063b657bc9c14610e61578063becde0e114610e81578063c041982214610ea157600080fd5b8063af953a4a14610e2c578063afb28d1f14610e4c57600080fd5b8063948108f7116102275780639d385eaa116101db578063a6548248116101c0578063a654824814610db8578063a6b5947514610dec578063a72aa27e14610e0c57600080fd5b80639d385eaa14610d785780639d6f1cc714610d9857600080fd5b80639ac542eb1161020c5780639ac542eb14610cf05780639b42935414610d1a5780639b51fb0d14610d4757600080fd5b8063948108f714610cb057806396cebc7c14610cd057600080fd5b806386e330af1161027e5780638da5cb5b116102635780638da5cb5b14610c385780638fcb3fba14610c63578063924ca57814610c9057600080fd5b806386e330af14610bf8578063873c758614610c1857600080fd5b80637b10399914610b6b5780637e7a46dc14610b985780638243444a14610bb85780638340507c14610bd857600080fd5b806345d2ec17116103f057806360457ff51161036857806373644cce1161031c578063776898c811610301578063776898c814610b1657806379ba509714610b3657806379ea994314610b4b57600080fd5b806373644cce14610abc5780637672130314610ae957600080fd5b8063642f6cef1161034d578063642f6cef14610a1b57806369cdbadb14610a5f5780637145f11b14610a8c57600080fd5b806360457ff5146109c9578063636092e8146109f657600080fd5b80635147cd59116103bf57806357970e93116103a457806357970e93146109675780635d4ee7f3146109945780635f17e616146109a957600080fd5b80635147cd591461091557806351c98be31461094757600080fd5b806345d2ec1714610867578063469820931461089457806346e7a63e146108c85780634b56a42e146108f557600080fd5b806320e3dbd41161049e5780632b20e397116104525780633ebe8d6c116104375780633ebe8d6c146107f957806340691db4146108195780634585e33b1461084757600080fd5b80632b20e3971461077a578063328ffd11146107cc57600080fd5b806328c4b57b1161048357806328c4b57b1461070d57806329e0a8411461072d5780632a9032d31461075a57600080fd5b806320e3dbd4146106cd5780632636aecf146106ed57600080fd5b806319d97a94116104f55780631e010439116104da5780631e0104391461063b578063206c32e814610678578063207b6516146106ad57600080fd5b806319d97a94146105ee5780631cdde2511461061b57600080fd5b806306c1cc0014610532578063077ac621146105545780630b7d33e61461058757806312c55027146105a757600080fd5b3661052d57005b600080fd5b34801561053e57600080fd5b5061055261054d366004614814565b611173565b005b34801561056057600080fd5b5061057461056f3660046148c7565b6113c2565b6040519081526020015b60405180910390f35b34801561059357600080fd5b506105526105a23660046148fc565b611400565b3480156105b357600080fd5b506105db7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161057e565b3480156105fa57600080fd5b5061060e610609366004614943565b61148e565b60405161057e91906149ca565b34801561062757600080fd5b506105526106363660046149ff565b61154b565b34801561064757600080fd5b5061065b610656366004614943565b611688565b6040516bffffffffffffffffffffffff909116815260200161057e565b34801561068457600080fd5b50610698610693366004614a64565b61171d565b6040805192835260208301919091520161057e565b3480156106b957600080fd5b5061060e6106c8366004614943565b6117a0565b3480156106d957600080fd5b506105526106e8366004614a90565b6117f8565b3480156106f957600080fd5b50610552610708366004614af2565b6119c2565b34801561071957600080fd5b50610574610728366004614b6c565b611c8b565b34801561073957600080fd5b5061074d610748366004614943565b611cf6565b60405161057e9190614b98565b34801561076657600080fd5b50610552610775366004614cd9565b611dfb565b34801561078657600080fd5b506011546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161057e565b3480156107d857600080fd5b506105746107e7366004614943565b60036020526000908152604090205481565b34801561080557600080fd5b50610574610814366004614943565b611edc565b34801561082557600080fd5b50610839610834366004614d1b565b611f45565b60405161057e929190614d7e565b34801561085357600080fd5b50610552610862366004614ddb565b61244b565b34801561087357600080fd5b50610887610882366004614a64565b61269a565b60405161057e9190614e11565b3480156108a057600080fd5b506105747f000000000000000000000000000000000000000000000000000000000000000081565b3480156108d457600080fd5b506105746108e3366004614943565b600a6020526000908152604090205481565b34801561090157600080fd5b50610839610910366004614e79565b612709565b34801561092157600080fd5b50610935610930366004614943565b61275d565b60405160ff909116815260200161057e565b34801561095357600080fd5b50610552610962366004614f36565b6127f1565b34801561097357600080fd5b506012546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b3480156109a057600080fd5b50610552612895565b3480156109b557600080fd5b506105526109c4366004614f8d565b6129d0565b3480156109d557600080fd5b506105746109e4366004614943565b60076020526000908152604090205481565b348015610a0257600080fd5b5060155461065b906bffffffffffffffffffffffff1681565b348015610a2757600080fd5b50610a4f7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161057e565b348015610a6b57600080fd5b50610574610a7a366004614943565b60086020526000908152604090205481565b348015610a9857600080fd5b50610a4f610aa7366004614943565b600b6020526000908152604090205460ff1681565b348015610ac857600080fd5b50610574610ad7366004614943565b6000908152600c602052604090205490565b348015610af557600080fd5b50610574610b04366004614943565b60046020526000908152604090205481565b348015610b2257600080fd5b50610a4f610b31366004614943565b612a9d565b348015610b4257600080fd5b50610552612aef565b348015610b5757600080fd5b506107a7610b66366004614943565b612bec565b348015610b7757600080fd5b506013546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b348015610ba457600080fd5b50610552610bb3366004614faf565b612c80565b348015610bc457600080fd5b50610552610bd3366004614faf565b612d11565b348015610be457600080fd5b50610552610bf3366004614ffb565b612d6b565b348015610c0457600080fd5b50610552610c13366004615048565b612d89565b348015610c2457600080fd5b50610887610c33366004614f8d565b612d9c565b348015610c4457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166107a7565b348015610c6f57600080fd5b50610574610c7e366004614943565b60056020526000908152604090205481565b348015610c9c57600080fd5b50610552610cab366004614f8d565b612e59565b348015610cbc57600080fd5b50610552610ccb3660046150f9565b61309e565b348015610cdc57600080fd5b50610552610ceb366004615129565b6131b6565b348015610cfc57600080fd5b50601554610935906c01000000000000000000000000900460ff1681565b348015610d2657600080fd5b50610552610d35366004614f8d565b60009182526009602052604090912055565b348015610d5357600080fd5b506105db610d62366004614943565b600e6020526000908152604090205461ffff1681565b348015610d8457600080fd5b50610887610d93366004614943565b6133c0565b348015610da457600080fd5b5061060e610db3366004614943565b613422565b348015610dc457600080fd5b506105747f000000000000000000000000000000000000000000000000000000000000000081565b348015610df857600080fd5b50610552610e07366004614b6c565b6134ce565b348015610e1857600080fd5b50610552610e27366004615146565b613537565b348015610e3857600080fd5b50610552610e47366004614943565b6135e2565b348015610e5857600080fd5b5061060e613668565b348015610e6d57600080fd5b5061065b610e7c366004614943565b613675565b348015610e8d57600080fd5b50610552610e9c366004614cd9565b6136cd565b348015610ead57600080fd5b50610887610ebc366004614f8d565b613767565b348015610ecd57600080fd5b50601954610a4f9060ff1681565b348015610ee757600080fd5b5061060e613864565b348015610efc57600080fd5b50610552610f0b36600461516b565b613871565b348015610f1c57600080fd5b50610698610f2b366004614f8d565b6138f0565b348015610f3c57600080fd5b50610552610f4b366004615190565b613959565b348015610f5c57600080fd5b50610552610f6b366004614cd9565b613cc0565b348015610f7c57600080fd5b50610574610f8b366004614f8d565b613d8b565b348015610f9c57600080fd5b50610552610fab366004615129565b6019805460ff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b348015610ff057600080fd5b50610574610fff366004614943565b60096020526000908152604090205481565b34801561101d57600080fd5b5061057460145481565b34801561103357600080fd5b5060195461093590610100900460ff1681565b34801561105257600080fd5b50610552611061366004614a90565b613dbc565b34801561107257600080fd5b5061060e6110813660046151f8565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b34801561112557600080fd5b50610574611134366004614943565b60066020526000908152604090205481565b34801561115257600080fd5b50610574611161366004614943565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690611259908c1688615280565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af11580156112d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fb91906152c4565b5060008860ff1667ffffffffffffffff81111561131a5761131a6146b6565b604051908082528060200260200182016040528015611343578160200160208202803683370190505b50905060005b8960ff168160ff1610156113b657600061136284613dd0565b905080838360ff168151811061137a5761137a6152df565b602090810291909101810191909152600091825260088152604080832088905560079091529020849055806113ae8161530e565b915050611349565b50505050505050505050565b600d60205282600052604060002060205281600052604060002081815481106113ea57600080fd5b9060005260206000200160009250925050505481565b6013546040517f0b7d33e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690630b7d33e690611458908590859060040161532d565b600060405180830381600087803b15801561147257600080fd5b505af1158015611486573d6000803e3d6000fd5b505050505050565b6013546040517f19d97a940000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff16906319d97a94906024015b600060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115459190810190615393565b92915050565b6013546040517ffa333dfb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015260ff8816602483015260448201879052606482018690526084820185905260a4820184905290911690634ee88d35908990309063fa333dfb9060c401600060405180830381865afa1580156115ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526116309190810190615393565b6040518363ffffffff1660e01b815260040161164d92919061532d565b600060405180830381600087803b15801561166757600080fd5b505af115801561167b573d6000803e3d6000fd5b5050505050505050505050565b6013546040517f1e0104390000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690631e010439906024015b602060405180830381865afa1580156116f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154591906153d3565b6000828152600d6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561178157602002820191906000526020600020905b81548152602001906001019080831161176d575b50505050509050611793818251613e9e565b92509250505b9250929050565b6013546040517f207b65160000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063207b6516906024016114e2565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa15801561188e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b291906153fb565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015611955573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119799190615429565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b8560005b81811015611c805760008989838181106119e2576119e26152df565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001611a1b91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611a4792919061532d565b600060405180830381600087803b158015611a6157600080fd5b505af1158015611a75573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015611aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0f9190615446565b90508060ff16600103611c6b576040517ffa333dfb000000000000000000000000000000000000000000000000000000008152306004820181905260ff8b166024830152604482018a9052606482018890526084820188905260a4820187905260009163fa333dfb9060c401600060405180830381865afa158015611b98573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bde9190810190615393565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590611c37908690859060040161532d565b600060405180830381600087803b158015611c5157600080fd5b505af1158015611c65573d6000803e3d6000fd5b50505050505b50508080611c7890615463565b9150506119c6565b505050505050505050565b6000838152600c602090815260408083208054825181850281018501909352808352611cec93830182828015611ce057602002820191906000526020600020905b815481526020019060010190808311611ccc575b50505050508484613f23565b90505b9392505050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c7c3a19a90602401600060405180830381865afa158015611db5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261154591908101906154be565b8060005b818160ff161015611ed65760135473ffffffffffffffffffffffffffffffffffffffff1663c8048022858560ff8516818110611e3d57611e3d6152df565b905060200201356040518263ffffffff1660e01b8152600401611e6291815260200190565b600060405180830381600087803b158015611e7c57600080fd5b505af1158015611e90573d6000803e3d6000fd5b50505050611ec384848360ff16818110611eac57611eac6152df565b90506020020135600f61408290919063ffffffff16565b5080611ece8161530e565b915050611dff565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611f3d576000858152600d6020908152604080832061ffff85168452909152902054611f2990836155dd565b915080611f35816155f0565b915050611ef2565b509392505050565b6000606060005a90506000611f5861408e565b9050600085806020019051810190611f709190615611565b6019549091507f000000000000000000000000000000000000000000000000000000000000000090610100900460ff1615611fc857507f00000000000000000000000000000000000000000000000000000000000000005b80611fd660c08a018a61562a565b6000818110611fe757611fe76152df565b90506020020135036123e957600061200260c08a018a61562a565b6001818110612013576120136152df565b9050602002013560405160200161202c91815260200190565b60405160208183030381529060405290506000818060200190518101906120539190615611565b90508381146120c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f75706b6565702069647320646f6e2774206d617463680000000000000000000060448201526064015b60405180910390fd5b60006120d260c08c018c61562a565b60028181106120e3576120e36152df565b905060200201356040516020016120fc91815260200190565b60405160208183030381529060405290506000818060200190518101906121239190615611565b9050600061213460c08e018e61562a565b6003818110612145576121456152df565b9050602002013560405160200161215e91815260200190565b60405160208183030381529060405290506000818060200190518101906121859190615429565b6000868152600860205260409020549091505b805a6121a4908d615692565b6121b090613a986155dd565b10156121f15783406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612198565b6040517f6665656449644865780000000000000000000000000000000000000000000000602082015260009060290160405160208183030381529060405280519060200120601860405160200161224891906156f8565b604051602081830303815290604052805190602001200361226a57508361226d565b50425b60195460ff161561231557604080516020810189905290810186905273ffffffffffffffffffffffffffffffffffffffff841660608201526017906016906018908490608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527ff055e4a20000000000000000000000000000000000000000000000000000000082526120ba9594939291600401615827565b60165460009067ffffffffffffffff811115612333576123336146b6565b60405190808252806020026020018201604052801561236657816020015b60608152602001906001900390816123515790505b5060408051602081018b905290810188905273ffffffffffffffffffffffffffffffffffffffff861660608201529091506000906080016040516020818303038152906040529050600182826040516020016123c39291906158ea565b6040516020818303038152906040529f509f505050505050505050505050505050611799565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f756e6578706563746564206576656e742073696700000000000000000000000060448201526064016120ba565b60005a905060008061245f84860186614e79565b9150915060008060008380602001905181019061247c919061597e565b60008381526005602090815260408083205460049092528220549497509295509093509091906124aa61408e565b9050826000036124ca57600086815260056020526040902081905561260e565b60006124d68683615692565b6000888152600e6020908152604080832054600d835281842061ffff90911680855290835281842080548351818602810186019094528084529596509094919290919083018282801561254857602002820191906000526020600020905b815481526020019060010190808311612534575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff168151036125c35781612585816155f0565b60008b8152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000888152600d6020908152604080832061ffff9094168352928152828220805460018181018355918452828420018590558a8352600c8252928220805493840181558252902001555b6000868152600660205260408120546126289060016155dd565b60008881526006602090815260408083208490556004909152902083905590506126528783612e59565b6040513090839089907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a461268c878b846134ce565b505050505050505050505050565b6000828152600d6020908152604080832061ffff851684528252918290208054835181840281018401909452808452606093928301828280156126fc57602002820191906000526020600020905b8154815260200190600101908083116126e8575b5050505050905092915050565b60006060600084846040516020016127229291906158ea565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b6013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690635147cd5990602401602060405180830381865afa1580156127cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190615446565b8160005b8181101561288e5730635f17e616868684818110612815576128156152df565b90506020020135856040518363ffffffff1660e01b815260040161284992919091825263ffffffff16602082015260400190565b600060405180830381600087803b15801561286357600080fd5b505af1158015612877573d6000803e3d6000fd5b50505050808061288690615463565b9150506127f5565b5050505050565b61289d614130565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561290c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129309190615611565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af11580156129a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cc91906152c4565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c9091528120612a08916145b5565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611612a64576000848152600d6020908152604080832061ffff851684529091528120612a52916145b5565b80612a5c816155f0565b915050612a1d565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000818152600560205260408120548103612aba57506001919050565b600082815260036020908152604080832054600490925290912054612add61408e565b612ae79190615692565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612b70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016120ba565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517f79ea99430000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff16906379ea994390602401602060405180830381865afa158015612c5c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190615429565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b590612cda908690869086906004016159ac565b600060405180830381600087803b158015612cf457600080fd5b505af1158015612d08573d6000803e3d6000fd5b50505050505050565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634ee88d3590612cda908690869086906004016159ac565b6017612d778382615a46565b506018612d848282615a46565b505050565b80516129cc9060169060208401906145d3565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260609173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612e13573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611cef9190810190615b60565b601454600083815260026020526040902054612e759083615692565b11156129cc576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612eeb573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612f3191908101906154be565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa158015612fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fca91906153d3565b601554909150612fee9082906c01000000000000000000000000900460ff16615280565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611ed6576015546130319085906bffffffffffffffffffffffff1661309e565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af1158015613126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061314a91906152c4565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401611458565b6040517fc04198220000000000000000000000000000000000000000000000000000000081526000600482018190526024820181905290309063c041982290604401600060405180830381865afa158015613215573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261325b9190810190615b60565b8051909150600061326a61408e565b905060005b8281101561288e57600084828151811061328b5761328b6152df565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa15801561330b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332f9190615446565b90508060ff166001036133ab578660ff1660000361337b576040513090859084907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a46133ab565b6040513090859084907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a45b505080806133b890615463565b91505061326f565b6000818152600c602090815260409182902080548351818402810184019094528084526060939283018282801561341657602002820191906000526020600020905b815481526020019060010190808311613402575b50505050509050919050565b6016818154811061343257600080fd5b90600052602060002001600091509050805461344d906156a5565b80601f0160208091040260200160405190810160405280929190818152602001828054613479906156a5565b80156134c65780601f1061349b576101008083540402835291602001916134c6565b820191906000526020600020905b8154815290600101906020018083116134a957829003601f168201915b505050505081565b6000838152600760205260409020545b805a6134ea9085615692565b6134f6906127106155dd565b1015611ed65781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556134de565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b1580156135af57600080fd5b505af11580156135c3573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b15801561365457600080fd5b505af115801561288e573d6000803e3d6000fd5b6017805461344d906156a5565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff169063b657bc9c906024016116dc565b8060005b818163ffffffff161015611ed6573063af953a4a858563ffffffff85168181106136fd576136fd6152df565b905060200201356040518263ffffffff1660e01b815260040161372291815260200190565b600060405180830381600087803b15801561373c57600080fd5b505af1158015613750573d6000803e3d6000fd5b50505050808061375f90615bf1565b9150506136d1565b60606000613775600f6141b3565b90508084106137b0576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036137c5576137c28482615692565b92505b60008367ffffffffffffffff8111156137e0576137e06146b6565b604051908082528060200260200182016040528015613809578160200160208202803683370190505b50905060005b8481101561385b5761382c61382482886155dd565b600f906141bd565b82828151811061383e5761383e6152df565b60209081029190910101528061385381615463565b91505061380f565b50949350505050565b6018805461344d906156a5565b600061387b61408e565b90508160ff166000036138bc576040513090829085907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4505050565b6040513090829085907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a4505050565b6000828152600c6020908152604080832080548251818502810185019093528083528493849392919083018282801561394857602002820191906000526020600020905b815481526020019060010190808311613934575b505050505090506117938185613e9e565b8260005b81811015611486576000868683818110613979576139796152df565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc82836040516020016139b291815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016139de92919061532d565b600060405180830381600087803b1580156139f857600080fd5b505af1158015613a0c573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015613a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aa69190615446565b90508060ff16600103613cab577f000000000000000000000000000000000000000000000000000000000000000060ff871615613b0057507f00000000000000000000000000000000000000000000000000000000000000005b60003073ffffffffffffffffffffffffffffffffffffffff1663fa333dfb30898588604051602001613b3491815260200190565b604051602081830303815290604052613b4c90615c0a565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff909416600485015260ff90921660248401526044830152606482015260006084820181905260a482015260c401600060405180830381865afa158015613bd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052613c1d9190810190615393565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590613c76908790859060040161532d565b600060405180830381600087803b158015613c9057600080fd5b505af1158015613ca4573d6000803e3d6000fd5b5050505050505b50508080613cb890615463565b91505061395d565b8060005b81811015611ed6576000848483818110613ce057613ce06152df565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001613d1991815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401613d4592919061532d565b600060405180830381600087803b158015613d5f57600080fd5b505af1158015613d73573d6000803e3d6000fd5b50505050508080613d8390615463565b915050613cc4565b600c6020528160005260406000208181548110613da757600080fd5b90600052602060002001600091509150505481565b613dc4614130565b613dcd816141c9565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190613e2b908690600401615c4c565b6020604051808303816000875af1158015613e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6e9190615611565b9050613e7b600f826142be565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b815160009081908190841580613eb45750808510155b15613ebd578094505b60008092505b85831015613f1957866001613ed88585615692565b613ee29190615692565b81518110613ef257613ef26152df565b602002602001015181613f0591906155dd565b905082613f1181615463565b935050613ec3565b9694955050505050565b82516000908190831580613f375750808410155b15613f40578093505b60008467ffffffffffffffff811115613f5b57613f5b6146b6565b604051908082528060200260200182016040528015613f84578160200160208202803683370190505b509050600092505b84831015613ff257866001613fa18585615692565b613fab9190615692565b81518110613fbb57613fbb6152df565b6020026020010151818481518110613fd557613fd56152df565b602090810291909101015282613fea81615463565b935050613f8c565b61400b816000600184516140069190615692565b6142ca565b856064036140445780600182516140229190615692565b81518110614032576140326152df565b60200260200101519350505050611cef565b8060648251886140549190615d9e565b61405e9190615e0a565b8151811061406e5761406e6152df565b602002602001015193505050509392505050565b6000611cef8383614442565b60007f00000000000000000000000000000000000000000000000000000000000000001561412b57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141269190615611565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff1633146141b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016120ba565b565b6000611545825490565b6000611cef838361453c565b3373ffffffffffffffffffffffffffffffffffffffff821603614248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016120ba565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611cef8383614566565b81818082036142da575050505050565b60008560026142e98787615e1e565b6142f39190615e3e565b6142fd9087615ea6565b8151811061430d5761430d6152df565b602002602001015190505b81831361441c575b80868481518110614333576143336152df565b60200260200101511015614353578261434b81615ece565b935050614320565b858281518110614365576143656152df565b6020026020010151811015614386578161437e81615eff565b925050614353565b8183136144175785828151811061439f5761439f6152df565b60200260200101518684815181106143b9576143b96152df565b60200260200101518785815181106143d3576143d36152df565b602002602001018885815181106143ec576143ec6152df565b6020908102919091010191909152528261440581615ece565b935050818061441390615eff565b9250505b614318565b8185121561442f5761442f8686846142ca565b83831215611486576114868684866142ca565b6000818152600183016020526040812054801561452b576000614466600183615692565b855490915060009061447a90600190615692565b90508181146144df57600086600001828154811061449a5761449a6152df565b90600052602060002001549050808760000184815481106144bd576144bd6152df565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806144f0576144f0615f56565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611545565b6000915050611545565b5092915050565b6000826000018281548110614553576145536152df565b9060005260206000200154905092915050565b60008181526001830160205260408120546145ad57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611545565b506000611545565b5080546000825590600052602060002090810190613dcd9190614629565b828054828255906000526020600020908101928215614619579160200282015b8281111561461957825182906146099082615a46565b50916020019190600101906145f3565b5061462592915061463e565b5090565b5b80821115614625576000815560010161462a565b80821115614625576000614652828261465b565b5060010161463e565b508054614667906156a5565b6000825580601f10614677575050565b601f016020900490600052602060002090810190613dcd9190614629565b60ff81168114613dcd57600080fd5b63ffffffff81168114613dcd57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614709576147096146b6565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614756576147566146b6565b604052919050565b600067ffffffffffffffff821115614778576147786146b6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126147b557600080fd5b81356147c86147c38261475e565b61470f565b8181528460208386010111156147dd57600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff81168114613dcd57600080fd5b600080600080600080600060e0888a03121561482f57600080fd5b873561483a81614695565b9650602088013561484a816146a4565b9550604088013561485a81614695565b9450606088013567ffffffffffffffff81111561487657600080fd5b6148828a828b016147a4565b9450506080880135614893816147fa565b9699959850939692959460a0840135945060c09093013592915050565b803561ffff811681146148c257600080fd5b919050565b6000806000606084860312156148dc57600080fd5b833592506148ec602085016148b0565b9150604084013590509250925092565b6000806040838503121561490f57600080fd5b82359150602083013567ffffffffffffffff81111561492d57600080fd5b614939858286016147a4565b9150509250929050565b60006020828403121561495557600080fd5b5035919050565b60005b8381101561497757818101518382015260200161495f565b50506000910152565b6000815180845261499881602086016020860161495c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cef6020830184614980565b73ffffffffffffffffffffffffffffffffffffffff81168114613dcd57600080fd5b600080600080600080600060e0888a031215614a1a57600080fd5b873596506020880135614a2c816149dd565b95506040880135614a3c81614695565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b60008060408385031215614a7757600080fd5b82359150614a87602084016148b0565b90509250929050565b600060208284031215614aa257600080fd5b8135611cef816149dd565b60008083601f840112614abf57600080fd5b50813567ffffffffffffffff811115614ad757600080fd5b6020830191508360208260051b850101111561179957600080fd5b600080600080600080600060c0888a031215614b0d57600080fd5b873567ffffffffffffffff811115614b2457600080fd5b614b308a828b01614aad565b9098509650506020880135614b4481614695565b96999598509596604081013596506060810135956080820135955060a0909101359350915050565b600080600060608486031215614b8157600080fd5b505081359360208301359350604090920135919050565b60208152614bbf60208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614bd8604084018263ffffffff169052565b506040830151610140806060850152614bf5610160850183614980565b91506060850151614c1660808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614c82818701836bffffffffffffffffffffffff169052565b8601519050610120614c978682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001838701529050614ccf8382614980565b9695505050505050565b60008060208385031215614cec57600080fd5b823567ffffffffffffffff811115614d0357600080fd5b614d0f85828601614aad565b90969095509350505050565b60008060408385031215614d2e57600080fd5b823567ffffffffffffffff80821115614d4657600080fd5b908401906101008287031215614d5b57600080fd5b90925060208401359080821115614d7157600080fd5b50614939858286016147a4565b8215158152604060208201526000611cec6040830184614980565b60008083601f840112614dab57600080fd5b50813567ffffffffffffffff811115614dc357600080fd5b60208301915083602082850101111561179957600080fd5b60008060208385031215614dee57600080fd5b823567ffffffffffffffff811115614e0557600080fd5b614d0f85828601614d99565b6020808252825182820181905260009190848201906040850190845b81811015614e4957835183529284019291840191600101614e2d565b50909695505050505050565b600067ffffffffffffffff821115614e6f57614e6f6146b6565b5060051b60200190565b60008060408385031215614e8c57600080fd5b823567ffffffffffffffff80821115614ea457600080fd5b818501915085601f830112614eb857600080fd5b81356020614ec86147c383614e55565b82815260059290921b84018101918181019089841115614ee757600080fd5b8286015b84811015614f1f57803586811115614f035760008081fd5b614f118c86838b01016147a4565b845250918301918301614eeb565b5096505086013592505080821115614d7157600080fd5b600080600060408486031215614f4b57600080fd5b833567ffffffffffffffff811115614f6257600080fd5b614f6e86828701614aad565b9094509250506020840135614f82816146a4565b809150509250925092565b60008060408385031215614fa057600080fd5b50508035926020909101359150565b600080600060408486031215614fc457600080fd5b83359250602084013567ffffffffffffffff811115614fe257600080fd5b614fee86828701614d99565b9497909650939450505050565b6000806040838503121561500e57600080fd5b823567ffffffffffffffff8082111561502657600080fd5b615032868387016147a4565b93506020850135915080821115614d7157600080fd5b6000602080838503121561505b57600080fd5b823567ffffffffffffffff8082111561507357600080fd5b818501915085601f83011261508757600080fd5b81356150956147c382614e55565b81815260059190911b830184019084810190888311156150b457600080fd5b8585015b838110156150ec578035858111156150d05760008081fd5b6150de8b89838a01016147a4565b8452509186019186016150b8565b5098975050505050505050565b6000806040838503121561510c57600080fd5b82359150602083013561511e816147fa565b809150509250929050565b60006020828403121561513b57600080fd5b8135611cef81614695565b6000806040838503121561515957600080fd5b82359150602083013561511e816146a4565b6000806040838503121561517e57600080fd5b82359150602083013561511e81614695565b600080600080606085870312156151a657600080fd5b843567ffffffffffffffff8111156151bd57600080fd5b6151c987828801614aad565b90955093505060208501356151dd81614695565b915060408501356151ed81614695565b939692955090935050565b60008060008060008060c0878903121561521157600080fd5b863561521c816149dd565b9550602087013561522c81614695565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516818304811182151516156152ab576152ab615251565b02949350505050565b805180151581146148c257600080fd5b6000602082840312156152d657600080fd5b611cef826152b4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff810361532457615324615251565b60010192915050565b828152604060208201526000611cec6040830184614980565b600082601f83011261535757600080fd5b81516153656147c38261475e565b81815284602083860101111561537a57600080fd5b61538b82602083016020870161495c565b949350505050565b6000602082840312156153a557600080fd5b815167ffffffffffffffff8111156153bc57600080fd5b61538b84828501615346565b80516148c2816147fa565b6000602082840312156153e557600080fd5b8151611cef816147fa565b80516148c2816149dd565b6000806040838503121561540e57600080fd5b8251615419816149dd565b6020939093015192949293505050565b60006020828403121561543b57600080fd5b8151611cef816149dd565b60006020828403121561545857600080fd5b8151611cef81614695565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361549457615494615251565b5060010190565b80516148c2816146a4565b805167ffffffffffffffff811681146148c257600080fd5b6000602082840312156154d057600080fd5b815167ffffffffffffffff808211156154e857600080fd5b9083019061014082860312156154fd57600080fd5b6155056146e5565b61550e836153f0565b815261551c6020840161549b565b602082015260408301518281111561553357600080fd5b61553f87828601615346565b604083015250615551606084016153c8565b6060820152615562608084016153f0565b608082015261557360a084016154a6565b60a082015261558460c0840161549b565b60c082015261559560e084016153c8565b60e08201526101006155a88185016152b4565b9082015261012083810151838111156155c057600080fd5b6155cc88828701615346565b918301919091525095945050505050565b8082018082111561154557611545615251565b600061ffff80831681810361560757615607615251565b6001019392505050565b60006020828403121561562357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261565f57600080fd5b83018035915067ffffffffffffffff82111561567a57600080fd5b6020019150600581901b360382131561179957600080fd5b8181038181111561154557611545615251565b600181811c908216806156b957607f821691505b6020821081036156f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000808354615706816156a5565b6001828116801561571e576001811461575157615780565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450615780565b8760005260208060002060005b858110156157775781548a82015290840190820161575e565b50505082870194505b50929695505050505050565b60008154615799816156a5565b8085526020600183811680156157b657600181146157ee5761581c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061581c565b866000528260002060005b858110156158145781548a82018601529083019084016157f9565b890184019650505b505050505092915050565b60a08152600061583a60a083018861578c565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b838110156158ac577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261589a838361578c565b94860194925060019182019101615861565b505086810360408801526158c0818b61578c565b94505050505084606084015282810360808401526158de8185614980565b98975050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561595f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261594d868351614980565b95509382019390820190600101615913565b5050858403818701525050506159758185614980565b95945050505050565b60008060006060848603121561599357600080fd5b83519250602084015191506040840151614f82816149dd565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b601f821115612d8457600081815260208120601f850160051c81016020861015615a275750805b601f850160051c820191505b8181101561148657828155600101615a33565b815167ffffffffffffffff811115615a6057615a606146b6565b615a7481615a6e84546156a5565b84615a00565b602080601f831160018114615ac75760008415615a915750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611486565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015615b1457888601518255948401946001909101908401615af5565b5085821015615b5057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808385031215615b7357600080fd5b825167ffffffffffffffff811115615b8a57600080fd5b8301601f81018513615b9b57600080fd5b8051615ba96147c382614e55565b81815260059190911b82018301908381019087831115615bc857600080fd5b928401925b82841015615be657835182529284019290840190615bcd565b979650505050505050565b600063ffffffff80831681810361560757615607615251565b805160208083015191908110156156f2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b6020815260008251610140806020850152615c6b610160850183614980565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080868503016040870152615ca78483614980565b935060408701519150615cd2606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e0870152615d338483614980565b935060e08701519150610100818786030181880152615d528584614980565b945080880151925050610120818786030181880152615d718584614980565b94508088015192505050615d94828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615dd657615dd6615251565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615e1957615e19615ddb565b500490565b818103600083128015838313168383128216171561453557614535615251565b600082615e4d57615e4d615ddb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615ea157615ea1615251565b500590565b8082018281126000831280158216821582161715615ec657615ec6615251565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361549457615494615251565b60007f80000000000000000000000000000000000000000000000000000000000000008203615f3057615f30615251565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", } var VerifiableLoadLogTriggerUpkeepABI = VerifiableLoadLogTriggerUpkeepMetaData.ABI diff --git a/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper/verifiable_load_streams_lookup_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper/verifiable_load_streams_lookup_upkeep_wrapper.go index 1ff616ee12b..75bea5079a2 100644 --- a/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper/verifiable_load_streams_lookup_upkeep_wrapper.go +++ b/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper/verifiable_load_streams_lookup_upkeep_wrapper.go @@ -45,7 +45,7 @@ type KeeperRegistryBase21UpkeepInfo struct { var VerifiableLoadStreamsLookupUpkeepMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmittedAgain\",\"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\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"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\"}],\"name\":\"batchPreparingUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"}],\"name\":\"batchPreparingUpkeepsSimple\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedAgainSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDsDeployedByThisContract\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getAllActiveUpkeepIDsOnRegistry\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"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\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"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\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepInfo\",\"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\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"name\":\"\",\"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\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"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\"}],\"name\":\"updateLogTriggerConfig1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"updateLogTriggerConfig2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080527fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d60a0526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460e0526101c0604052604261014081815261010091829190620060c161016039815260200160405180608001604052806042815260200162006103604291399052620000be906016906002620003c7565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000ee908262000543565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b602082015260189062000120908262000543565b503480156200012e57600080fd5b506040516200614538038062006145833981016040819052620001519162000625565b81813380600081620001aa5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001dd57620001dd816200031c565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200023a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000260919062000668565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec919062000699565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560c05250620006c0915050565b336001600160a01b03821603620003765760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620001a1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821562000412579160200282015b8281111562000412578251829062000401908262000543565b5091602001919060010190620003e8565b506200042092915062000424565b5090565b80821115620004205760006200043b828262000445565b5060010162000424565b5080546200045390620004b4565b6000825580601f1062000464575050565b601f01602090049060005260206000209081019062000484919062000487565b50565b5b8082111562000420576000815560010162000488565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c957607f821691505b602082108103620004ea57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053e57600081815260208120601f850160051c81016020861015620005195750805b601f850160051c820191505b818110156200053a5782815560010162000525565b5050505b505050565b81516001600160401b038111156200055f576200055f6200049e565b6200057781620005708454620004b4565b84620004f0565b602080601f831160018114620005af5760008415620005965750858301515b600019600386901b1c1916600185901b1785556200053a565b600085815260208120601f198616915b82811015620005e057888601518255948401946001909101908401620005bf565b5085821015620005ff5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200048457600080fd5b600080604083850312156200063957600080fd5b825162000646816200060f565b602084015190925080151581146200065d57600080fd5b809150509250929050565b600080604083850312156200067c57600080fd5b825162000689816200060f565b6020939093015192949293505050565b600060208284031215620006ac57600080fd5b8151620006b9816200060f565b9392505050565b60805160a05160c05160e0516159ab62000716600039600081816105680152611f7a0152600081816109bc0152613c2b0152600081816108270152613679015260008181610d79015261364e01526159ab6000f3fe6080604052600436106104d55760003560e01c806379ea994311610279578063a6b594751161015e578063d6051a72116100d6578063e45530831161008a578063fa333dfb1161006f578063fa333dfb14610f88578063fba7ffa31461103b578063fcdc1f631461106857600080fd5b8063e455308314610f52578063f2fde38b14610f6857600080fd5b8063daee1aeb116100bb578063daee1aeb14610ee5578063dbef701e14610f05578063e0114adb14610f2557600080fd5b8063d6051a7214610ea5578063da6cba4714610ec557600080fd5b8063b657bc9c1161012d578063c041982211610112578063c041982214610e50578063c98f10b014610e70578063d4c2490014610e8557600080fd5b8063b657bc9c14610e10578063becde0e114610e3057600080fd5b8063a6b5947514610d9b578063a72aa27e14610dbb578063af953a4a14610ddb578063afb28d1f14610dfb57600080fd5b8063924ca578116101f15780639b429354116101c05780639d385eaa116101a55780639d385eaa14610d275780639d6f1cc714610d47578063a654824814610d6757600080fd5b80639b42935414610cc95780639b51fb0d14610cf657600080fd5b8063924ca57814610c3f578063948108f714610c5f57806396cebc7c14610c7f5780639ac542eb14610c9f57600080fd5b80638340507c11610248578063873c75861161022d578063873c758614610bc75780638da5cb5b14610be75780638fcb3fba14610c1257600080fd5b80638340507c14610b8757806386e330af14610ba757600080fd5b806379ea994314610afa5780637b10399914610b1a5780637e7a46dc14610b475780638243444a14610b6757600080fd5b806345d2ec17116103ba57806360457ff5116103325780637145f11b116102e657806376721303116102cb5780637672130314610a98578063776898c814610ac557806379ba509714610ae557600080fd5b80637145f11b14610a3b57806373644cce14610a6b57600080fd5b8063642f6cef11610317578063642f6cef146109aa57806369cdbadb146109ee5780636e04ff0d14610a1b57600080fd5b806360457ff514610958578063636092e81461098557600080fd5b80635147cd591161038957806357970e931161036e57806357970e93146108f65780635d4ee7f3146109235780635f17e6161461093857600080fd5b80635147cd59146108a457806351c98be3146108d657600080fd5b806345d2ec17146107e8578063469820931461081557806346e7a63e146108495780634b56a42e1461087657600080fd5b806320e3dbd41161044d5780632a9032d31161041c578063328ffd1111610401578063328ffd111461077b5780633ebe8d6c146107a85780634585e33b146107c857600080fd5b80632a9032d3146107095780632b20e3971461072957600080fd5b806320e3dbd41461067c5780632636aecf1461069c57806328c4b57b146106bc57806329e0a841146106dc57600080fd5b806319d97a94116104a45780631e010439116104895780631e010439146105ea578063206c32e814610627578063207b65161461065c57600080fd5b806319d97a941461059d5780631cdde251146105ca57600080fd5b806306c1cc00146104e1578063077ac621146105035780630b7d33e61461053657806312c550271461055657600080fd5b366104dc57005b600080fd5b3480156104ed57600080fd5b506105016104fc3660046143ad565b611095565b005b34801561050f57600080fd5b5061052361051e366004614460565b6112e4565b6040519081526020015b60405180910390f35b34801561054257600080fd5b50610501610551366004614495565b611322565b34801561056257600080fd5b5061058a7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161052d565b3480156105a957600080fd5b506105bd6105b83660046144dc565b6113b0565b60405161052d9190614563565b3480156105d657600080fd5b506105016105e5366004614598565b61146d565b3480156105f657600080fd5b5061060a6106053660046144dc565b6115aa565b6040516bffffffffffffffffffffffff909116815260200161052d565b34801561063357600080fd5b506106476106423660046145fd565b61163f565b6040805192835260208301919091520161052d565b34801561066857600080fd5b506105bd6106773660046144dc565b6116c2565b34801561068857600080fd5b50610501610697366004614629565b61171a565b3480156106a857600080fd5b506105016106b736600461468b565b6118e4565b3480156106c857600080fd5b506105236106d7366004614705565b611bad565b3480156106e857600080fd5b506106fc6106f73660046144dc565b611c18565b60405161052d9190614731565b34801561071557600080fd5b50610501610724366004614872565b611d1d565b34801561073557600080fd5b506011546107569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161052d565b34801561078757600080fd5b506105236107963660046144dc565b60036020526000908152604090205481565b3480156107b457600080fd5b506105236107c33660046144dc565b611dfe565b3480156107d457600080fd5b506105016107e33660046148f6565b611e67565b3480156107f457600080fd5b506108086108033660046145fd565b612086565b60405161052d919061492c565b34801561082157600080fd5b506105237f000000000000000000000000000000000000000000000000000000000000000081565b34801561085557600080fd5b506105236108643660046144dc565b600a6020526000908152604090205481565b34801561088257600080fd5b50610896610891366004614994565b6120f5565b60405161052d929190614a5e565b3480156108b057600080fd5b506108c46108bf3660046144dc565b612149565b60405160ff909116815260200161052d565b3480156108e257600080fd5b506105016108f1366004614a79565b6121dd565b34801561090257600080fd5b506012546107569073ffffffffffffffffffffffffffffffffffffffff1681565b34801561092f57600080fd5b50610501612281565b34801561094457600080fd5b50610501610953366004614ad0565b6123bc565b34801561096457600080fd5b506105236109733660046144dc565b60076020526000908152604090205481565b34801561099157600080fd5b5060155461060a906bffffffffffffffffffffffff1681565b3480156109b657600080fd5b506109de7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161052d565b3480156109fa57600080fd5b50610523610a093660046144dc565b60086020526000908152604090205481565b348015610a2757600080fd5b50610896610a363660046148f6565b612489565b348015610a4757600080fd5b506109de610a563660046144dc565b600b6020526000908152604090205460ff1681565b348015610a7757600080fd5b50610523610a863660046144dc565b6000908152600c602052604090205490565b348015610aa457600080fd5b50610523610ab33660046144dc565b60046020526000908152604090205481565b348015610ad157600080fd5b506109de610ae03660046144dc565b612636565b348015610af157600080fd5b50610501612688565b348015610b0657600080fd5b50610756610b153660046144dc565b612785565b348015610b2657600080fd5b506013546107569073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b5357600080fd5b50610501610b62366004614af2565b612819565b348015610b7357600080fd5b50610501610b82366004614af2565b6128aa565b348015610b9357600080fd5b50610501610ba2366004614b3e565b612904565b348015610bb357600080fd5b50610501610bc2366004614b8b565b612922565b348015610bd357600080fd5b50610808610be2366004614ad0565b612935565b348015610bf357600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610756565b348015610c1e57600080fd5b50610523610c2d3660046144dc565b60056020526000908152604090205481565b348015610c4b57600080fd5b50610501610c5a366004614ad0565b6129f2565b348015610c6b57600080fd5b50610501610c7a366004614c3c565b612c37565b348015610c8b57600080fd5b50610501610c9a366004614c6c565b612d4f565b348015610cab57600080fd5b506015546108c4906c01000000000000000000000000900460ff1681565b348015610cd557600080fd5b50610501610ce4366004614ad0565b60009182526009602052604090912055565b348015610d0257600080fd5b5061058a610d113660046144dc565b600e6020526000908152604090205461ffff1681565b348015610d3357600080fd5b50610808610d423660046144dc565b612f59565b348015610d5357600080fd5b506105bd610d623660046144dc565b612fbb565b348015610d7357600080fd5b506105237f000000000000000000000000000000000000000000000000000000000000000081565b348015610da757600080fd5b50610501610db6366004614705565b613067565b348015610dc757600080fd5b50610501610dd6366004614c89565b6130d0565b348015610de757600080fd5b50610501610df63660046144dc565b61317b565b348015610e0757600080fd5b506105bd613201565b348015610e1c57600080fd5b5061060a610e2b3660046144dc565b61320e565b348015610e3c57600080fd5b50610501610e4b366004614872565b613266565b348015610e5c57600080fd5b50610808610e6b366004614ad0565b613300565b348015610e7c57600080fd5b506105bd6133fd565b348015610e9157600080fd5b50610501610ea0366004614cae565b61340a565b348015610eb157600080fd5b50610647610ec0366004614ad0565b613489565b348015610ed157600080fd5b50610501610ee0366004614cd3565b6134f2565b348015610ef157600080fd5b50610501610f00366004614872565b613859565b348015610f1157600080fd5b50610523610f20366004614ad0565b613924565b348015610f3157600080fd5b50610523610f403660046144dc565b60096020526000908152604090205481565b348015610f5e57600080fd5b5061052360145481565b348015610f7457600080fd5b50610501610f83366004614629565b613955565b348015610f9457600080fd5b506105bd610fa3366004614d3b565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b34801561104757600080fd5b506105236110563660046144dc565b60066020526000908152604090205481565b34801561107457600080fd5b506105236110833660046144dc565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b392169061117b908c1688614dc3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af11580156111f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121d9190614e07565b5060008860ff1667ffffffffffffffff81111561123c5761123c61424f565b604051908082528060200260200182016040528015611265578160200160208202803683370190505b50905060005b8960ff168160ff1610156112d857600061128484613969565b905080838360ff168151811061129c5761129c614e22565b602090810291909101810191909152600091825260088152604080832088905560079091529020849055806112d081614e51565b91505061126b565b50505050505050505050565b600d602052826000526040600020602052816000526040600020818154811061130c57600080fd5b9060005260206000200160009250925050505481565b6013546040517f0b7d33e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690630b7d33e69061137a9085908590600401614e70565b600060405180830381600087803b15801561139457600080fd5b505af11580156113a8573d6000803e3d6000fd5b505050505050565b6013546040517f19d97a940000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff16906319d97a94906024015b600060405180830381865afa158015611421573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114679190810190614ed6565b92915050565b6013546040517ffa333dfb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015260ff8816602483015260448201879052606482018690526084820185905260a4820184905290911690634ee88d35908990309063fa333dfb9060c401600060405180830381865afa15801561150c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115529190810190614ed6565b6040518363ffffffff1660e01b815260040161156f929190614e70565b600060405180830381600087803b15801561158957600080fd5b505af115801561159d573d6000803e3d6000fd5b5050505050505050505050565b6013546040517f1e0104390000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690631e010439906024015b602060405180830381865afa15801561161b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190614f16565b6000828152600d6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156116a357602002820191906000526020600020905b81548152602001906001019080831161168f575b505050505090506116b5818251613a37565b92509250505b9250929050565b6013546040517f207b65160000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063207b651690602401611404565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa1580156117b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d49190614f3e565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015611877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189b9190614f6c565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b8560005b81811015611ba257600089898381811061190457611904614e22565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161193d91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611969929190614e70565b600060405180830381600087803b15801561198357600080fd5b505af1158015611997573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015611a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a319190614f89565b90508060ff16600103611b8d576040517ffa333dfb000000000000000000000000000000000000000000000000000000008152306004820181905260ff8b166024830152604482018a9052606482018890526084820188905260a4820187905260009163fa333dfb9060c401600060405180830381865afa158015611aba573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611b009190810190614ed6565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590611b599086908590600401614e70565b600060405180830381600087803b158015611b7357600080fd5b505af1158015611b87573d6000803e3d6000fd5b50505050505b50508080611b9a90614fa6565b9150506118e8565b505050505050505050565b6000838152600c602090815260408083208054825181850281018501909352808352611c0e93830182828015611c0257602002820191906000526020600020905b815481526020019060010190808311611bee575b50505050508484613abc565b90505b9392505050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c7c3a19a90602401600060405180830381865afa158015611cd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114679190810190615001565b8060005b818160ff161015611df85760135473ffffffffffffffffffffffffffffffffffffffff1663c8048022858560ff8516818110611d5f57611d5f614e22565b905060200201356040518263ffffffff1660e01b8152600401611d8491815260200190565b600060405180830381600087803b158015611d9e57600080fd5b505af1158015611db2573d6000803e3d6000fd5b50505050611de584848360ff16818110611dce57611dce614e22565b90506020020135600f613c1b90919063ffffffff16565b5080611df081614e51565b915050611d21565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611e5f576000858152600d6020908152604080832061ffff85168452909152902054611e4b9083615120565b915080611e5781615133565b915050611e14565b509392505050565b60005a9050600080611e7b84860186614994565b91509150600081806020019051810190611e959190615154565b60008181526005602090815260408083205460049092528220549293509190611ebc613c27565b905082600003611edc576000848152600560205260409020819055612037565b600084815260036020526040812054611ef5848461516d565b611eff919061516d565b6000868152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611f7157602002820191906000526020600020905b815481526020019060010190808311611f5d575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611fec5781611fae81615133565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b600084815260066020526040812054612051906001615120565b600086815260066020908152604080832084905560049091529020839055905061207b85836129f2565b6112d8858984613067565b6000828152600d6020908152604080832061ffff851684528252918290208054835181840281018401909452808452606093928301828280156120e857602002820191906000526020600020905b8154815260200190600101908083116120d4575b5050505050905092915050565b600060606000848460405160200161210e929190615180565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b6013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690635147cd5990602401602060405180830381865afa1580156121b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190614f89565b8160005b8181101561227a5730635f17e61686868481811061220157612201614e22565b90506020020135856040518363ffffffff1660e01b815260040161223592919091825263ffffffff16602082015260400190565b600060405180830381600087803b15801561224f57600080fd5b505af1158015612263573d6000803e3d6000fd5b50505050808061227290614fa6565b9150506121e1565b5050505050565b612289613cc9565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156122f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231c9190615154565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015612394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b89190614e07565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c90915281206123f49161414e565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611612450576000848152600d6020908152604080832061ffff85168452909152812061243e9161414e565b8061244881615133565b915050612409565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a905060006124a0858701876144dc565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff8111156124d9576124d961424f565b6040519080825280601f01601f191660200182016040528015612503576020820181803683370190505b50604051602001612515929190614e70565b60405160208183030381529060405290506000612530613c27565b9050600061253d86612636565b90505b835a61254c908961516d565b61255890612710615120565b10156125995781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612540565b806125b15760008398509850505050505050506116bb565b60176016601884896040516020016125cb91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527ff055e4a200000000000000000000000000000000000000000000000000000000825261262d9594939291600401615302565b60405180910390fd5b600081815260056020526040812054810361265357506001919050565b600082815260036020908152604080832054600490925290912054612676613c27565b612680919061516d565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161262d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517f79ea99430000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff16906379ea994390602401602060405180830381865afa1580156127f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190614f6c565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b590612873908690869086906004016153c5565b600060405180830381600087803b15801561288d57600080fd5b505af11580156128a1573d6000803e3d6000fd5b50505050505050565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634ee88d3590612873908690869086906004016153c5565b6017612910838261545f565b50601861291d828261545f565b505050565b80516123b890601690602084019061416c565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260609173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa1580156129ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611c119190810190615579565b601454600083815260026020526040902054612a0e908361516d565b11156123b8576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612a84573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612aca9190810190615001565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa158015612b3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b639190614f16565b601554909150612b879082906c01000000000000000000000000900460ff16614dc3565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611df857601554612bca9085906bffffffffffffffffffffffff16612c37565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af1158015612cbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce39190614e07565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f79060440161137a565b6040517fc04198220000000000000000000000000000000000000000000000000000000081526000600482018190526024820181905290309063c041982290604401600060405180830381865afa158015612dae573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612df49190810190615579565b80519091506000612e03613c27565b905060005b8281101561227a576000848281518110612e2457612e24614e22565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015612ea4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ec89190614f89565b90508060ff16600103612f44578660ff16600003612f14576040513090859084907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4612f44565b6040513090859084907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a45b50508080612f5190614fa6565b915050612e08565b6000818152600c6020908152604091829020805483518184028101840190945280845260609392830182828015612faf57602002820191906000526020600020905b815481526020019060010190808311612f9b575b50505050509050919050565b60168181548110612fcb57600080fd5b906000526020600020016000915090508054612fe690615214565b80601f016020809104026020016040519081016040528092919081815260200182805461301290615214565b801561305f5780601f106130345761010080835404028352916020019161305f565b820191906000526020600020905b81548152906001019060200180831161304257829003601f168201915b505050505081565b6000838152600760205260409020545b805a613083908561516d565b61308f90612710615120565b1015611df85781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055613077565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b15801561314857600080fd5b505af115801561315c573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b1580156131ed57600080fd5b505af115801561227a573d6000803e3d6000fd5b60178054612fe690615214565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff169063b657bc9c906024016115fe565b8060005b818163ffffffff161015611df8573063af953a4a858563ffffffff851681811061329657613296614e22565b905060200201356040518263ffffffff1660e01b81526004016132bb91815260200190565b600060405180830381600087803b1580156132d557600080fd5b505af11580156132e9573d6000803e3d6000fd5b5050505080806132f89061560a565b91505061326a565b6060600061330e600f613d4c565b9050808410613349576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361335e5761335b848261516d565b92505b60008367ffffffffffffffff8111156133795761337961424f565b6040519080825280602002602001820160405280156133a2578160200160208202803683370190505b50905060005b848110156133f4576133c56133bd8288615120565b600f90613d56565b8282815181106133d7576133d7614e22565b6020908102919091010152806133ec81614fa6565b9150506133a8565b50949350505050565b60188054612fe690615214565b6000613414613c27565b90508160ff16600003613455576040513090829085907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4505050565b6040513090829085907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a4505050565b6000828152600c602090815260408083208054825181850281018501909352808352849384939291908301828280156134e157602002820191906000526020600020905b8154815260200190600101908083116134cd575b505050505090506116b58185613a37565b8260005b818110156113a857600086868381811061351257613512614e22565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161354b91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401613577929190614e70565b600060405180830381600087803b15801561359157600080fd5b505af11580156135a5573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa15801561361b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061363f9190614f89565b90508060ff16600103613844577f000000000000000000000000000000000000000000000000000000000000000060ff87161561369957507f00000000000000000000000000000000000000000000000000000000000000005b60003073ffffffffffffffffffffffffffffffffffffffff1663fa333dfb308985886040516020016136cd91815260200190565b6040516020818303038152906040526136e590615623565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff909416600485015260ff90921660248401526044830152606482015260006084820181905260a482015260c401600060405180830381865afa158015613770573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526137b69190810190614ed6565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d359061380f9087908590600401614e70565b600060405180830381600087803b15801561382957600080fd5b505af115801561383d573d6000803e3d6000fd5b5050505050505b5050808061385190614fa6565b9150506134f6565b8060005b81811015611df857600084848381811061387957613879614e22565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc82836040516020016138b291815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016138de929190614e70565b600060405180830381600087803b1580156138f857600080fd5b505af115801561390c573d6000803e3d6000fd5b5050505050808061391c90614fa6565b91505061385d565b600c602052816000526040600020818154811061394057600080fd5b90600052602060002001600091509150505481565b61395d613cc9565b61396681613d62565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e11906139c4908690600401615665565b6020604051808303816000875af11580156139e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a079190615154565b9050613a14600f82613e57565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b815160009081908190841580613a4d5750808510155b15613a56578094505b60008092505b85831015613ab257866001613a71858561516d565b613a7b919061516d565b81518110613a8b57613a8b614e22565b602002602001015181613a9e9190615120565b905082613aaa81614fa6565b935050613a5c565b9694955050505050565b82516000908190831580613ad05750808410155b15613ad9578093505b60008467ffffffffffffffff811115613af457613af461424f565b604051908082528060200260200182016040528015613b1d578160200160208202803683370190505b509050600092505b84831015613b8b57866001613b3a858561516d565b613b44919061516d565b81518110613b5457613b54614e22565b6020026020010151818481518110613b6e57613b6e614e22565b602090810291909101015282613b8381614fa6565b935050613b25565b613ba481600060018451613b9f919061516d565b613e63565b85606403613bdd578060018251613bbb919061516d565b81518110613bcb57613bcb614e22565b60200260200101519350505050611c11565b806064825188613bed91906157b7565b613bf79190615823565b81518110613c0757613c07614e22565b602002602001015193505050509392505050565b6000611c118383613fdb565b60007f000000000000000000000000000000000000000000000000000000000000000015613cc457606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cbf9190615154565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff163314613d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161262d565b565b6000611467825490565b6000611c1183836140d5565b3373ffffffffffffffffffffffffffffffffffffffff821603613de1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161262d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611c1183836140ff565b8181808203613e73575050505050565b6000856002613e828787615837565b613e8c9190615857565b613e9690876158bf565b81518110613ea657613ea6614e22565b602002602001015190505b818313613fb5575b80868481518110613ecc57613ecc614e22565b60200260200101511015613eec5782613ee4816158e7565b935050613eb9565b858281518110613efe57613efe614e22565b6020026020010151811015613f1f5781613f1781615918565b925050613eec565b818313613fb057858281518110613f3857613f38614e22565b6020026020010151868481518110613f5257613f52614e22565b6020026020010151878581518110613f6c57613f6c614e22565b60200260200101888581518110613f8557613f85614e22565b60209081029190910101919091525282613f9e816158e7565b9350508180613fac90615918565b9250505b613eb1565b81851215613fc857613fc8868684613e63565b838312156113a8576113a8868486613e63565b600081815260018301602052604081205480156140c4576000613fff60018361516d565b85549091506000906140139060019061516d565b905081811461407857600086600001828154811061403357614033614e22565b906000526020600020015490508087600001848154811061405657614056614e22565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806140895761408961596f565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611467565b6000915050611467565b5092915050565b60008260000182815481106140ec576140ec614e22565b9060005260206000200154905092915050565b600081815260018301602052604081205461414657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611467565b506000611467565b508054600082559060005260206000209081019061396691906141c2565b8280548282559060005260206000209081019282156141b2579160200282015b828111156141b257825182906141a2908261545f565b509160200191906001019061418c565b506141be9291506141d7565b5090565b5b808211156141be57600081556001016141c3565b808211156141be5760006141eb82826141f4565b506001016141d7565b50805461420090615214565b6000825580601f10614210575050565b601f01602090049060005260206000209081019061396691906141c2565b60ff8116811461396657600080fd5b63ffffffff8116811461396657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156142a2576142a261424f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156142ef576142ef61424f565b604052919050565b600067ffffffffffffffff8211156143115761431161424f565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261434e57600080fd5b813561436161435c826142f7565b6142a8565b81815284602083860101111561437657600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461396657600080fd5b600080600080600080600060e0888a0312156143c857600080fd5b87356143d38161422e565b965060208801356143e38161423d565b955060408801356143f38161422e565b9450606088013567ffffffffffffffff81111561440f57600080fd5b61441b8a828b0161433d565b945050608088013561442c81614393565b9699959850939692959460a0840135945060c09093013592915050565b803561ffff8116811461445b57600080fd5b919050565b60008060006060848603121561447557600080fd5b8335925061448560208501614449565b9150604084013590509250925092565b600080604083850312156144a857600080fd5b82359150602083013567ffffffffffffffff8111156144c657600080fd5b6144d28582860161433d565b9150509250929050565b6000602082840312156144ee57600080fd5b5035919050565b60005b838110156145105781810151838201526020016144f8565b50506000910152565b600081518084526145318160208601602086016144f5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611c116020830184614519565b73ffffffffffffffffffffffffffffffffffffffff8116811461396657600080fd5b600080600080600080600060e0888a0312156145b357600080fd5b8735965060208801356145c581614576565b955060408801356145d58161422e565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b6000806040838503121561461057600080fd5b8235915061462060208401614449565b90509250929050565b60006020828403121561463b57600080fd5b8135611c1181614576565b60008083601f84011261465857600080fd5b50813567ffffffffffffffff81111561467057600080fd5b6020830191508360208260051b85010111156116bb57600080fd5b600080600080600080600060c0888a0312156146a657600080fd5b873567ffffffffffffffff8111156146bd57600080fd5b6146c98a828b01614646565b90985096505060208801356146dd8161422e565b96999598509596604081013596506060810135956080820135955060a0909101359350915050565b60008060006060848603121561471a57600080fd5b505081359360208301359350604090920135919050565b6020815261475860208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614771604084018263ffffffff169052565b50604083015161014080606085015261478e610160850183614519565b915060608501516147af60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e085015161010061481b818701836bffffffffffffffffffffffff169052565b86015190506101206148308682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018387015290506148688382614519565b9695505050505050565b6000806020838503121561488557600080fd5b823567ffffffffffffffff81111561489c57600080fd5b6148a885828601614646565b90969095509350505050565b60008083601f8401126148c657600080fd5b50813567ffffffffffffffff8111156148de57600080fd5b6020830191508360208285010111156116bb57600080fd5b6000806020838503121561490957600080fd5b823567ffffffffffffffff81111561492057600080fd5b6148a8858286016148b4565b6020808252825182820181905260009190848201906040850190845b8181101561496457835183529284019291840191600101614948565b50909695505050505050565b600067ffffffffffffffff82111561498a5761498a61424f565b5060051b60200190565b600080604083850312156149a757600080fd5b823567ffffffffffffffff808211156149bf57600080fd5b818501915085601f8301126149d357600080fd5b813560206149e361435c83614970565b82815260059290921b84018101918181019089841115614a0257600080fd5b8286015b84811015614a3a57803586811115614a1e5760008081fd5b614a2c8c86838b010161433d565b845250918301918301614a06565b5096505086013592505080821115614a5157600080fd5b506144d28582860161433d565b8215158152604060208201526000611c0e6040830184614519565b600080600060408486031215614a8e57600080fd5b833567ffffffffffffffff811115614aa557600080fd5b614ab186828701614646565b9094509250506020840135614ac58161423d565b809150509250925092565b60008060408385031215614ae357600080fd5b50508035926020909101359150565b600080600060408486031215614b0757600080fd5b83359250602084013567ffffffffffffffff811115614b2557600080fd5b614b31868287016148b4565b9497909650939450505050565b60008060408385031215614b5157600080fd5b823567ffffffffffffffff80821115614b6957600080fd5b614b758683870161433d565b93506020850135915080821115614a5157600080fd5b60006020808385031215614b9e57600080fd5b823567ffffffffffffffff80821115614bb657600080fd5b818501915085601f830112614bca57600080fd5b8135614bd861435c82614970565b81815260059190911b83018401908481019088831115614bf757600080fd5b8585015b83811015614c2f57803585811115614c135760008081fd5b614c218b89838a010161433d565b845250918601918601614bfb565b5098975050505050505050565b60008060408385031215614c4f57600080fd5b823591506020830135614c6181614393565b809150509250929050565b600060208284031215614c7e57600080fd5b8135611c118161422e565b60008060408385031215614c9c57600080fd5b823591506020830135614c618161423d565b60008060408385031215614cc157600080fd5b823591506020830135614c618161422e565b60008060008060608587031215614ce957600080fd5b843567ffffffffffffffff811115614d0057600080fd5b614d0c87828801614646565b9095509350506020850135614d208161422e565b91506040850135614d308161422e565b939692955090935050565b60008060008060008060c08789031215614d5457600080fd5b8635614d5f81614576565b95506020870135614d6f8161422e565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80831681851681830481118215151615614dee57614dee614d94565b02949350505050565b8051801515811461445b57600080fd5b600060208284031215614e1957600080fd5b611c1182614df7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103614e6757614e67614d94565b60010192915050565b828152604060208201526000611c0e6040830184614519565b600082601f830112614e9a57600080fd5b8151614ea861435c826142f7565b818152846020838601011115614ebd57600080fd5b614ece8260208301602087016144f5565b949350505050565b600060208284031215614ee857600080fd5b815167ffffffffffffffff811115614eff57600080fd5b614ece84828501614e89565b805161445b81614393565b600060208284031215614f2857600080fd5b8151611c1181614393565b805161445b81614576565b60008060408385031215614f5157600080fd5b8251614f5c81614576565b6020939093015192949293505050565b600060208284031215614f7e57600080fd5b8151611c1181614576565b600060208284031215614f9b57600080fd5b8151611c118161422e565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614fd757614fd7614d94565b5060010190565b805161445b8161423d565b805167ffffffffffffffff8116811461445b57600080fd5b60006020828403121561501357600080fd5b815167ffffffffffffffff8082111561502b57600080fd5b90830190610140828603121561504057600080fd5b61504861427e565b61505183614f33565b815261505f60208401614fde565b602082015260408301518281111561507657600080fd5b61508287828601614e89565b60408301525061509460608401614f0b565b60608201526150a560808401614f33565b60808201526150b660a08401614fe9565b60a08201526150c760c08401614fde565b60c08201526150d860e08401614f0b565b60e08201526101006150eb818501614df7565b90820152610120838101518381111561510357600080fd5b61510f88828701614e89565b918301919091525095945050505050565b8082018082111561146757611467614d94565b600061ffff80831681810361514a5761514a614d94565b6001019392505050565b60006020828403121561516657600080fd5b5051919050565b8181038181111561146757611467614d94565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156151f5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08887030185526151e3868351614519565b955093820193908201906001016151a9565b50508584038187015250505061520b8185614519565b95945050505050565b600181811c9082168061522857607f821691505b602082108103615261577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000815461527481615214565b80855260206001838116801561529157600181146152c9576152f7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b89010195506152f7565b866000528260002060005b858110156152ef5781548a82018601529083019084016152d4565b890184019650505b505050505092915050565b60a08152600061531560a0830188615267565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015615387577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526153758383615267565b9486019492506001918201910161533c565b5050868103604088015261539b818b615267565b94505050505084606084015282810360808401526153b98185614519565b98975050505050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b601f82111561291d57600081815260208120601f850160051c810160208610156154405750805b601f850160051c820191505b818110156113a85782815560010161544c565b815167ffffffffffffffff8111156154795761547961424f565b61548d816154878454615214565b84615419565b602080601f8311600181146154e057600084156154aa5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556113a8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561552d5788860151825594840194600190910190840161550e565b508582101561556957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080838503121561558c57600080fd5b825167ffffffffffffffff8111156155a357600080fd5b8301601f810185136155b457600080fd5b80516155c261435c82614970565b81815260059190911b820183019083810190878311156155e157600080fd5b928401925b828410156155ff578351825292840192908401906155e6565b979650505050505050565b600063ffffffff80831681810361514a5761514a614d94565b80516020808301519190811015615261577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b6020815260008251610140806020850152615684610160850183614519565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030160408701526156c08483614519565b9350604087015191506156eb606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e087015261574c8483614519565b935060e0870151915061010081878603018188015261576b8584614519565b94508088015192505061012081878603018188015261578a8584614519565b945080880151925050506157ad828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156157ef576157ef614d94565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615832576158326157f4565b500490565b81810360008312801583831316838312821617156140ce576140ce614d94565b600082615866576158666157f4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158ba576158ba614d94565b500590565b80820182811260008312801582168215821617156158df576158df614d94565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614fd757614fd7614d94565b60007f8000000000000000000000000000000000000000000000000000000000000000820361594957615949614d94565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", + Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080527fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d60a0526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460e0526101c0604052604261014081815261010091829190620061d161016039815260200160405180608001604052806042815260200162006213604291399052620000be906016906002620003c7565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000ee908262000543565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b602082015260189062000120908262000543565b503480156200012e57600080fd5b506040516200625538038062006255833981016040819052620001519162000625565b81813380600081620001aa5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001dd57620001dd816200031c565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200023a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000260919062000668565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec919062000699565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560c05250620006c0915050565b336001600160a01b03821603620003765760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620001a1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821562000412579160200282015b8281111562000412578251829062000401908262000543565b5091602001919060010190620003e8565b506200042092915062000424565b5090565b80821115620004205760006200043b828262000445565b5060010162000424565b5080546200045390620004b4565b6000825580601f1062000464575050565b601f01602090049060005260206000209081019062000484919062000487565b50565b5b8082111562000420576000815560010162000488565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c957607f821691505b602082108103620004ea57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053e57600081815260208120601f850160051c81016020861015620005195750805b601f850160051c820191505b818110156200053a5782815560010162000525565b5050505b505050565b81516001600160401b038111156200055f576200055f6200049e565b6200057781620005708454620004b4565b84620004f0565b602080601f831160018114620005af5760008415620005965750858301515b600019600386901b1c1916600185901b1785556200053a565b600085815260208120601f198616915b82811015620005e057888601518255948401946001909101908401620005bf565b5085821015620005ff5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200048457600080fd5b600080604083850312156200063957600080fd5b825162000646816200060f565b602084015190925080151581146200065d57600080fd5b809150509250929050565b600080604083850312156200067c57600080fd5b825162000689816200060f565b6020939093015192949293505050565b600060208284031215620006ac57600080fd5b8151620006b9816200060f565b9392505050565b60805160a05160c05160e051615abb62000716600039600081816105680152611f7a0152600081816109bc0152613ca701526000818161082701526136f5015260008181610d7901526136ca0152615abb6000f3fe6080604052600436106104d55760003560e01c806379ea994311610279578063a6b594751161015e578063d6051a72116100d6578063e45530831161008a578063fa333dfb1161006f578063fa333dfb14610f88578063fba7ffa31461103b578063fcdc1f631461106857600080fd5b8063e455308314610f52578063f2fde38b14610f6857600080fd5b8063daee1aeb116100bb578063daee1aeb14610ee5578063dbef701e14610f05578063e0114adb14610f2557600080fd5b8063d6051a7214610ea5578063da6cba4714610ec557600080fd5b8063b657bc9c1161012d578063c041982211610112578063c041982214610e50578063c98f10b014610e70578063d4c2490014610e8557600080fd5b8063b657bc9c14610e10578063becde0e114610e3057600080fd5b8063a6b5947514610d9b578063a72aa27e14610dbb578063af953a4a14610ddb578063afb28d1f14610dfb57600080fd5b8063924ca578116101f15780639b429354116101c05780639d385eaa116101a55780639d385eaa14610d275780639d6f1cc714610d47578063a654824814610d6757600080fd5b80639b42935414610cc95780639b51fb0d14610cf657600080fd5b8063924ca57814610c3f578063948108f714610c5f57806396cebc7c14610c7f5780639ac542eb14610c9f57600080fd5b80638340507c11610248578063873c75861161022d578063873c758614610bc75780638da5cb5b14610be75780638fcb3fba14610c1257600080fd5b80638340507c14610b8757806386e330af14610ba757600080fd5b806379ea994314610afa5780637b10399914610b1a5780637e7a46dc14610b475780638243444a14610b6757600080fd5b806345d2ec17116103ba57806360457ff5116103325780637145f11b116102e657806376721303116102cb5780637672130314610a98578063776898c814610ac557806379ba509714610ae557600080fd5b80637145f11b14610a3b57806373644cce14610a6b57600080fd5b8063642f6cef11610317578063642f6cef146109aa57806369cdbadb146109ee5780636e04ff0d14610a1b57600080fd5b806360457ff514610958578063636092e81461098557600080fd5b80635147cd591161038957806357970e931161036e57806357970e93146108f65780635d4ee7f3146109235780635f17e6161461093857600080fd5b80635147cd59146108a457806351c98be3146108d657600080fd5b806345d2ec17146107e8578063469820931461081557806346e7a63e146108495780634b56a42e1461087657600080fd5b806320e3dbd41161044d5780632a9032d31161041c578063328ffd1111610401578063328ffd111461077b5780633ebe8d6c146107a85780634585e33b146107c857600080fd5b80632a9032d3146107095780632b20e3971461072957600080fd5b806320e3dbd41461067c5780632636aecf1461069c57806328c4b57b146106bc57806329e0a841146106dc57600080fd5b806319d97a94116104a45780631e010439116104895780631e010439146105ea578063206c32e814610627578063207b65161461065c57600080fd5b806319d97a941461059d5780631cdde251146105ca57600080fd5b806306c1cc00146104e1578063077ac621146105035780630b7d33e61461053657806312c550271461055657600080fd5b366104dc57005b600080fd5b3480156104ed57600080fd5b506105016104fc366004614429565b611095565b005b34801561050f57600080fd5b5061052361051e3660046144dc565b6112e4565b6040519081526020015b60405180910390f35b34801561054257600080fd5b50610501610551366004614511565b611322565b34801561056257600080fd5b5061058a7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161052d565b3480156105a957600080fd5b506105bd6105b8366004614558565b6113b0565b60405161052d91906145df565b3480156105d657600080fd5b506105016105e5366004614614565b61146d565b3480156105f657600080fd5b5061060a610605366004614558565b6115aa565b6040516bffffffffffffffffffffffff909116815260200161052d565b34801561063357600080fd5b50610647610642366004614679565b61163f565b6040805192835260208301919091520161052d565b34801561066857600080fd5b506105bd610677366004614558565b6116c2565b34801561068857600080fd5b506105016106973660046146a5565b61171a565b3480156106a857600080fd5b506105016106b7366004614707565b6118e4565b3480156106c857600080fd5b506105236106d7366004614781565b611bad565b3480156106e857600080fd5b506106fc6106f7366004614558565b611c18565b60405161052d91906147ad565b34801561071557600080fd5b506105016107243660046148ee565b611d1d565b34801561073557600080fd5b506011546107569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161052d565b34801561078757600080fd5b50610523610796366004614558565b60036020526000908152604090205481565b3480156107b457600080fd5b506105236107c3366004614558565b611dfe565b3480156107d457600080fd5b506105016107e3366004614972565b611e67565b3480156107f457600080fd5b50610808610803366004614679565b612086565b60405161052d91906149a8565b34801561082157600080fd5b506105237f000000000000000000000000000000000000000000000000000000000000000081565b34801561085557600080fd5b50610523610864366004614558565b600a6020526000908152604090205481565b34801561088257600080fd5b50610896610891366004614a10565b6120f5565b60405161052d929190614ada565b3480156108b057600080fd5b506108c46108bf366004614558565b612149565b60405160ff909116815260200161052d565b3480156108e257600080fd5b506105016108f1366004614af5565b6121dd565b34801561090257600080fd5b506012546107569073ffffffffffffffffffffffffffffffffffffffff1681565b34801561092f57600080fd5b50610501612281565b34801561094457600080fd5b50610501610953366004614b4c565b6123bc565b34801561096457600080fd5b50610523610973366004614558565b60076020526000908152604090205481565b34801561099157600080fd5b5060155461060a906bffffffffffffffffffffffff1681565b3480156109b657600080fd5b506109de7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161052d565b3480156109fa57600080fd5b50610523610a09366004614558565b60086020526000908152604090205481565b348015610a2757600080fd5b50610896610a36366004614972565b612489565b348015610a4757600080fd5b506109de610a56366004614558565b600b6020526000908152604090205460ff1681565b348015610a7757600080fd5b50610523610a86366004614558565b6000908152600c602052604090205490565b348015610aa457600080fd5b50610523610ab3366004614558565b60046020526000908152604090205481565b348015610ad157600080fd5b506109de610ae0366004614558565b6126b2565b348015610af157600080fd5b50610501612704565b348015610b0657600080fd5b50610756610b15366004614558565b612801565b348015610b2657600080fd5b506013546107569073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b5357600080fd5b50610501610b62366004614b6e565b612895565b348015610b7357600080fd5b50610501610b82366004614b6e565b612926565b348015610b9357600080fd5b50610501610ba2366004614bba565b612980565b348015610bb357600080fd5b50610501610bc2366004614c07565b61299e565b348015610bd357600080fd5b50610808610be2366004614b4c565b6129b1565b348015610bf357600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610756565b348015610c1e57600080fd5b50610523610c2d366004614558565b60056020526000908152604090205481565b348015610c4b57600080fd5b50610501610c5a366004614b4c565b612a6e565b348015610c6b57600080fd5b50610501610c7a366004614cb8565b612cb3565b348015610c8b57600080fd5b50610501610c9a366004614ce8565b612dcb565b348015610cab57600080fd5b506015546108c4906c01000000000000000000000000900460ff1681565b348015610cd557600080fd5b50610501610ce4366004614b4c565b60009182526009602052604090912055565b348015610d0257600080fd5b5061058a610d11366004614558565b600e6020526000908152604090205461ffff1681565b348015610d3357600080fd5b50610808610d42366004614558565b612fd5565b348015610d5357600080fd5b506105bd610d62366004614558565b613037565b348015610d7357600080fd5b506105237f000000000000000000000000000000000000000000000000000000000000000081565b348015610da757600080fd5b50610501610db6366004614781565b6130e3565b348015610dc757600080fd5b50610501610dd6366004614d05565b61314c565b348015610de757600080fd5b50610501610df6366004614558565b6131f7565b348015610e0757600080fd5b506105bd61327d565b348015610e1c57600080fd5b5061060a610e2b366004614558565b61328a565b348015610e3c57600080fd5b50610501610e4b3660046148ee565b6132e2565b348015610e5c57600080fd5b50610808610e6b366004614b4c565b61337c565b348015610e7c57600080fd5b506105bd613479565b348015610e9157600080fd5b50610501610ea0366004614d2a565b613486565b348015610eb157600080fd5b50610647610ec0366004614b4c565b613505565b348015610ed157600080fd5b50610501610ee0366004614d4f565b61356e565b348015610ef157600080fd5b50610501610f003660046148ee565b6138d5565b348015610f1157600080fd5b50610523610f20366004614b4c565b6139a0565b348015610f3157600080fd5b50610523610f40366004614558565b60096020526000908152604090205481565b348015610f5e57600080fd5b5061052360145481565b348015610f7457600080fd5b50610501610f833660046146a5565b6139d1565b348015610f9457600080fd5b506105bd610fa3366004614db7565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b34801561104757600080fd5b50610523611056366004614558565b60066020526000908152604090205481565b34801561107457600080fd5b50610523611083366004614558565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b392169061117b908c1688614e3f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af11580156111f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121d9190614e83565b5060008860ff1667ffffffffffffffff81111561123c5761123c6142cb565b604051908082528060200260200182016040528015611265578160200160208202803683370190505b50905060005b8960ff168160ff1610156112d8576000611284846139e5565b905080838360ff168151811061129c5761129c614e9e565b602090810291909101810191909152600091825260088152604080832088905560079091529020849055806112d081614ecd565b91505061126b565b50505050505050505050565b600d602052826000526040600020602052816000526040600020818154811061130c57600080fd5b9060005260206000200160009250925050505481565b6013546040517f0b7d33e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690630b7d33e69061137a9085908590600401614eec565b600060405180830381600087803b15801561139457600080fd5b505af11580156113a8573d6000803e3d6000fd5b505050505050565b6013546040517f19d97a940000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff16906319d97a94906024015b600060405180830381865afa158015611421573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114679190810190614f52565b92915050565b6013546040517ffa333dfb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015260ff8816602483015260448201879052606482018690526084820185905260a4820184905290911690634ee88d35908990309063fa333dfb9060c401600060405180830381865afa15801561150c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115529190810190614f52565b6040518363ffffffff1660e01b815260040161156f929190614eec565b600060405180830381600087803b15801561158957600080fd5b505af115801561159d573d6000803e3d6000fd5b5050505050505050505050565b6013546040517f1e0104390000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690631e010439906024015b602060405180830381865afa15801561161b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190614f92565b6000828152600d6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156116a357602002820191906000526020600020905b81548152602001906001019080831161168f575b505050505090506116b5818251613ab3565b92509250505b9250929050565b6013546040517f207b65160000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063207b651690602401611404565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa1580156117b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d49190614fba565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015611877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189b9190614fe8565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b8560005b81811015611ba257600089898381811061190457611904614e9e565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161193d91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611969929190614eec565b600060405180830381600087803b15801561198357600080fd5b505af1158015611997573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015611a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a319190615005565b90508060ff16600103611b8d576040517ffa333dfb000000000000000000000000000000000000000000000000000000008152306004820181905260ff8b166024830152604482018a9052606482018890526084820188905260a4820187905260009163fa333dfb9060c401600060405180830381865afa158015611aba573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611b009190810190614f52565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590611b599086908590600401614eec565b600060405180830381600087803b158015611b7357600080fd5b505af1158015611b87573d6000803e3d6000fd5b50505050505b50508080611b9a90615022565b9150506118e8565b505050505050505050565b6000838152600c602090815260408083208054825181850281018501909352808352611c0e93830182828015611c0257602002820191906000526020600020905b815481526020019060010190808311611bee575b50505050508484613b38565b90505b9392505050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c7c3a19a90602401600060405180830381865afa158015611cd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611467919081019061507d565b8060005b818160ff161015611df85760135473ffffffffffffffffffffffffffffffffffffffff1663c8048022858560ff8516818110611d5f57611d5f614e9e565b905060200201356040518263ffffffff1660e01b8152600401611d8491815260200190565b600060405180830381600087803b158015611d9e57600080fd5b505af1158015611db2573d6000803e3d6000fd5b50505050611de584848360ff16818110611dce57611dce614e9e565b90506020020135600f613c9790919063ffffffff16565b5080611df081614ecd565b915050611d21565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611e5f576000858152600d6020908152604080832061ffff85168452909152902054611e4b908361519c565b915080611e57816151af565b915050611e14565b509392505050565b60005a9050600080611e7b84860186614a10565b91509150600081806020019051810190611e9591906151d0565b60008181526005602090815260408083205460049092528220549293509190611ebc613ca3565b905082600003611edc576000848152600560205260409020819055612037565b600084815260036020526040812054611ef584846151e9565b611eff91906151e9565b6000868152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611f7157602002820191906000526020600020905b815481526020019060010190808311611f5d575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611fec5781611fae816151af565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b60008481526006602052604081205461205190600161519c565b600086815260066020908152604080832084905560049091529020839055905061207b8583612a6e565b6112d88589846130e3565b6000828152600d6020908152604080832061ffff851684528252918290208054835181840281018401909452808452606093928301828280156120e857602002820191906000526020600020905b8154815260200190600101908083116120d4575b5050505050905092915050565b600060606000848460405160200161210e9291906151fc565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b6013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690635147cd5990602401602060405180830381865afa1580156121b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190615005565b8160005b8181101561227a5730635f17e61686868481811061220157612201614e9e565b90506020020135856040518363ffffffff1660e01b815260040161223592919091825263ffffffff16602082015260400190565b600060405180830381600087803b15801561224f57600080fd5b505af1158015612263573d6000803e3d6000fd5b50505050808061227290615022565b9150506121e1565b5050505050565b612289613d45565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156122f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231c91906151d0565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015612394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b89190614e83565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c90915281206123f4916141ca565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611612450576000848152600d6020908152604080832061ffff85168452909152812061243e916141ca565b80612448816151af565b915050612409565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a905060006124a085870187614558565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff8111156124d9576124d96142cb565b6040519080825280601f01601f191660200182016040528015612503576020820181803683370190505b50604051602001612515929190614eec565b60405160208183030381529060405290506000612530613ca3565b9050600061253d866126b2565b90505b835a61254c90896151e9565b6125589061271061519c565b10156125995781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612540565b806125b15760008398509850505050505050506116bb565b6040517f6665656449644865780000000000000000000000000000000000000000000000602082015260009060290160405160208183030381529060405280519060200120601860405160200161260891906152e3565b604051602081830303815290604052805190602001200361262a57508161262d565b50425b601760166018838a60405160200161264791815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527ff055e4a20000000000000000000000000000000000000000000000000000000082526126a99594939291600401615412565b60405180910390fd5b60008181526005602052604081205481036126cf57506001919050565b6000828152600360209081526040808320546004909252909120546126f2613ca3565b6126fc91906151e9565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612785576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016126a9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517f79ea99430000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff16906379ea994390602401602060405180830381865afa158015612871573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190614fe8565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b5906128ef908690869086906004016154d5565b600060405180830381600087803b15801561290957600080fd5b505af115801561291d573d6000803e3d6000fd5b50505050505050565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634ee88d35906128ef908690869086906004016154d5565b601761298c838261556f565b506018612999828261556f565b505050565b80516123b89060169060208401906141e8565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260609173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611c119190810190615689565b601454600083815260026020526040902054612a8a90836151e9565b11156123b8576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612b00573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612b46919081019061507d565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa158015612bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bdf9190614f92565b601554909150612c039082906c01000000000000000000000000900460ff16614e3f565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611df857601554612c469085906bffffffffffffffffffffffff16612cb3565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af1158015612d3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5f9190614e83565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f79060440161137a565b6040517fc04198220000000000000000000000000000000000000000000000000000000081526000600482018190526024820181905290309063c041982290604401600060405180830381865afa158015612e2a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612e709190810190615689565b80519091506000612e7f613ca3565b905060005b8281101561227a576000848281518110612ea057612ea0614e9e565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015612f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f449190615005565b90508060ff16600103612fc0578660ff16600003612f90576040513090859084907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4612fc0565b6040513090859084907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a45b50508080612fcd90615022565b915050612e84565b6000818152600c602090815260409182902080548351818402810184019094528084526060939283018282801561302b57602002820191906000526020600020905b815481526020019060010190808311613017575b50505050509050919050565b6016818154811061304757600080fd5b90600052602060002001600091509050805461306290615290565b80601f016020809104026020016040519081016040528092919081815260200182805461308e90615290565b80156130db5780601f106130b0576101008083540402835291602001916130db565b820191906000526020600020905b8154815290600101906020018083116130be57829003601f168201915b505050505081565b6000838152600760205260409020545b805a6130ff90856151e9565b61310b9061271061519c565b1015611df85781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556130f3565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b1580156131c457600080fd5b505af11580156131d8573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b15801561326957600080fd5b505af115801561227a573d6000803e3d6000fd5b6017805461306290615290565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff169063b657bc9c906024016115fe565b8060005b818163ffffffff161015611df8573063af953a4a858563ffffffff851681811061331257613312614e9e565b905060200201356040518263ffffffff1660e01b815260040161333791815260200190565b600060405180830381600087803b15801561335157600080fd5b505af1158015613365573d6000803e3d6000fd5b5050505080806133749061571a565b9150506132e6565b6060600061338a600f613dc8565b90508084106133c5576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036133da576133d784826151e9565b92505b60008367ffffffffffffffff8111156133f5576133f56142cb565b60405190808252806020026020018201604052801561341e578160200160208202803683370190505b50905060005b8481101561347057613441613439828861519c565b600f90613dd2565b82828151811061345357613453614e9e565b60209081029190910101528061346881615022565b915050613424565b50949350505050565b6018805461306290615290565b6000613490613ca3565b90508160ff166000036134d1576040513090829085907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4505050565b6040513090829085907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a4505050565b6000828152600c6020908152604080832080548251818502810185019093528083528493849392919083018282801561355d57602002820191906000526020600020905b815481526020019060010190808311613549575b505050505090506116b58185613ab3565b8260005b818110156113a857600086868381811061358e5761358e614e9e565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc82836040516020016135c791815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016135f3929190614eec565b600060405180830381600087803b15801561360d57600080fd5b505af1158015613621573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015613697573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136bb9190615005565b90508060ff166001036138c0577f000000000000000000000000000000000000000000000000000000000000000060ff87161561371557507f00000000000000000000000000000000000000000000000000000000000000005b60003073ffffffffffffffffffffffffffffffffffffffff1663fa333dfb3089858860405160200161374991815260200190565b60405160208183030381529060405261376190615733565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff909416600485015260ff90921660248401526044830152606482015260006084820181905260a482015260c401600060405180830381865afa1580156137ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526138329190810190614f52565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d359061388b9087908590600401614eec565b600060405180830381600087803b1580156138a557600080fd5b505af11580156138b9573d6000803e3d6000fd5b5050505050505b505080806138cd90615022565b915050613572565b8060005b81811015611df85760008484838181106138f5576138f5614e9e565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161392e91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161395a929190614eec565b600060405180830381600087803b15801561397457600080fd5b505af1158015613988573d6000803e3d6000fd5b5050505050808061399890615022565b9150506138d9565b600c60205281600052604060002081815481106139bc57600080fd5b90600052602060002001600091509150505481565b6139d9613d45565b6139e281613dde565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190613a40908690600401615775565b6020604051808303816000875af1158015613a5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a8391906151d0565b9050613a90600f82613ed3565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b815160009081908190841580613ac95750808510155b15613ad2578094505b60008092505b85831015613b2e57866001613aed85856151e9565b613af791906151e9565b81518110613b0757613b07614e9e565b602002602001015181613b1a919061519c565b905082613b2681615022565b935050613ad8565b9694955050505050565b82516000908190831580613b4c5750808410155b15613b55578093505b60008467ffffffffffffffff811115613b7057613b706142cb565b604051908082528060200260200182016040528015613b99578160200160208202803683370190505b509050600092505b84831015613c0757866001613bb685856151e9565b613bc091906151e9565b81518110613bd057613bd0614e9e565b6020026020010151818481518110613bea57613bea614e9e565b602090810291909101015282613bff81615022565b935050613ba1565b613c2081600060018451613c1b91906151e9565b613edf565b85606403613c59578060018251613c3791906151e9565b81518110613c4757613c47614e9e565b60200260200101519350505050611c11565b806064825188613c6991906158c7565b613c739190615933565b81518110613c8357613c83614e9e565b602002602001015193505050509392505050565b6000611c118383614057565b60007f000000000000000000000000000000000000000000000000000000000000000015613d4057606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d3b91906151d0565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff163314613dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016126a9565b565b6000611467825490565b6000611c118383614151565b3373ffffffffffffffffffffffffffffffffffffffff821603613e5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016126a9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611c11838361417b565b8181808203613eef575050505050565b6000856002613efe8787615947565b613f089190615967565b613f1290876159cf565b81518110613f2257613f22614e9e565b602002602001015190505b818313614031575b80868481518110613f4857613f48614e9e565b60200260200101511015613f685782613f60816159f7565b935050613f35565b858281518110613f7a57613f7a614e9e565b6020026020010151811015613f9b5781613f9381615a28565b925050613f68565b81831361402c57858281518110613fb457613fb4614e9e565b6020026020010151868481518110613fce57613fce614e9e565b6020026020010151878581518110613fe857613fe8614e9e565b6020026020010188858151811061400157614001614e9e565b6020908102919091010191909152528261401a816159f7565b935050818061402890615a28565b9250505b613f2d565b8185121561404457614044868684613edf565b838312156113a8576113a8868486613edf565b6000818152600183016020526040812054801561414057600061407b6001836151e9565b855490915060009061408f906001906151e9565b90508181146140f45760008660000182815481106140af576140af614e9e565b90600052602060002001549050808760000184815481106140d2576140d2614e9e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061410557614105615a7f565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611467565b6000915050611467565b5092915050565b600082600001828154811061416857614168614e9e565b9060005260206000200154905092915050565b60008181526001830160205260408120546141c257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611467565b506000611467565b50805460008255906000526020600020908101906139e2919061423e565b82805482825590600052602060002090810192821561422e579160200282015b8281111561422e578251829061421e908261556f565b5091602001919060010190614208565b5061423a929150614253565b5090565b5b8082111561423a576000815560010161423f565b8082111561423a5760006142678282614270565b50600101614253565b50805461427c90615290565b6000825580601f1061428c575050565b601f0160209004906000526020600020908101906139e2919061423e565b60ff811681146139e257600080fd5b63ffffffff811681146139e257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561431e5761431e6142cb565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561436b5761436b6142cb565b604052919050565b600067ffffffffffffffff82111561438d5761438d6142cb565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126143ca57600080fd5b81356143dd6143d882614373565b614324565b8181528460208386010111156143f257600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff811681146139e257600080fd5b600080600080600080600060e0888a03121561444457600080fd5b873561444f816142aa565b9650602088013561445f816142b9565b9550604088013561446f816142aa565b9450606088013567ffffffffffffffff81111561448b57600080fd5b6144978a828b016143b9565b94505060808801356144a88161440f565b9699959850939692959460a0840135945060c09093013592915050565b803561ffff811681146144d757600080fd5b919050565b6000806000606084860312156144f157600080fd5b83359250614501602085016144c5565b9150604084013590509250925092565b6000806040838503121561452457600080fd5b82359150602083013567ffffffffffffffff81111561454257600080fd5b61454e858286016143b9565b9150509250929050565b60006020828403121561456a57600080fd5b5035919050565b60005b8381101561458c578181015183820152602001614574565b50506000910152565b600081518084526145ad816020860160208601614571565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611c116020830184614595565b73ffffffffffffffffffffffffffffffffffffffff811681146139e257600080fd5b600080600080600080600060e0888a03121561462f57600080fd5b873596506020880135614641816145f2565b95506040880135614651816142aa565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b6000806040838503121561468c57600080fd5b8235915061469c602084016144c5565b90509250929050565b6000602082840312156146b757600080fd5b8135611c11816145f2565b60008083601f8401126146d457600080fd5b50813567ffffffffffffffff8111156146ec57600080fd5b6020830191508360208260051b85010111156116bb57600080fd5b600080600080600080600060c0888a03121561472257600080fd5b873567ffffffffffffffff81111561473957600080fd5b6147458a828b016146c2565b9098509650506020880135614759816142aa565b96999598509596604081013596506060810135956080820135955060a0909101359350915050565b60008060006060848603121561479657600080fd5b505081359360208301359350604090920135919050565b602081526147d460208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516147ed604084018263ffffffff169052565b50604083015161014080606085015261480a610160850183614595565b9150606085015161482b60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614897818701836bffffffffffffffffffffffff169052565b86015190506101206148ac8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018387015290506148e48382614595565b9695505050505050565b6000806020838503121561490157600080fd5b823567ffffffffffffffff81111561491857600080fd5b614924858286016146c2565b90969095509350505050565b60008083601f84011261494257600080fd5b50813567ffffffffffffffff81111561495a57600080fd5b6020830191508360208285010111156116bb57600080fd5b6000806020838503121561498557600080fd5b823567ffffffffffffffff81111561499c57600080fd5b61492485828601614930565b6020808252825182820181905260009190848201906040850190845b818110156149e0578351835292840192918401916001016149c4565b50909695505050505050565b600067ffffffffffffffff821115614a0657614a066142cb565b5060051b60200190565b60008060408385031215614a2357600080fd5b823567ffffffffffffffff80821115614a3b57600080fd5b818501915085601f830112614a4f57600080fd5b81356020614a5f6143d8836149ec565b82815260059290921b84018101918181019089841115614a7e57600080fd5b8286015b84811015614ab657803586811115614a9a5760008081fd5b614aa88c86838b01016143b9565b845250918301918301614a82565b5096505086013592505080821115614acd57600080fd5b5061454e858286016143b9565b8215158152604060208201526000611c0e6040830184614595565b600080600060408486031215614b0a57600080fd5b833567ffffffffffffffff811115614b2157600080fd5b614b2d868287016146c2565b9094509250506020840135614b41816142b9565b809150509250925092565b60008060408385031215614b5f57600080fd5b50508035926020909101359150565b600080600060408486031215614b8357600080fd5b83359250602084013567ffffffffffffffff811115614ba157600080fd5b614bad86828701614930565b9497909650939450505050565b60008060408385031215614bcd57600080fd5b823567ffffffffffffffff80821115614be557600080fd5b614bf1868387016143b9565b93506020850135915080821115614acd57600080fd5b60006020808385031215614c1a57600080fd5b823567ffffffffffffffff80821115614c3257600080fd5b818501915085601f830112614c4657600080fd5b8135614c546143d8826149ec565b81815260059190911b83018401908481019088831115614c7357600080fd5b8585015b83811015614cab57803585811115614c8f5760008081fd5b614c9d8b89838a01016143b9565b845250918601918601614c77565b5098975050505050505050565b60008060408385031215614ccb57600080fd5b823591506020830135614cdd8161440f565b809150509250929050565b600060208284031215614cfa57600080fd5b8135611c11816142aa565b60008060408385031215614d1857600080fd5b823591506020830135614cdd816142b9565b60008060408385031215614d3d57600080fd5b823591506020830135614cdd816142aa565b60008060008060608587031215614d6557600080fd5b843567ffffffffffffffff811115614d7c57600080fd5b614d88878288016146c2565b9095509350506020850135614d9c816142aa565b91506040850135614dac816142aa565b939692955090935050565b60008060008060008060c08789031215614dd057600080fd5b8635614ddb816145f2565b95506020870135614deb816142aa565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80831681851681830481118215151615614e6a57614e6a614e10565b02949350505050565b805180151581146144d757600080fd5b600060208284031215614e9557600080fd5b611c1182614e73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103614ee357614ee3614e10565b60010192915050565b828152604060208201526000611c0e6040830184614595565b600082601f830112614f1657600080fd5b8151614f246143d882614373565b818152846020838601011115614f3957600080fd5b614f4a826020830160208701614571565b949350505050565b600060208284031215614f6457600080fd5b815167ffffffffffffffff811115614f7b57600080fd5b614f4a84828501614f05565b80516144d78161440f565b600060208284031215614fa457600080fd5b8151611c118161440f565b80516144d7816145f2565b60008060408385031215614fcd57600080fd5b8251614fd8816145f2565b6020939093015192949293505050565b600060208284031215614ffa57600080fd5b8151611c11816145f2565b60006020828403121561501757600080fd5b8151611c11816142aa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361505357615053614e10565b5060010190565b80516144d7816142b9565b805167ffffffffffffffff811681146144d757600080fd5b60006020828403121561508f57600080fd5b815167ffffffffffffffff808211156150a757600080fd5b9083019061014082860312156150bc57600080fd5b6150c46142fa565b6150cd83614faf565b81526150db6020840161505a565b60208201526040830151828111156150f257600080fd5b6150fe87828601614f05565b60408301525061511060608401614f87565b606082015261512160808401614faf565b608082015261513260a08401615065565b60a082015261514360c0840161505a565b60c082015261515460e08401614f87565b60e0820152610100615167818501614e73565b90820152610120838101518381111561517f57600080fd5b61518b88828701614f05565b918301919091525095945050505050565b8082018082111561146757611467614e10565b600061ffff8083168181036151c6576151c6614e10565b6001019392505050565b6000602082840312156151e257600080fd5b5051919050565b8181038181111561146757611467614e10565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015615271577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261525f868351614595565b95509382019390820190600101615225565b5050858403818701525050506152878185614595565b95945050505050565b600181811c908216806152a457607f821691505b6020821081036152dd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008083546152f181615290565b60018281168015615309576001811461533c5761536b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416875282151583028701945061536b565b8760005260208060002060005b858110156153625781548a820152908401908201615349565b50505082870194505b50929695505050505050565b6000815461538481615290565b8085526020600183811680156153a157600181146153d957615407565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550615407565b866000528260002060005b858110156153ff5781548a82018601529083019084016153e4565b890184019650505b505050505092915050565b60a08152600061542560a0830188615377565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015615497577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526154858383615377565b9486019492506001918201910161544c565b505086810360408801526154ab818b615377565b94505050505084606084015282810360808401526154c98185614595565b98975050505050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b601f82111561299957600081815260208120601f850160051c810160208610156155505750805b601f850160051c820191505b818110156113a85782815560010161555c565b815167ffffffffffffffff811115615589576155896142cb565b61559d816155978454615290565b84615529565b602080601f8311600181146155f057600084156155ba5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556113a8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561563d5788860151825594840194600190910190840161561e565b508582101561567957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080838503121561569c57600080fd5b825167ffffffffffffffff8111156156b357600080fd5b8301601f810185136156c457600080fd5b80516156d26143d8826149ec565b81815260059190911b820183019083810190878311156156f157600080fd5b928401925b8284101561570f578351825292840192908401906156f6565b979650505050505050565b600063ffffffff8083168181036151c6576151c6614e10565b805160208083015191908110156152dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b6020815260008251610140806020850152615794610160850183614595565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030160408701526157d08483614595565b9350604087015191506157fb606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e087015261585c8483614595565b935060e0870151915061010081878603018188015261587b8584614595565b94508088015192505061012081878603018188015261589a8584614595565b945080880151925050506158bd828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156158ff576158ff614e10565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261594257615942615904565b500490565b818103600083128015838313168383128216171561414a5761414a614e10565b60008261597657615976615904565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156159ca576159ca614e10565b500590565b80820182811260008312801582168215821617156159ef576159ef614e10565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361505357615053614e10565b60007f80000000000000000000000000000000000000000000000000000000000000008203615a5957615a59614e10565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", } var VerifiableLoadStreamsLookupUpkeepABI = VerifiableLoadStreamsLookupUpkeepMetaData.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 97b336b1885..d158a94937f 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 @@ -59,15 +59,15 @@ solidity_vrf_v08_verifier_wrapper: ../../contracts/solc/v0.8.6/VRFTestHelper.abi solidity_vrf_verifier_wrapper: ../../contracts/solc/v0.6/VRFTestHelper.abi ../../contracts/solc/v0.6/VRFTestHelper.bin 44c2b67d8d2990ab580453deb29d63508c6147a3dc49908a1db563bef06e6474 solidity_vrf_wrapper: ../../contracts/solc/v0.6/VRF.abi ../../contracts/solc/v0.6/VRF.bin 04ede5b83c06ba5b76ef99c081c72928007d8a7aaefcf21449a46a07cbd4bfc2 streams_lookup_compatible_interface: ../../contracts/solc/v0.8.16/StreamsLookupCompatibleInterface.abi ../../contracts/solc/v0.8.16/StreamsLookupCompatibleInterface.bin feb92cc666df21ea04ab9d7a588a513847b01b2f66fc167d06ab28ef2b17e015 -streams_lookup_upkeep_wrapper: ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.bin 4999afb752411696ec59210609b6deef45f519b18bd5e1450688062b3f7d0951 +streams_lookup_upkeep_wrapper: ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.bin a2c5a0ee6c85104609259ecdb09440f4eb115259f4283b2509e41e9c57aca265 test_api_consumer_wrapper: ../../contracts/solc/v0.6/TestAPIConsumer.abi ../../contracts/solc/v0.6/TestAPIConsumer.bin ed10893cb18894c18e275302329c955f14ea2de37ee044f84aa1e067ac5ea71e trusted_blockhash_store: ../../contracts/solc/v0.8.6/TrustedBlockhashStore.abi ../../contracts/solc/v0.8.6/TrustedBlockhashStore.bin a85d2899892aa9fd73fc99852ccba52c3983375113580673e6c5d655bfa79909 type_and_version_interface_wrapper: ../../contracts/solc/v0.8.6/TypeAndVersionInterface.abi ../../contracts/solc/v0.8.6/TypeAndVersionInterface.bin bc9c3a6e73e3ebd5b58754df0deeb3b33f4bb404d5709bb904aed51d32f4b45e upkeep_counter_wrapper: ../../contracts/solc/v0.7/UpkeepCounter.abi ../../contracts/solc/v0.7/UpkeepCounter.bin 901961ebf18906febc1c350f02da85c7ea1c2a68da70cfd94efa27c837a48663 upkeep_perform_counter_restrictive_wrapper: ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.abi ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.bin 8975a058fba528e16d8414dc6f13946d17a145fcbc66cf25a32449b6fe1ce878 upkeep_transcoder: ../../contracts/solc/v0.8.6/UpkeepTranscoder.abi ../../contracts/solc/v0.8.6/UpkeepTranscoder.bin 336c92a981597be26508455f81a908a0784a817b129a59686c5b2c4afcba730a -verifiable_load_log_trigger_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.bin 9d6f38552015d190c32671d785339716803b3b97223ea388e7a699d7f707494f -verifiable_load_streams_lookup_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.bin 4c02260ab1ab687536e13f417c048ee387c56c64d22a1b35ccd9bbc56f13ce50 +verifiable_load_log_trigger_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.bin 13f2238ad1ea1dfde87ea48d1d16a4939dc2c8ede399034c072b07deee9e642e +verifiable_load_streams_lookup_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.bin c626fb01272895f2a87ddd0f038c99bf46e9bedd4abd8dc102fe89ff3cb87a9a verifiable_load_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.bin a3e02c43756ea91e7ce4b81e48c11648f1d12f6663c236780147e41dfa36ebee vrf_consumer_v2: ../../contracts/solc/v0.8.6/VRFConsumerV2.abi ../../contracts/solc/v0.8.6/VRFConsumerV2.bin 9ef258bf8e9f8d880fd229ceb145593d91e24fc89366baa0bf19169c5787d15f vrf_consumer_v2_plus_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.bin 3155c611e4d6882e9324b6e975033b31356776ea8b031ca63d63da37589d583b From f2bcbbfb6b6ff96e0d5e5776dfe5f85aa769eceb Mon Sep 17 00:00:00 2001 From: Chris Cushman <104409744+vreff@users.noreply.github.com> Date: Mon, 11 Sep 2023 04:59:29 -0400 Subject: [PATCH 82/88] [VRF-616] Skip flaky VRF test (#10572) --- core/services/vrf/v2/integration_v2_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index a06920ece45..7c7e4122b0b 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -1318,6 +1318,7 @@ func TestVRFV2Integration_SingleConsumer_NeedsTrustedBlockhashStore(t *testing.T } func TestVRFV2Integration_SingleConsumer_NeedsTrustedBlockhashStore_AfterDelay(t *testing.T) { + t.Skip("TODO: VRF-616") t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 2, true) From dc3272d81d281204c0b89d1a52ab92b07e511f96 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:13:27 +0200 Subject: [PATCH 83/88] Add mercury contract wrappers (#10492) * Add mercury contract wrappers * Update contracts * Add VerifyBulk --- .../contracts/contract_loader.go | 43 +++++++++++++ .../contracts/contract_models.go | 11 ++++ .../contracts/ethereum_contracts.go | 64 +++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/integration-tests/contracts/contract_loader.go b/integration-tests/contracts/contract_loader.go index 7517ef7ba7e..2c079a61b8b 100644 --- a/integration-tests/contracts/contract_loader.go +++ b/integration-tests/contracts/contract_loader.go @@ -2,6 +2,7 @@ package contracts import ( "errors" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -12,6 +13,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" ) // ContractLoader is an interface for abstracting the contract loading methods across network implementations @@ -24,6 +27,10 @@ type ContractLoader interface { LoadFunctionsCoordinator(addr string) (FunctionsCoordinator, error) LoadFunctionsRouter(addr string) (FunctionsRouter, error) LoadFunctionsLoadTestClient(addr string) (FunctionsLoadTestClient, error) + + // Mercury + LoadMercuryVerifier(addr string) (MercuryVerifier, error) + LoadMercuryVerifierProxy(addr string) (MercuryVerifierProxy, error) } // NewContractLoader returns an instance of a contract Loader based on the client type @@ -189,3 +196,39 @@ func (e *EthereumContractLoader) LoadAuthorizedForwarder(address common.Address) authorizedForwarder: instance.(*authorized_forwarder.AuthorizedForwarder), }, err } + +// LoadMercuryVerifier returns Verifier contract deployed on given address +func (e *EthereumContractLoader) LoadMercuryVerifier(addr string) (MercuryVerifier, error) { + instance, err := e.client.LoadContract("Mercury Verifier", common.HexToAddress(addr), func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return verifier.NewVerifier(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryVerifier{ + client: e.client, + instance: instance.(*verifier.Verifier), + address: common.HexToAddress(addr), + }, err +} + +// LoadMercuryVerifierProxy returns VerifierProxy contract deployed on given address +func (e *EthereumContractLoader) LoadMercuryVerifierProxy(addr string) (MercuryVerifierProxy, error) { + instance, err := e.client.LoadContract("Mercury Verifier Proxy", common.HexToAddress(addr), func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return verifier_proxy.NewVerifierProxy(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryVerifierProxy{ + client: e.client, + instance: instance.(*verifier_proxy.VerifierProxy), + address: common.HexToAddress(addr), + }, err +} diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index 8e9d561f822..7bcddceae5e 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -367,3 +367,14 @@ type FunctionsLoadTestClient interface { SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error SendRequestWithDONHostedSecrets(times uint32, source string, slotID uint8, slotVersion uint64, args []string, subscriptionId uint64, donID [32]byte) error } + +type MercuryVerifier interface { + Address() string + Verify(signedReport []byte, sender common.Address) error +} + +type MercuryVerifierProxy interface { + Address() string + Verify(signedReport []byte, value *big.Int) (*types.Transaction, error) + VerifyBulk(signedReports [][]byte, value *big.Int) (*types.Transaction, error) +} diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 5e937ad9b72..763faecace7 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -46,6 +46,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/oracle_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/test_api_consumer_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" ) // EthereumOracle oracle for "directrequest" job tests @@ -2244,3 +2246,65 @@ func (e *EthereumFunctionsLoadTestClient) SendRequestWithDONHostedSecrets(times } return e.client.ProcessTransaction(tx) } + +type EthereumMercuryVerifier struct { + address common.Address + client blockchain.EVMClient + instance *verifier.Verifier +} + +func (e *EthereumMercuryVerifier) Address() string { + return e.address.Hex() +} + +func (e *EthereumMercuryVerifier) Verify(signedReport []byte, sender common.Address) error { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := e.instance.Verify(opts, signedReport, sender) + if err != nil { + return err + } + return e.client.ProcessTransaction(tx) +} + +type EthereumMercuryVerifierProxy struct { + address common.Address + client blockchain.EVMClient + instance *verifier_proxy.VerifierProxy +} + +func (e *EthereumMercuryVerifierProxy) Address() string { + return e.address.Hex() +} + +func (e *EthereumMercuryVerifierProxy) Verify(signedReport []byte, value *big.Int) (*types.Transaction, error) { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if value != nil { + opts.Value = value + } + if err != nil { + return nil, err + } + tx, err := e.instance.Verify(opts, signedReport) + if err != nil { + return nil, err + } + return tx, e.client.ProcessTransaction(tx) +} + +func (e *EthereumMercuryVerifierProxy) VerifyBulk(signedReports [][]byte, value *big.Int) (*types.Transaction, error) { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if value != nil { + opts.Value = value + } + if err != nil { + return nil, err + } + tx, err := e.instance.VerifyBulk(opts, signedReports) + if err != nil { + return nil, err + } + return tx, e.client.ProcessTransaction(tx) +} From 36db6a46b291ed1151161d1b1826f9c1ca25714e Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal Date: Mon, 11 Sep 2023 11:11:02 +0100 Subject: [PATCH 84/88] update block time calculation (#10576) * update block time calculation * update --- .../evm21/logprovider/block_time.go | 35 +++++++------------ .../evm21/logprovider/block_time_test.go | 6 ++-- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go index 3af93f873c1..9fc35dd84be 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go @@ -11,7 +11,7 @@ import ( ) var ( - defaultSampleSize = int64(200) + defaultSampleSize = int64(10000) defaultBlockTime = time.Second * 1 ) @@ -34,39 +34,28 @@ func (r *blockTimeResolver) BlockTime(ctx context.Context, blockSampleSize int64 if err != nil { return 0, fmt.Errorf("failed to get latest block from poller: %w", err) } - if latest < blockSampleSize { + if latest <= blockSampleSize { return defaultBlockTime, nil } - blockTimes, err := r.getSampleTimestamps(ctx, blockSampleSize, latest) + start, end := latest-blockSampleSize, latest + startTime, endTime, err := r.getSampleTimestamps(ctx, uint64(start), uint64(end)) if err != nil { return 0, err } - var sumDiff time.Duration - for i := range blockTimes { - if i != int(blockSampleSize-1) { - sumDiff += blockTimes[i].Sub(blockTimes[i+1]) - } - } - - return sumDiff / time.Duration(blockSampleSize-1), nil + return endTime.Sub(startTime) / time.Duration(blockSampleSize), nil } -func (r *blockTimeResolver) getSampleTimestamps(ctx context.Context, blockSampleSize, latest int64) ([]time.Time, error) { - blockSample := make([]uint64, blockSampleSize) - for i := range blockSample { - blockSample[i] = uint64(latest - blockSampleSize + int64(i)) - } - blocks, err := r.poller.GetBlocksRange(ctx, blockSample) +func (r *blockTimeResolver) getSampleTimestamps(ctx context.Context, start, end uint64) (time.Time, time.Time, error) { + blocks, err := r.poller.GetBlocksRange(ctx, []uint64{start, end}) if err != nil { - return nil, fmt.Errorf("failed to get block range from poller: %w", err) + return time.Time{}, time.Time{}, fmt.Errorf("failed to get block range from poller: %w", err) } sort.Slice(blocks, func(i, j int) bool { - return blocks[i].BlockNumber > blocks[j].BlockNumber + return blocks[i].BlockNumber < blocks[j].BlockNumber }) - blockTimes := make([]time.Time, blockSampleSize) - for i, b := range blocks { - blockTimes[i] = b.BlockTimestamp + if len(blocks) < 2 { + return time.Time{}, time.Time{}, fmt.Errorf("failed to fetch blocks %d, %d from log poller", start, end) } - return blockTimes, nil + return blocks[0].BlockTimestamp, blocks[1].BlockTimestamp, nil } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go index 55437ff6721..0ad9990e185 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go @@ -52,10 +52,8 @@ func TestBlockTimeResolver_BlockTime(t *testing.T) { 20, nil, []logpoller.LogPollerBlock{ - {BlockTimestamp: now.Add(-time.Second * (2 * 4)), BlockNumber: 1}, - {BlockTimestamp: now.Add(-time.Second * (2 * 3)), BlockNumber: 2}, - {BlockTimestamp: now.Add(-time.Second * (2 * 2)), BlockNumber: 3}, - {BlockTimestamp: now.Add(-time.Second * 2), BlockNumber: 4}, + {BlockTimestamp: now.Add(-time.Second * (2 * 4)), BlockNumber: 16}, + {BlockTimestamp: now, BlockNumber: 20}, }, nil, 2 * time.Second, From 09d1534f4541c4ecbf95164212d4c2b83c853e99 Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:49:32 +0300 Subject: [PATCH 85/88] Resolve data races when closing services (#10535) * avoid logging if context is done * add wait group to block Close until all goroutines return * block Close() for recoverer and registry * block Close() of states store * states store * rename threads -> threadsWG * wg.Add before spawning a goroutine * remove redundant assignment the channel was created in the constructor * added thread control helper * refactor automation services to use common infra for service logic * handle errors while spawning goroutines * block subscriber * remove thread control (was extracted to #10560) * align thread control interface * extract function that requires lock * recoverer: spawn several goroutines for background work * remove redundant log * remove redundant check * removed unused cancel * reset flush ticker * timer to ticker * fix test --- .../ocr2keeper/evm21/block_subscriber.go | 109 +++++++------ .../ocr2keeper/evm21/block_subscriber_test.go | 2 +- .../ocr2keeper/evm21/logprovider/provider.go | 80 ++++------ .../evm21/logprovider/provider_test.go | 2 +- .../ocr2keeper/evm21/logprovider/recoverer.go | 99 +++++++----- .../ocr2/plugins/ocr2keeper/evm21/registry.go | 146 ++++++++---------- .../ocr2keeper/evm21/upkeepstate/store.go | 77 ++++----- .../evm21/upkeepstate/store_test.go | 9 +- 8 files changed, 237 insertions(+), 287 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go index 9a7d9c5dcc7..87b46c9785b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go @@ -29,11 +29,15 @@ const ( blockHistorySize = int64(256) ) +var ( + BlockSubscriberServiceName = "BlockSubscriber" +) + type BlockSubscriber struct { - sync utils.StartStopOnce + utils.StartStopOnce + threadCtrl utils.ThreadControl + mu sync.RWMutex - ctx context.Context - cancel context.CancelFunc hb httypes.HeadBroadcaster lp logpoller.LogPoller headC chan *evmtypes.Head @@ -53,6 +57,7 @@ var _ ocr2keepers.BlockSubscriber = &BlockSubscriber{} func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, lggr logger.Logger) *BlockSubscriber { return &BlockSubscriber{ + threadCtrl: utils.NewThreadControl(), hb: hb, lp: lp, headC: make(chan *evmtypes.Head, channelSize), @@ -81,8 +86,8 @@ func (bs *BlockSubscriber) getBlockRange(ctx context.Context) ([]uint64, error) return blocks, nil } -func (bs *BlockSubscriber) initializeBlocks(blocks []uint64) error { - logpollerBlocks, err := bs.lp.GetBlocksRange(bs.ctx, blocks, pg.WithParentCtx(bs.ctx)) +func (bs *BlockSubscriber) initializeBlocks(ctx context.Context, blocks []uint64) error { + logpollerBlocks, err := bs.lp.GetBlocksRange(ctx, blocks) if err != nil { return err } @@ -127,67 +132,61 @@ func (bs *BlockSubscriber) cleanup() { bs.lggr.Infof("lastClearedBlock is set to %d", bs.lastClearedBlock) } -func (bs *BlockSubscriber) Start(_ context.Context) error { - bs.lggr.Info("block subscriber started.") - return bs.sync.StartOnce("BlockSubscriber", func() error { - bs.mu.Lock() - defer bs.mu.Unlock() - bs.ctx, bs.cancel = context.WithCancel(context.Background()) - // initialize the blocks map with the recent blockSize blocks - blocks, err := bs.getBlockRange(bs.ctx) - if err != nil { - bs.lggr.Errorf("failed to get block range", err) - } - err = bs.initializeBlocks(blocks) - if err != nil { - bs.lggr.Errorf("failed to get log poller blocks", err) - } - - _, bs.unsubscribe = bs.hb.Subscribe(&headWrapper{headC: bs.headC, lggr: bs.lggr}) +func (bs *BlockSubscriber) initialize(ctx context.Context) { + bs.mu.Lock() + defer bs.mu.Unlock() + // initialize the blocks map with the recent blockSize blocks + blocks, err := bs.getBlockRange(ctx) + if err != nil { + bs.lggr.Errorf("failed to get block range", err) + } + err = bs.initializeBlocks(ctx, blocks) + if err != nil { + bs.lggr.Errorf("failed to get log poller blocks", err) + } + _, bs.unsubscribe = bs.hb.Subscribe(&headWrapper{headC: bs.headC, lggr: bs.lggr}) +} +func (bs *BlockSubscriber) Start(ctx context.Context) error { + return bs.StartOnce(BlockSubscriberServiceName, func() error { + bs.lggr.Info("block subscriber started.") + bs.initialize(ctx) // poll from head broadcaster channel and push to subscribers - { - go func(ctx context.Context) { - for { - select { - case h := <-bs.headC: - if h != nil { - bs.processHead(h) - } - case <-ctx.Done(): - return + bs.threadCtrl.Go(func(ctx context.Context) { + for { + select { + case h := <-bs.headC: + if h != nil { + bs.processHead(h) } + case <-ctx.Done(): + return } - }(bs.ctx) - } - - // clean up block maps - { - go func(ctx context.Context) { - ticker := time.NewTicker(cleanUpInterval) - for { - select { - case <-ticker.C: - bs.cleanup() - case <-ctx.Done(): - ticker.Stop() - return - } + } + }) + // cleanup old blocks + bs.threadCtrl.Go(func(ctx context.Context) { + ticker := time.NewTicker(cleanUpInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + bs.cleanup() + case <-ctx.Done(): + return } - }(bs.ctx) - } + } + }) return nil }) } func (bs *BlockSubscriber) Close() error { - bs.lggr.Info("stop block subscriber") - return bs.sync.StopOnce("BlockSubscriber", func() error { - bs.mu.Lock() - defer bs.mu.Unlock() - - bs.cancel() + return bs.StopOnce(BlockSubscriberServiceName, func() error { + bs.lggr.Info("stop block subscriber") + bs.threadCtrl.Close() bs.unsubscribe() return nil }) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go index 19dfa7d9281..23fcf3f6695 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go @@ -158,7 +158,7 @@ func TestBlockSubscriber_InitializeBlocks(t *testing.T) { bs := NewBlockSubscriber(hb, lp, lggr) bs.blockHistorySize = historySize bs.blockSize = blockSize - err := bs.initializeBlocks(tc.Blocks) + err := bs.initializeBlocks(testutils.Context(t), tc.Blocks) if tc.Error != nil { assert.Equal(t, tc.Error.Error(), err.Error()) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go index 50e7e85e3b6..b62fb370847 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go @@ -22,9 +22,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) var ( + LogProviderServiceName = "LogEventProvider" + ErrHeadNotAvailable = fmt.Errorf("head not available") ErrBlockLimitExceeded = fmt.Errorf("block limit exceeded") @@ -78,9 +81,10 @@ var _ LogEventProviderTest = &logEventProvider{} // logEventProvider manages log filters for upkeeps and enables to read the log events. type logEventProvider struct { - lggr logger.Logger + utils.StartStopOnce + threadCtrl utils.ThreadControl - cancel context.CancelFunc + lggr logger.Logger poller logpoller.LogPoller @@ -99,8 +103,9 @@ type logEventProvider struct { func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, packer LogDataPacker, filterStore UpkeepFilterStore, opts LogTriggersOptions) *logEventProvider { return &logEventProvider{ - packer: packer, + threadCtrl: utils.NewThreadControl(), lggr: lggr.Named("KeepersRegistry.LogEventProvider"), + packer: packer, buffer: newLogEventBuffer(lggr, int(opts.LookbackBlocks), maxLogsPerBlock, maxLogsPerUpkeepInBlock), poller: poller, opts: opts, @@ -109,33 +114,22 @@ func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, packer LogDa } func (p *logEventProvider) Start(context.Context) error { - ctx, cancel := context.WithCancel(context.Background()) + return p.StartOnce(LogProviderServiceName, func() error { - p.lock.Lock() - if p.cancel != nil { - p.lock.Unlock() - cancel() // Cancel the created context - return errors.New("already started") - } - p.cancel = cancel - p.lock.Unlock() + readQ := make(chan []*big.Int, readJobQueueSize) - readQ := make(chan []*big.Int, readJobQueueSize) + p.lggr.Infow("starting log event provider", "readInterval", p.opts.ReadInterval, "readMaxBatchSize", readMaxBatchSize, "readers", readerThreads) - p.lggr.Infow("starting log event provider", "readInterval", p.opts.ReadInterval, "readMaxBatchSize", readMaxBatchSize, "readers", readerThreads) + for i := 0; i < readerThreads; i++ { + p.threadCtrl.Go(func(ctx context.Context) { + p.startReader(ctx, readQ) + }) + } - { // start readers - go func(ctx context.Context) { - for i := 0; i < readerThreads; i++ { - go p.startReader(ctx, readQ) - } - }(ctx) - } + p.threadCtrl.Go(func(ctx context.Context) { + lggr := p.lggr.With("where", "scheduler") - { // start scheduler - lggr := p.lggr.With("where", "scheduler") - go func(ctx context.Context) { - err := p.scheduleReadJobs(ctx, func(ids []*big.Int) { + p.scheduleReadJobs(ctx, func(ids []*big.Int) { select { case readQ <- ids: case <-ctx.Done(): @@ -143,35 +137,21 @@ func (p *logEventProvider) Start(context.Context) error { lggr.Warnw("readQ is full, dropping ids", "ids", ids) } }) - // if the context was canceled, we don't need to log the error - if ctx.Err() != nil { - return - } - if err != nil { - lggr.Warnw("stopped scheduling read jobs with error", "err", err) - } - lggr.Debug("stopped scheduling read jobs") - }(ctx) - } + }) - return nil + return nil + }) } func (p *logEventProvider) Close() error { - p.lock.Lock() - defer p.lock.Unlock() - - if cancel := p.cancel; cancel != nil { - p.cancel = nil - cancel() - } else { - return errors.New("already stopped") - } - return nil + return p.StopOnce(LogProviderServiceName, func() error { + p.threadCtrl.Close() + return nil + }) } -func (p *logEventProvider) Name() string { - return p.lggr.Name() +func (p *logEventProvider) HealthReport() map[string]error { + return map[string]error{LogProviderServiceName: p.Healthy()} } func (p *logEventProvider) GetLatestPayloads(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { @@ -237,7 +217,7 @@ func (p *logEventProvider) CurrentPartitionIdx() uint64 { } // scheduleReadJobs starts a scheduler that pushed ids to readQ for reading logs in the background. -func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([]*big.Int)) error { +func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([]*big.Int)) { ctx, cancel := context.WithCancel(pctx) defer cancel() @@ -265,7 +245,7 @@ func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([ partitionIdx++ atomic.StoreUint64(&p.currentPartitionIdx, partitionIdx) case <-ctx.Done(): - return ctx.Err() + return } } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go index 47070d71aed..db22886cbb7 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go @@ -193,7 +193,7 @@ func TestLogEventProvider_ScheduleReadJobs(t *testing.T) { reads := make(chan []*big.Int, 100) go func(ctx context.Context) { - _ = p.scheduleReadJobs(ctx, func(ids []*big.Int) { + p.scheduleReadJobs(ctx, func(ids []*big.Int) { select { case reads <- ids: default: diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go index c1065b7e870..06a3b257065 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -26,6 +26,8 @@ import ( ) var ( + LogRecovererServiceName = "LogRecoverer" + // RecoveryInterval is the interval at which the recovery scanning processing is triggered RecoveryInterval = 5 * time.Second // RecoveryCacheTTL is the time to live for the recovery cache @@ -57,9 +59,10 @@ type visitedRecord struct { } type logRecoverer struct { - lggr logger.Logger + utils.StartStopOnce + threadCtrl utils.ThreadControl - cancel context.CancelFunc + lggr logger.Logger lookbackBlocks *atomic.Int64 blockTime *atomic.Int64 @@ -82,7 +85,9 @@ var _ LogRecoverer = &logRecoverer{} func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client client.Client, stateStore core.UpkeepStateReader, packer LogDataPacker, filterStore UpkeepFilterStore, opts LogTriggersOptions) *logRecoverer { rec := &logRecoverer{ - lggr: lggr.Named("LogRecoverer"), + lggr: lggr.Named(LogRecovererServiceName), + + threadCtrl: utils.NewThreadControl(), blockTime: &atomic.Int64{}, lookbackBlocks: &atomic.Int64{}, @@ -104,63 +109,75 @@ func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client clie return rec } -func (r *logRecoverer) Start(_ context.Context) error { - ctx, cancel := context.WithCancel(context.Background()) +// Start starts the log recoverer, which runs 3 threads in the background: +// 1. Recovery thread: scans for logs that were missed by the log poller +// 2. Cleanup thread: cleans up the cache of logs that were already processed +// 3. Block time thread: updates the block time of the chain +func (r *logRecoverer) Start(ctx context.Context) error { + return r.StartOnce(LogRecovererServiceName, func() error { + r.updateBlockTime(ctx) - r.lock.Lock() - if r.cancel != nil { - r.lock.Unlock() - cancel() // Cancel the created context - return errors.New("already started") - } - r.cancel = cancel - r.lock.Unlock() - - r.updateBlockTime(ctx) + r.lggr.Infow("starting log recoverer", "blockTime", r.blockTime.Load(), "lookbackBlocks", r.lookbackBlocks.Load(), "interval", r.interval) - r.lggr.Infow("starting log recoverer", "blockTime", r.blockTime.Load(), "lookbackBlocks", r.lookbackBlocks.Load(), "interval", r.interval) - - { - go func(ctx context.Context, interval time.Duration) { - recoverTicker := time.NewTicker(interval) - defer recoverTicker.Stop() - gcTicker := time.NewTicker(utils.WithJitter(GCInterval)) - defer gcTicker.Stop() - blockTimeUpdateTicker := time.NewTicker(blockTimeUpdateCadence) - defer blockTimeUpdateTicker.Stop() + r.threadCtrl.Go(func(ctx context.Context) { + recoveryTicker := time.NewTicker(r.interval) + defer recoveryTicker.Stop() for { select { - case <-recoverTicker.C: + case <-recoveryTicker.C: if err := r.recover(ctx); err != nil { r.lggr.Warnw("failed to recover logs", "err", err) } - case <-gcTicker.C: + case <-ctx.Done(): + return + } + } + }) + + r.threadCtrl.Go(func(ctx context.Context) { + cleanupTicker := time.NewTicker(utils.WithJitter(GCInterval)) + defer cleanupTicker.Stop() + + for { + select { + case <-cleanupTicker.C: r.clean(ctx) - gcTicker.Reset(utils.WithJitter(GCInterval)) - case <-blockTimeUpdateTicker.C: + cleanupTicker.Reset(utils.WithJitter(GCInterval)) + case <-ctx.Done(): + return + } + } + }) + + r.threadCtrl.Go(func(ctx context.Context) { + blockTimeTicker := time.NewTicker(blockTimeUpdateCadence) + defer blockTimeTicker.Stop() + + for { + select { + case <-blockTimeTicker.C: r.updateBlockTime(ctx) + blockTimeTicker.Reset(utils.WithJitter(blockTimeUpdateCadence)) case <-ctx.Done(): return } } - }(ctx, r.interval) - } + }) - return nil + return nil + }) } func (r *logRecoverer) Close() error { - r.lock.Lock() - defer r.lock.Unlock() + return r.StopOnce(LogRecovererServiceName, func() error { + r.threadCtrl.Close() + return nil + }) +} - if cancel := r.cancel; cancel != nil { - r.cancel = nil - cancel() - } else { - return errors.New("already stopped") - } - return nil +func (r *logRecoverer) HealthReport() map[string]error { + return map[string]error{LogRecovererServiceName: r.Healthy()} } func (r *logRecoverer) GetProposalData(ctx context.Context, proposal ocr2keepers.CoordinatedBlockProposal) ([]byte, error) { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go index 751b94bde5c..a4684e67078 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go @@ -41,6 +41,8 @@ const ( ) var ( + RegistryServiceName = "AutomationRegistry" + ErrLogReadFailure = fmt.Errorf("failure reading logs") ErrHeadNotAvailable = fmt.Errorf("head not available") ErrInitializationFailure = fmt.Errorf("failed to initialize registry") @@ -83,6 +85,8 @@ func NewEvmRegistry( finalityDepth uint32, ) *EvmRegistry { return &EvmRegistry{ + ctx: context.Background(), + threadCtrl: utils.NewThreadControl(), lggr: lggr.Named("EvmRegistry"), poller: client.LogPoller(), addr: addr, @@ -124,7 +128,8 @@ type MercuryConfig struct { } type EvmRegistry struct { - sync utils.StartStopOnce + utils.StartStopOnce + threadCtrl utils.ThreadControl lggr logger.Logger poller logpoller.LogPoller addr common.Address @@ -134,13 +139,11 @@ type EvmRegistry struct { abi abi.ABI packer encoding.Packer chLog chan logpoller.Log - reInit *time.Timer mu sync.RWMutex logProcessed map[string]bool active ActiveUpkeepList lastPollBlock int64 ctx context.Context - cancel context.CancelFunc headFunc func(ocr2keepers.BlockKey) runState int runError error @@ -155,110 +158,83 @@ func (r *EvmRegistry) Name() string { return r.lggr.Name() } -func (r *EvmRegistry) Start(_ context.Context) error { - return r.sync.StartOnce("AutomationRegistry", func() error { - r.mu.Lock() - defer r.mu.Unlock() - r.ctx, r.cancel = context.WithCancel(context.Background()) - r.reInit = time.NewTimer(refreshInterval) - +func (r *EvmRegistry) Start(ctx context.Context) error { + return r.StartOnce(RegistryServiceName, func() error { if err := r.registerEvents(r.chainID, r.addr); err != nil { return fmt.Errorf("logPoller error while registering automation events: %w", err) } - // refresh the active upkeep keys; if the reInit timer returns, do it again - { - go func(cx context.Context, tmr *time.Timer, lggr logger.Logger, f func() error) { - err := f() - if err != nil { - lggr.Errorf("failed to initialize upkeeps", err) - } + r.threadCtrl.Go(func(ctx context.Context) { + lggr := r.lggr.With("where", "upkeeps_referesh") + err := r.refreshActiveUpkeeps() + if err != nil { + lggr.Errorf("failed to initialize upkeeps", err) + } + + ticker := time.NewTicker(refreshInterval) + defer ticker.Stop() - for { - select { - case <-tmr.C: - err = f() - if err != nil { - lggr.Errorf("failed to re-initialize upkeeps", err) - } - tmr.Reset(refreshInterval) - case <-cx.Done(): - return + for { + select { + case <-ticker.C: + err = r.refreshActiveUpkeeps() + if err != nil { + lggr.Errorf("failed to refresh upkeeps", err) } + case <-ctx.Done(): + return } - }(r.ctx, r.reInit, r.lggr, r.refreshActiveUpkeeps) - } - - // start polling logs on an interval - { - go func(cx context.Context, lggr logger.Logger, f func() error) { - ticker := time.NewTicker(time.Second) - for { - select { - case <-ticker.C: - err := f() - if err != nil { - lggr.Errorf("failed to poll logs for upkeeps", err) - } - case <-cx.Done(): - ticker.Stop() - return + } + }) + + r.threadCtrl.Go(func(ctx context.Context) { + lggr := r.lggr.With("where", "logs_polling") + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + err := r.pollUpkeepStateLogs() + if err != nil { + lggr.Errorf("failed to poll logs for upkeeps", err) } + case <-ctx.Done(): + return } - }(r.ctx, r.lggr, r.pollUpkeepStateLogs) - } - - // run process to process logs from log channel - { - go func(cx context.Context, ch chan logpoller.Log, lggr logger.Logger, f func(logpoller.Log) error) { - for { - select { - case l := <-ch: - err := f(l) - if err != nil { - lggr.Errorf("failed to process log for upkeep", err) - } - case <-cx.Done(): - return + } + }) + + r.threadCtrl.Go(func(ctx context.Context) { + lggr := r.lggr.With("where", "logs_processing") + ch := r.chLog + + for { + select { + case l := <-ch: + err := r.processUpkeepStateLog(l) + if err != nil { + lggr.Errorf("failed to process log for upkeep", err) } + case <-ctx.Done(): + return } - }(r.ctx, r.chLog, r.lggr, r.processUpkeepStateLog) - } + } + }) - r.runState = 1 return nil }) } func (r *EvmRegistry) Close() error { - return r.sync.StopOnce("AutomationRegistry", func() error { - r.mu.Lock() - defer r.mu.Unlock() - r.cancel() - r.runState = 0 - r.runError = nil + return r.StopOnce(RegistryServiceName, func() error { + r.threadCtrl.Close() return nil }) } -func (r *EvmRegistry) Ready() error { - r.mu.RLock() - defer r.mu.RUnlock() - - if r.runState == 1 { - return nil - } - return r.sync.Ready() -} - func (r *EvmRegistry) HealthReport() map[string]error { - r.mu.RLock() - defer r.mu.RUnlock() - - if r.runState > 1 { - r.sync.SvcErrBuffer.Append(fmt.Errorf("failed run state: %w", r.runError)) - } - return map[string]error{r.Name(): r.sync.Healthy()} + return map[string]error{RegistryServiceName: r.Healthy()} } func (r *EvmRegistry) refreshActiveUpkeeps() error { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go index ce1b50de229..cd123212376 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go @@ -2,7 +2,6 @@ package upkeepstate import ( "context" - "errors" "fmt" "io" "math/big" @@ -18,10 +17,12 @@ import ( ) const ( + UpkeepStateStoreServiceName = "UpkeepStateStore" // CacheExpiration is the amount of time that we keep a record in the cache. CacheExpiration = 24 * time.Hour // GCInterval is the amount of time between cache cleanups. - GCInterval = 2 * time.Hour + GCInterval = 2 * time.Hour + // flushCadence is the amount of time between flushes to the DB. flushCadence = 30 * time.Second concurrentBatchCalls = 10 ) @@ -58,12 +59,13 @@ type upkeepStateRecord struct { // It stores the state of ineligible upkeeps in a local, in-memory cache. // In addition, performed events are fetched by the scanner on demand. type upkeepStateStore struct { - // dependencies + utils.StartStopOnce + threadCtrl utils.ThreadControl + orm ORM lggr logger.Logger scanner PerformedLogsScanner - // configuration retention time.Duration cleanCadence time.Duration @@ -73,20 +75,18 @@ type upkeepStateStore struct { pendingRecords []persistedStateRecord sem chan struct{} batchSize int - - // service values - cancel context.CancelFunc } // NewUpkeepStateStore creates a new state store func NewUpkeepStateStore(orm ORM, lggr logger.Logger, scanner PerformedLogsScanner) *upkeepStateStore { return &upkeepStateStore{ orm: orm, - lggr: lggr.Named("UpkeepStateStore"), + lggr: lggr.Named(UpkeepStateStoreServiceName), cache: map[string]*upkeepStateRecord{}, scanner: scanner, retention: CacheExpiration, cleanCadence: GCInterval, + threadCtrl: utils.NewThreadControl(), pendingRecords: []persistedStateRecord{}, sem: make(chan struct{}, concurrentBatchCalls), batchSize: batchSize, @@ -94,32 +94,18 @@ func NewUpkeepStateStore(orm ORM, lggr logger.Logger, scanner PerformedLogsScann } // Start starts the upkeep state store. -// it does background cleanup of the cache. +// it does background cleanup of the cache every GCInterval, +// and flush records to DB every flushCadence. func (u *upkeepStateStore) Start(pctx context.Context) error { - if u.retention == 0 { - return errors.New("pruneDepth must be greater than zero") - } - - u.mu.Lock() - if u.cancel != nil { - u.mu.Unlock() - return fmt.Errorf("already started") - } - - ctx, cancel := context.WithCancel(context.Background()) - - u.cancel = cancel - u.mu.Unlock() - - if err := u.scanner.Start(ctx); err != nil { - return fmt.Errorf("failed to start scanner") - } + return u.StartOnce(UpkeepStateStoreServiceName, func() error { + if err := u.scanner.Start(pctx); err != nil { + return fmt.Errorf("failed to start scanner") + } - u.lggr.Debug("Starting upkeep state store") + u.lggr.Debug("Starting upkeep state store") - { - go func(ctx context.Context) { - ticker := time.NewTicker(u.cleanCadence) + u.threadCtrl.Go(func(ctx context.Context) { + ticker := time.NewTicker(utils.WithJitter(u.cleanCadence)) defer ticker.Stop() flushTicker := newTickerFn(utils.WithJitter(flushCadence)) @@ -131,19 +117,18 @@ func (u *upkeepStateStore) Start(pctx context.Context) error { if err := u.cleanup(ctx); err != nil { u.lggr.Errorw("unable to clean old state values", "err", err) } - ticker.Reset(utils.WithJitter(u.cleanCadence)) case <-flushTicker.C: u.flush(ctx) + flushTicker.Reset(utils.WithJitter(flushCadence)) case <-ctx.Done(): u.flush(ctx) return } } - }(ctx) - } - - return nil + }) + return nil + }) } func (u *upkeepStateStore) flush(ctx context.Context) { @@ -175,20 +160,14 @@ func (u *upkeepStateStore) flush(ctx context.Context) { // Close stops the service of pruning stale data; implements io.Closer func (u *upkeepStateStore) Close() error { - u.mu.Lock() - defer u.mu.Unlock() - - if cancel := u.cancel; cancel != nil { - u.cancel = nil - cancel() - } else { - return fmt.Errorf("already stopped") - } - if err := u.scanner.Close(); err != nil { - return fmt.Errorf("failed to start scanner") - } + return u.StopOnce(UpkeepStateStoreServiceName, func() error { + u.threadCtrl.Close() + return nil + }) +} - return nil +func (u *upkeepStateStore) HealthReport() map[string]error { + return map[string]error{UpkeepStateStoreServiceName: u.Healthy()} } // SelectByWorkIDs returns the current state of the upkeep for the provided ids. diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go index 9e7ba81e5eb..cc4f6d0a23f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go @@ -310,14 +310,13 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) { ctx := testutils.Context(t) tickerCh := make(chan time.Time) + oldNewTickerFn := newTickerFn oldFlushSize := batchSize - defer func() { - }() newTickerFn = func(d time.Duration) *time.Ticker { - return &time.Ticker{ - C: tickerCh, - } + t := time.NewTicker(d) + t.C = tickerCh + return t } batchSize = test.flushSize defer func() { From e8214f2ef75ed3f42adc7956050c90c4518ff4d5 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 11 Sep 2023 09:23:50 -0500 Subject: [PATCH 86/88] bumg golangci-lint 1.54.2 (#10265) --- .github/workflows/ci-core.yml | 2 +- .tool-versions | 2 +- GNUmakefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 8dc29d5db77..db867f70c4d 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -80,7 +80,7 @@ jobs: if: needs.init.outputs.on_trigger_lint == 'true' uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0 with: - version: v1.53.3 + version: v1.54.2 only-new-issues: ${{ github.event.schedule == '' }} # show only new issues, unless it's a scheduled run args: --out-format checkstyle:golangci-lint-report.xml - name: Print lint report artifact diff --git a/.tool-versions b/.tool-versions index c7deac35bf5..f7934265340 100644 --- a/.tool-versions +++ b/.tool-versions @@ -4,5 +4,5 @@ nodejs 16.16.0 postgres 13.3 helm 3.10.3 zig 0.10.1 -golangci-lint 1.53.3 +golangci-lint 1.54.2 shellspec 0.28.1 diff --git a/GNUmakefile b/GNUmakefile index 8698d845f3d..71279f43651 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -146,7 +146,7 @@ config-docs: ## Generate core node configuration documentation .PHONY: golangci-lint golangci-lint: ## Run golangci-lint for all issues. [ -d "./golangci-lint" ] || mkdir ./golangci-lint && \ - docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.53.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt + docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.54.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt GORELEASER_CONFIG ?= .goreleaser.yaml From 929313289d1a57d0c84e29b83950c2f7acc1b250 Mon Sep 17 00:00:00 2001 From: Chris Cushman <104409744+vreff@users.noreply.github.com> Date: Mon, 11 Sep 2023 12:41:57 -0400 Subject: [PATCH 87/88] Update test coverage for trusted blockhash store and VRFv2+ Wrapper (#10447) * Update test coverage for trusted blockhash store * Add wrapper coverage and update snapshot * Update gas snapshot * Update vrf.gas-snapshot * Delete contracts/gas-snapshots/vrf.gas-snapshot --- .../foundry/vrf/TrustedBlockhashStore.t.sol | 19 ++++- .../test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol | 69 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol b/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol index d2f52552e43..47fff7ea900 100644 --- a/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol +++ b/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol @@ -48,6 +48,7 @@ contract TrustedBlockhashStoreTest is BaseTest { assertEq(blockhash(unreachableBlock), 0); // Store blockhash from whitelisted address; + uint256[] memory invalidBlockNums = new uint256[](0); uint256[] memory blockNums = new uint256[](1); blockNums[0] = unreachableBlock; bytes32[] memory blockhashes = new bytes32[](1); @@ -64,9 +65,25 @@ contract TrustedBlockhashStoreTest is BaseTest { vm.expectRevert("Only callable by owner"); bhs.setWhitelist(new address[](0)); - // Should store unreachable blocks via whitelisted address. + // Should not store for a mismatched list of block numbers and hashes. changePrank(LINK_WHALE); + vm.expectRevert(TrustedBlockhashStore.InvalidTrustedBlockhashes.selector); + bhs.storeTrusted(invalidBlockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber)); + + // Should store unreachable blocks via whitelisted address. bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber)); assertEq(bhs.getBlockhash(unreachableBlock), unreachableBlockhash); + + // Change whitelist. Assert that the old whitelisted address can no longer store, + // but the new one can. + address[] memory newWhitelist = new address[](1); + newWhitelist[0] = LINK_WHALE_2; + bhs.setWhitelist(newWhitelist); + + vm.expectRevert(TrustedBlockhashStore.NotInWhitelist.selector); + bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber)); + + changePrank(LINK_WHALE_2); + bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber)); } } diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol index 4b506bb8c50..33bc72998f8 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol @@ -5,6 +5,7 @@ import {VRF} from "../../../../src/v0.8/vrf/VRF.sol"; import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol"; import {ExposedVRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol"; +import {VRFV2PlusWrapperConsumerBase} from "../../../../src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol"; import {VRFV2PlusWrapperConsumerExample} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol"; import {VRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol"; import {VRFV2PlusWrapper} from "../../../../src/v0.8/dev/vrf/VRFV2PlusWrapper.sol"; @@ -70,6 +71,21 @@ contract VRFV2PlusWrapperTest is BaseTest { vrfKeyHash, // keyHash 10 // max number of words ); + ( + , + , + , + uint32 _wrapperGasOverhead, + uint32 _coordinatorGasOverhead, + uint8 _wrapperPremiumPercentage, + bytes32 _keyHash, + uint8 _maxNumWords + ) = s_wrapper.getConfig(); + assertEq(_wrapperGasOverhead, wrapperGasOverhead); + assertEq(_coordinatorGasOverhead, coordinatorGasOverhead); + assertEq(0, _wrapperPremiumPercentage); + assertEq(vrfKeyHash, _keyHash); + assertEq(10, _maxNumWords); } event RandomWordsRequested( @@ -84,11 +100,42 @@ contract VRFV2PlusWrapperTest is BaseTest { address indexed sender ); + function testSetLinkAndLinkEthFeed() public { + VRFV2PlusWrapper wrapper = new VRFV2PlusWrapper(address(0), address(0), address(s_testCoordinator)); + + // Set LINK and LINK/ETH feed on wrapper. + wrapper.setLINK(address(s_linkToken)); + wrapper.setLinkEthFeed(address(s_linkEthFeed)); + assertEq(address(wrapper.s_link()), address(s_linkToken)); + assertEq(address(wrapper.s_linkEthFeed()), address(s_linkEthFeed)); + + // Revert for subsequent assignment. + vm.expectRevert(VRFV2PlusWrapper.LinkAlreadySet.selector); + wrapper.setLINK(address(s_linkToken)); + + // Consumer can set LINK token. + VRFV2PlusWrapperConsumerExample consumer = new VRFV2PlusWrapperConsumerExample(address(0), address(wrapper)); + consumer.setLinkToken(address(s_linkToken)); + + // Revert for subsequent assignment. + vm.expectRevert(VRFV2PlusWrapperConsumerBase.LINKAlreadySet.selector); + consumer.setLinkToken(address(s_linkToken)); + } + function testRequestAndFulfillRandomWordsNativeWrapper() public { // Fund subscription. s_testCoordinator.fundSubscriptionWithEth{value: 10 ether}(s_wrapper.SUBSCRIPTION_ID()); vm.deal(address(s_consumer), 10 ether); + // Get type and version. + assertEq(s_wrapper.typeAndVersion(), "VRFV2Wrapper 1.0.0"); + + // Cannot make request while disabled. + s_wrapper.disable(); + vm.expectRevert("wrapper is disabled"); + s_consumer.makeRequestNative(500_000, 0, 1); + s_wrapper.enable(); + // Request randomness from wrapper. uint32 callbackGasLimit = 1_000_000; vm.expectEmit(true, true, true, true); @@ -114,7 +161,11 @@ contract VRFV2PlusWrapperTest is BaseTest { (uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId); uint32 expectedPaid = callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead; + uint256 wrapperNativeCostEstimate = s_wrapper.estimateRequestPriceNative(callbackGasLimit, tx.gasprice); + uint256 wrapperCostCalculation = s_wrapper.calculateRequestPriceNative(callbackGasLimit); assertEq(paid, expectedPaid); + assertEq(uint256(paid), wrapperNativeCostEstimate); + assertEq(wrapperNativeCostEstimate, wrapperCostCalculation); assertEq(fulfilled, false); assertEq(native, true); assertEq(address(s_consumer).balance, 10 ether - expectedPaid); @@ -129,6 +180,13 @@ contract VRFV2PlusWrapperTest is BaseTest { (, bool nowFulfilled, uint256[] memory storedWords) = s_consumer.getRequestStatus(requestId); assertEq(nowFulfilled, true); assertEq(storedWords[0], 123); + + // Withdraw funds from wrapper. + changePrank(LINK_WHALE); + uint256 priorWhaleBalance = LINK_WHALE.balance; + s_wrapper.withdrawNative(LINK_WHALE, paid); + assertEq(LINK_WHALE.balance, priorWhaleBalance + paid); + assertEq(address(s_wrapper).balance, 0); } function testRequestAndFulfillRandomWordsLINKWrapper() public { @@ -162,7 +220,11 @@ contract VRFV2PlusWrapperTest is BaseTest { // Assert that the request was made correctly. (uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId); uint32 expectedPaid = (callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead) * 2; + uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, tx.gasprice); + uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit); assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/eth ratio + assertEq(uint256(paid), wrapperCostEstimate); + assertEq(wrapperCostEstimate, wrapperCostCalculation); assertEq(fulfilled, false); assertEq(native, false); assertEq(s_linkToken.balanceOf(address(s_consumer)), 10 ether - expectedPaid); @@ -177,5 +239,12 @@ contract VRFV2PlusWrapperTest is BaseTest { (, bool nowFulfilled, uint256[] memory storedWords) = s_consumer.getRequestStatus(requestId); assertEq(nowFulfilled, true); assertEq(storedWords[0], 456); + + // Withdraw funds from wrapper. + changePrank(LINK_WHALE); + uint256 priorWhaleBalance = s_linkToken.balanceOf(LINK_WHALE); + s_wrapper.withdraw(LINK_WHALE, paid); + assertEq(s_linkToken.balanceOf(LINK_WHALE), priorWhaleBalance + paid); + assertEq(s_linkToken.balanceOf(address(s_wrapper)), 0); } } From 8cba02a4f818ea90d4ba8f09a5faf162b8c41dec Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal Date: Mon, 11 Sep 2023 18:31:12 +0100 Subject: [PATCH 88/88] Update to ocr2keepers v0.7.23 (#10582) --- 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 76c1711d093..8936a4eb093 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,7 +19,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.22 + github.com/smartcontractkit/ocr2keepers v0.7.23 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/spf13/cobra v1.6.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 663fe3e046a..9913cde6135 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.22 h1:qMWy1/j7k3dA1NAxEyRF4iPrhH2gmricbBEXSlxRTSk= -github.com/smartcontractkit/ocr2keepers v0.7.22/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.23 h1:hvMCHm9zTOKGELc40n+JLGmbiW1tkFnHW17qAtoVews= +github.com/smartcontractkit/ocr2keepers v0.7.23/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/go.mod b/go.mod index d458408b70d..99487e273e1 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.22 + github.com/smartcontractkit/ocr2keepers v0.7.23 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230829114801-14bf715f805e diff --git a/go.sum b/go.sum index 36f20b94961..aef4542c59e 100644 --- a/go.sum +++ b/go.sum @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.22 h1:qMWy1/j7k3dA1NAxEyRF4iPrhH2gmricbBEXSlxRTSk= -github.com/smartcontractkit/ocr2keepers v0.7.22/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.23 h1:hvMCHm9zTOKGELc40n+JLGmbiW1tkFnHW17qAtoVews= +github.com/smartcontractkit/ocr2keepers v0.7.23/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 6002149a561..c82e1d15abc 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -23,7 +23,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework v1.16.5-0.20230908202859-e75102cf5f40 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 - github.com/smartcontractkit/ocr2keepers v0.7.22 + github.com/smartcontractkit/ocr2keepers v0.7.23 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230829114801-14bf715f805e github.com/smartcontractkit/wasp v0.3.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index a741ba40492..ebfbee21717 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2266,8 +2266,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.22 h1:qMWy1/j7k3dA1NAxEyRF4iPrhH2gmricbBEXSlxRTSk= -github.com/smartcontractkit/ocr2keepers v0.7.22/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2keepers v0.7.23 h1:hvMCHm9zTOKGELc40n+JLGmbiW1tkFnHW17qAtoVews= +github.com/smartcontractkit/ocr2keepers v0.7.23/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A=