From 49dc3addf9b869c11570a2c5c4bf43013eeeb3a0 Mon Sep 17 00:00:00 2001 From: kaleofduty <59616916+kaleofduty@users.noreply.github.com> Date: Mon, 10 Aug 2026 21:47:19 +0200 Subject: [PATCH] Improvements: - OCR3 signature verification contracts reject duplicate public keys - OCR3 signature verification contracts always reject invalid ECDSA signatures for defense-in-depth - OCR3 signature verification contracts naming & doc improvements - Non-malleable Merkle tree index - Harmonize OCR3 and OCR3.1 epoch start proof - More OCR3.1 metrics - OCR3.1 pacemaker events carry epoch numbers - Make ragep2p more robust to socket accept errors caused by OS resource limitations Based on 38d70076403ab27a829d9ef81e5c777921790e88 Co-authored-by: Kostis Karantias Co-authored-by: mvidigueira Co-authored-by: Philipp Schindler <4274886+PhilippSchindler@users.noreply.github.com> Co-authored-by: stchrysa --- contract3/OCR3AttestationVerifierBase.sol | 8 +- contract3/OCR3AttestationVerifierErrors.sol | 10 +- contract3/OCR3BLSAttestationVerifier.sol | 6 +- contract3/OCR3BLSAttestationVerifierLib.sol | 12 +- ...namicallyDispatchedAttestationVerifier.sol | 15 ++- ...llyDispatchedBLSAttestationVerifierLib.sol | 12 +- ...yDispatchedECDSAAttestationVerifierLib.sol | 10 +- contract3/OCR3ECDSAAttestationVerifier.sol | 15 ++- contract3/OCR3ECDSAAttestationVerifierLib.sol | 118 ++++++++++-------- contract3/dev/DemoBLSAttestationVerifier.sol | 2 +- ...namicallyDispatchedAttestationVerifier.sol | 2 +- .../dev/DemoECDSAAttestationVerifier.sol | 2 +- .../demoblsattestationverifier.go | 4 +- .../demoecdsaattestationverifier.go | 4 +- ...allydispatchedblsattestationverifierlib.go | 4 +- ...lydispatchedecdsaattestationverifierlib.go | 4 +- internal/mt/mt.go | 8 ++ .../protocol/outcome_generation_leader.go | 42 +++---- .../internal/ocr3/protocol/signed_data.go | 6 +- .../internal/ocr3_1/protocol/event.go | 12 +- .../internal/ocr3_1/protocol/metrics.go | 95 ++++++++++++-- .../internal/ocr3_1/protocol/oracle.go | 1 + .../ocr3_1/protocol/outcome_generation.go | 2 + .../protocol/outcome_generation_follower.go | 11 +- .../protocol/outcome_generation_leader.go | 6 +- .../internal/ocr3_1/protocol/pacemaker.go | 58 ++++++++- .../internal/ocr3_1/protocol/state_sync.go | 13 +- .../ocr3_1/protocol/state_sync_block.go | 3 + .../protocol/state_sync_block_replay.go | 6 +- .../ocr3_1/protocol/state_sync_tree.go | 1 + ragep2p/doc.go | 14 +++ ragep2p/metrics.go | 14 ++- ragep2p/ragep2p.go | 37 +++++- ragep2p/ragep2pnew/doc.go | 14 +++ ragep2p/ragep2pnew/metrics.go | 14 ++- ragep2p/ragep2pnew/ragep2p.go | 37 +++++- 36 files changed, 457 insertions(+), 165 deletions(-) diff --git a/contract3/OCR3AttestationVerifierBase.sol b/contract3/OCR3AttestationVerifierBase.sol index acbc2347..6e0ba236 100644 --- a/contract3/OCR3AttestationVerifierBase.sol +++ b/contract3/OCR3AttestationVerifierBase.sol @@ -11,10 +11,10 @@ abstract contract OCR3AttestationVerifierBase { /// @param n The number of keys expected to be set by this call. Must match the actual number of keys present in /// the `ocr3SignerPublicKeys` parameter. The maximum number of keys supported is 32 (based on the width of /// the attribution bitmask). - /// @param ocr3SignerPublicKeys A concatenation of `n` public keys from the OCR3 signers. The exact format of the - /// keys depends on the signature scheme used for verification (for example, for ECDSA, addresses of 20 bytes - /// each would be used). - function _setVerificationKeys(uint8 n, bytes calldata ocr3SignerPublicKeys) internal virtual; + /// @param ocr3SignerPublicKeys The `n` public keys of the OCR3 signers. The exact encoding depends on the + /// signature scheme used for verification (for example, ECDSA expects `abi.encode(address[])`, whereas BLS + /// expects a concatenation of fixed-size keys). + function _setAttestationVerificationKeys(uint8 n, bytes calldata ocr3SignerPublicKeys) internal virtual; /// @notice Verifies the attestation for the given report. /// Reverts if the attestation could not be verified successfully. diff --git a/contract3/OCR3AttestationVerifierErrors.sol b/contract3/OCR3AttestationVerifierErrors.sol index d927b72d..39282de0 100644 --- a/contract3/OCR3AttestationVerifierErrors.sol +++ b/contract3/OCR3AttestationVerifierErrors.sol @@ -2,24 +2,24 @@ pragma solidity ^0.8.19; // Raised when the number of provided verification keys does not match the expected number of keys (parameter: n). -error InvalidNumberOfKeys(); +error InvalidNumberOfAttestationVerificationKeys(); // Raised when the provided verification keys are of invalid size. -error KeysOfInvalidSize(); +error AttestationVerificationKeysOfInvalidSize(); // Raised when an attempt to set more than 32 verification keys is made. // An upper limit of 32 keys is enforced by the width of the bitmask used for the attribution data. -error MaximumNumberOfKeysExceeded(); +error MaximumNumberOfAttestationVerificationKeysExceeded(); // Raised when a provided verification key is found invalid. // Potential causes for invalid keys are, for example: // - ECDSA: the value 0x0000000000000000000000000000000000000000 // - BLS: a key with an invalid proof-of-possession -error InvalidKey(); +error InvalidAttestationVerificationKey(); // Raised when a duplicate verification key is provided during key set. // Each key must be unique to ensure correct attribution during attestation verification. -error DuplicateKey(); +error DuplicateAttestationVerificationKey(); // Raised when the signature verification failed for the provided attestation. error InvalidAttestation(); diff --git a/contract3/OCR3BLSAttestationVerifier.sol b/contract3/OCR3BLSAttestationVerifier.sol index d2cf9ee3..0825e43d 100644 --- a/contract3/OCR3BLSAttestationVerifier.sol +++ b/contract3/OCR3BLSAttestationVerifier.sol @@ -14,8 +14,10 @@ contract OCR3BLSAttestationVerifier is OCR3AttestationVerifierBase { // configurations, storage costs are only paid for the used number of keys. OCR3BLSAttestationVerifierLib.G2PointAffine[32] s_ocr3BlsSignerPublicKeys; - function _setVerificationKeys(uint8 n, bytes calldata ocr3BlsSignerPublicKeys) internal override { - OCR3BLSAttestationVerifierLib.setVerificationKeys(s_ocr3BlsSignerPublicKeys, n, ocr3BlsSignerPublicKeys); + function _setAttestationVerificationKeys(uint8 n, bytes calldata ocr3BlsSignerPublicKeys) internal override { + OCR3BLSAttestationVerifierLib.setAttestationVerificationKeys( + s_ocr3BlsSignerPublicKeys, n, ocr3BlsSignerPublicKeys + ); } function _verifyAttestation( diff --git a/contract3/OCR3BLSAttestationVerifierLib.sol b/contract3/OCR3BLSAttestationVerifierLib.sol index 1461a7f6..d6045270 100644 --- a/contract3/OCR3BLSAttestationVerifierLib.sol +++ b/contract3/OCR3BLSAttestationVerifierLib.sol @@ -36,7 +36,7 @@ library OCR3BLSAttestationVerifierLib { /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... innerHash /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... outerHash /// - function setVerificationKeys( + function setAttestationVerificationKeys( G2PointAffine[32] storage s_ocr3BlsSignerPublicKeys, uint8 n, bytes calldata ocr3BlsSignerPublicKeys @@ -44,13 +44,13 @@ library OCR3BLSAttestationVerifierLib { // Verify that `n` is consistent with the amount of data being passed in the `ocr3BlsSignerPublicKeys` parameter. // The maximum of 32 keys is based on the width of the attribution bitmask (currently set to 32 bits). if (ocr3BlsSignerPublicKeys.length % KEYSIZE_WITH_POP != 0) { - revert KeysOfInvalidSize(); + revert AttestationVerificationKeysOfInvalidSize(); } if (ocr3BlsSignerPublicKeys.length / KEYSIZE_WITH_POP != n) { - revert InvalidNumberOfKeys(); + revert InvalidNumberOfAttestationVerificationKeys(); } if (n > 32) { - revert MaximumNumberOfKeysExceeded(); + revert MaximumNumberOfAttestationVerificationKeysExceeded(); } // Temporary in-memory storage for the keys. This is used to check for duplicate keys at the end of this @@ -115,7 +115,7 @@ library OCR3BLSAttestationVerifierLib { // below the field modulus. This is required to ensure the comparison performed in the duplicate keys check // is not susceptible to maliciously crafted keys. if (!_verifySignature(ocr3BlsSignerPublicKey, outerHash, popSignature)) { - revert InvalidKey(); + revert InvalidAttestationVerificationKey(); } // Write the verified key to the application contract's storage and to the temporary in-memory storage @@ -138,7 +138,7 @@ library OCR3BLSAttestationVerifierLib { && ocr3BlsSignerPublicKeysMemory[i].y_imag == ocr3BlsSignerPublicKeysMemory[j].y_imag && ocr3BlsSignerPublicKeysMemory[i].y_real == ocr3BlsSignerPublicKeysMemory[j].y_real ) { - revert DuplicateKey(); + revert DuplicateAttestationVerificationKey(); } } } diff --git a/contract3/OCR3DynamicallyDispatchedAttestationVerifier.sol b/contract3/OCR3DynamicallyDispatchedAttestationVerifier.sol index 7ee0f81d..e2a3fc70 100644 --- a/contract3/OCR3DynamicallyDispatchedAttestationVerifier.sol +++ b/contract3/OCR3DynamicallyDispatchedAttestationVerifier.sol @@ -11,8 +11,9 @@ contract OCR3DynamicallyDispatchedAttestationVerifier is OCR3AttestationVerifier // Address of the pre-deployed library contract. address immutable i_verifierLibraryAddress; - // Function selectors for the setVerificationKeys(...) and verifyAttestation(...) functions of the library. - bytes4 immutable i_selectorSetVerificationKeys; + // Function selectors for the setAttestationVerificationKeys(...) and verifyAttestation(...) functions of the + // library. + bytes4 immutable i_selectorSetAttestationVerificationKeys; bytes4 immutable i_selectorVerifyAttestation; // Placeholder for reserving storage for up to 32 verification keys. The used library stores an implementation @@ -29,7 +30,7 @@ contract OCR3DynamicallyDispatchedAttestationVerifier is OCR3AttestationVerifier // delegatecall into the library, but is also security critical, it protects against potential misconfiguration, // where i_verifierLibraryAddress does not point to a contract. Additional details are provided in the comment // in the _delegatecall(...) helper below. - (i_selectorSetVerificationKeys, i_selectorVerifyAttestation) = + (i_selectorSetAttestationVerificationKeys, i_selectorVerifyAttestation) = (OCR3DynamicallyDispatchedAttestationVerifierSelectorInterface(verifierLibraryAddress).getSelectors()); } @@ -56,12 +57,14 @@ contract OCR3DynamicallyDispatchedAttestationVerifier is OCR3AttestationVerifier } } - function _setVerificationKeys(uint8 n, bytes calldata ocr3SignerPublicKeys) internal override { + function _setAttestationVerificationKeys(uint8 n, bytes calldata ocr3SignerPublicKeys) internal override { uint256 storagePtr; assembly { storagePtr := s_ocr3SignerPublicKeys.slot } - _delegatecall(abi.encodeWithSelector(i_selectorSetVerificationKeys, storagePtr, n, ocr3SignerPublicKeys)); + _delegatecall( + abi.encodeWithSelector(i_selectorSetAttestationVerificationKeys, storagePtr, n, ocr3SignerPublicKeys) + ); } function _verifyAttestation( @@ -82,7 +85,7 @@ contract OCR3DynamicallyDispatchedAttestationVerifier is OCR3AttestationVerifier } /// @title Internal selector interface for dynamically dispatched OCR3 attestation verifier libraries -/// @dev Exposes the selectors for the `setVerificationKeys(...)`, and `verifyAttestation(...)` functions. +/// @dev Exposes the selectors for the `setAttestationVerificationKeys(...)`, and `verifyAttestation(...)` functions. /// @dev Required for delegate-calling into a pre-deployed library, implemented in the `DynamicallyDispatched` shims. interface OCR3DynamicallyDispatchedAttestationVerifierSelectorInterface { function getSelectors() external pure returns (bytes4, bytes4); diff --git a/contract3/OCR3DynamicallyDispatchedBLSAttestationVerifierLib.sol b/contract3/OCR3DynamicallyDispatchedBLSAttestationVerifierLib.sol index 29ca69d9..7ca9192e 100644 --- a/contract3/OCR3DynamicallyDispatchedBLSAttestationVerifierLib.sol +++ b/contract3/OCR3DynamicallyDispatchedBLSAttestationVerifierLib.sol @@ -6,12 +6,14 @@ import "./OCR3BLSAttestationVerifierLib.sol"; /// @title Shim for the core BLS attestation verifier library, allowing it to be pre-deployed separately. /// @dev The function modifiers of the main interface functions are updated from internal to external. library OCR3DynamicallyDispatchedBLSAttestationVerifierLib { - function setVerificationKeys( + function setAttestationVerificationKeys( OCR3BLSAttestationVerifierLib.G2PointAffine[32] storage s_ocr3BlsSignerPublicKeys, uint8 n, bytes calldata ocr3BlsSignerPublicKeys ) external { - OCR3BLSAttestationVerifierLib.setVerificationKeys(s_ocr3BlsSignerPublicKeys, n, ocr3BlsSignerPublicKeys); + OCR3BLSAttestationVerifierLib.setAttestationVerificationKeys( + s_ocr3BlsSignerPublicKeys, n, ocr3BlsSignerPublicKeys + ); } function verifyAttestation( @@ -26,13 +28,15 @@ library OCR3DynamicallyDispatchedBLSAttestationVerifierLib { // Function to initialize the selectors for delegate-calling into this library. // Derived using keccak256 from the function signatures (without parameter names): - // - keccak256("setVerificationKeys(OCR3BLSAttestationVerifierLib.G2PointAffine[32] storage,uint8,bytes)")[:4] + // - keccak256( + // "setAttestationVerificationKeys(OCR3BLSAttestationVerifierLib.G2PointAffine[32] storage,uint8,bytes)" + // )[:4] // - keccak256( // "verifyAttestation(OCR3BLSAttestationVerifierLib.G2PointAffine[32] storage,uint8,uint8,bytes32,bytes)" // )[:4] function getSelectors() external pure returns (bytes4, bytes4) { return ( - OCR3DynamicallyDispatchedBLSAttestationVerifierLib.setVerificationKeys.selector, + OCR3DynamicallyDispatchedBLSAttestationVerifierLib.setAttestationVerificationKeys.selector, OCR3DynamicallyDispatchedBLSAttestationVerifierLib.verifyAttestation.selector ); } diff --git a/contract3/OCR3DynamicallyDispatchedECDSAAttestationVerifierLib.sol b/contract3/OCR3DynamicallyDispatchedECDSAAttestationVerifierLib.sol index a258bb7a..4c9b4af1 100644 --- a/contract3/OCR3DynamicallyDispatchedECDSAAttestationVerifierLib.sol +++ b/contract3/OCR3DynamicallyDispatchedECDSAAttestationVerifierLib.sol @@ -6,12 +6,14 @@ import "./OCR3ECDSAAttestationVerifierLib.sol"; /// @title Shim for the core ECDSA attestation verifier library, allowing it to be pre-deployed separately. /// @dev The function modifiers of the main interface functions are updated from internal to external. library OCR3DynamicallyDispatchedECDSAAttestationVerifierLib { - function setVerificationKeys( + function setAttestationVerificationKeys( uint256[32] storage s_ocr3EcdsaSignerPublicKeys, uint8 n, bytes calldata ocr3EcdsaSignerPublicKeys ) external { - OCR3ECDSAAttestationVerifierLib.setVerificationKeys(s_ocr3EcdsaSignerPublicKeys, n, ocr3EcdsaSignerPublicKeys); + OCR3ECDSAAttestationVerifierLib.setAttestationVerificationKeys( + s_ocr3EcdsaSignerPublicKeys, n, ocr3EcdsaSignerPublicKeys + ); } function verifyAttestation( @@ -26,11 +28,11 @@ library OCR3DynamicallyDispatchedECDSAAttestationVerifierLib { // Function to initialize the selectors for delegate-calling into this library. // Derived using keccak256 from the function signatures (without parameter names): - // - keccak256("setVerificationKeys(uint256[32] storage,uint8,bytes)")[:4] + // - keccak256("setAttestationVerificationKeys(uint256[32] storage,uint8,bytes)")[:4] // - keccak256("verifyAttestation(uint256[32] storage,uint8,uint8,bytes32,bytes)")[:4] function getSelectors() external pure returns (bytes4, bytes4) { return ( - OCR3DynamicallyDispatchedECDSAAttestationVerifierLib.setVerificationKeys.selector, + OCR3DynamicallyDispatchedECDSAAttestationVerifierLib.setAttestationVerificationKeys.selector, OCR3DynamicallyDispatchedECDSAAttestationVerifierLib.verifyAttestation.selector ); } diff --git a/contract3/OCR3ECDSAAttestationVerifier.sol b/contract3/OCR3ECDSAAttestationVerifier.sol index 5be281f2..ceb631b4 100644 --- a/contract3/OCR3ECDSAAttestationVerifier.sol +++ b/contract3/OCR3ECDSAAttestationVerifier.sol @@ -15,8 +15,19 @@ contract OCR3ECDSAAttestationVerifier is OCR3AttestationVerifierBase { // entries is fine for smaller configurations, storage costs are only paid for the used number of keys. uint256[32] s_ocr3EcdsaSignerPublicKeys; - function _setVerificationKeys(uint8 n, bytes calldata ocr3EcdsaSignerPublicKeys) internal override { - OCR3ECDSAAttestationVerifierLib.setVerificationKeys(s_ocr3EcdsaSignerPublicKeys, n, ocr3EcdsaSignerPublicKeys); + function _setAttestationVerificationKeys(uint8 n, bytes calldata ocr3EcdsaSignerPublicKeys) internal override { + OCR3ECDSAAttestationVerifierLib.setAttestationVerificationKeys( + s_ocr3EcdsaSignerPublicKeys, n, ocr3EcdsaSignerPublicKeys + ); + } + + /// @notice Address-typed convenience overload of `_setAttestationVerificationKeys`. Callers holding an + /// `address[]` (the common case on EVM chains) can use this directly, without ABI-encoding the keys into + /// the `bytes` layout and without supplying a redundant key count. + function _setAttestationVerificationKeys(address[] memory ocr3EcdsaSignerPublicKeys) internal { + OCR3ECDSAAttestationVerifierLib.setAttestationVerificationKeys( + s_ocr3EcdsaSignerPublicKeys, ocr3EcdsaSignerPublicKeys + ); } function _verifyAttestation( diff --git a/contract3/OCR3ECDSAAttestationVerifierLib.sol b/contract3/OCR3ECDSAAttestationVerifierLib.sol index 13d23dbe..5293ef19 100644 --- a/contract3/OCR3ECDSAAttestationVerifierLib.sol +++ b/contract3/OCR3ECDSAAttestationVerifierLib.sol @@ -9,64 +9,73 @@ import "./OCR3AttestationVerifierErrors.sol"; /// library. library OCR3ECDSAAttestationVerifierLib { /// @notice Verifies and stores the provided ECDSA public keys for later use within `verifyAttestation(...)`. - /// Reverts if an invalid number of keys was provided, any key is found invalid, or a duplicate key is + /// Reverts if the decoded key count does not match `n`, any key is found invalid, or a duplicate key is /// provided. + /// @dev Bytes-typed overload of `setAttestationVerificationKeys`. The keys are ABI-decoded into an `address[]` + /// and forwarded to the address-typed overload, which performs all validation and storage. This exists for + /// callers that hold the keys as opaque bytes (for example, dispatching through the scheme-agnostic + /// `_setAttestationVerificationKeys(uint8, bytes)` interface). /// @param s_ocr3EcdsaSignerPublicKeys Storage space for holding all ECDSA verification keys (in the form of - /// addresses). The first `n` values are populated with values from the `ocr3EcdsaSignerPublicKeys` parameter. - /// The size of 32 is the maximum number of keys supported (based on the width of the attribution bitmask). - /// Storage costs are only paid for the number of keys used `n`. - /// @param n The number of keys expected to be set by this call. Must match the actual number of keys present in - /// the `ocr3EcdsaSignerPublicKeys` parameter. - /// @param ocr3EcdsaSignerPublicKeys A concatenation of `n` ECDSA public keys (i.e., addresses, 20 bytes each). - function setVerificationKeys( + /// addresses). The first `n` values are populated. The size of 32 is the maximum number of keys supported + /// (based on the width of the attribution bitmask). Storage costs are only paid for the number of keys used. + /// @param n The number of keys expected to be set by this call. Must match the number of keys decoded from the + /// `ocr3EcdsaSignerPublicKeys` parameter. + /// @param ocr3EcdsaSignerPublicKeys The ABI-encoding of the signers' ECDSA public keys, i.e. + /// `abi.encode(address[])`. + function setAttestationVerificationKeys( uint256[32] storage s_ocr3EcdsaSignerPublicKeys, uint8 n, bytes calldata ocr3EcdsaSignerPublicKeys ) internal { - // Verify that `n` is consistent with the amount of data being passed in the `ocr3EcdsaSignerPublicKeys` parameter. - // The maximum of 32 keys is based on the width of the attribution bitmask (currently set to 32 bits). - if (ocr3EcdsaSignerPublicKeys.length % 20 != 0) { - revert KeysOfInvalidSize(); - } - if (ocr3EcdsaSignerPublicKeys.length / 20 != n) { - revert InvalidNumberOfKeys(); - } - if (n > 32) { - revert MaximumNumberOfKeysExceeded(); + address[] memory signers = abi.decode(ocr3EcdsaSignerPublicKeys, (address[])); + // Verify that `n` is consistent with the number of keys decoded from `ocr3EcdsaSignerPublicKeys`. + if (signers.length != n) { + revert InvalidNumberOfAttestationVerificationKeys(); } + setAttestationVerificationKeys(s_ocr3EcdsaSignerPublicKeys, signers); + } - // Temporary in-memory storage for the keys. This is used to check for duplicate keys at the end of this - // function. The size of 32 is the maximum number of keys supported (based on the width of the attribution - // bitmask). - uint160[32] memory ocr3EcdsaSignerPublicKeysMemory; + /// @notice Verifies and stores the provided ECDSA public keys (as addresses) for later use within + /// `verifyAttestation(...)`. Reverts if too many keys are provided, any key is found invalid, or a + /// duplicate key is provided. + /// @dev Address-typed convenience overload of `setAttestationVerificationKeys`. Callers holding an `address[]` + /// (the common case on EVM chains) can use this directly, without ABI-encoding the keys into the `bytes` + /// layout and without supplying a redundant key count. The `bytes` overload remains available for callers + /// that hold the keys as an ABI-encoded `address[]`. + /// @param s_ocr3EcdsaSignerPublicKeys Storage space for holding all ECDSA verification keys (in the form of + /// addresses). The first `ocr3EcdsaSignerPublicKeys.length` values are populated. The size of 32 is the + /// maximum number of keys supported (based on the width of the attribution bitmask). Storage costs are only + /// paid for the number of keys used. + /// @param ocr3EcdsaSignerPublicKeys The ECDSA public keys (i.e., addresses) of the OCR3 signers. + function setAttestationVerificationKeys( + uint256[32] storage s_ocr3EcdsaSignerPublicKeys, + address[] memory ocr3EcdsaSignerPublicKeys + ) internal { + uint256 n = ocr3EcdsaSignerPublicKeys.length; - // Copy the provided keys from calldata (ocr3EcdsaSignerPublicKeys) to storage (s_ocr3EcdsaSignerPublicKeys). - // After copying, the i-th 32 byte storage slot holds the i-th 20 byte key (i.e., the signer's address) in its - // lower bytes. - uint256 pos = 0; - for (uint256 i = 0; i < n; ++i) { - // Read the next 20 byte key/address from the ocr3EcdsaSignerPublicKeys parameter and ensure the key/address - // is non-zero. Clearly the value 0x0000000000000000000000000000000000000000 is an invalid key/address, - // however, during signature verification the call to the ecRecover precompile returns zero on failure, and - // its return value is directly compared to s_ocr3EcdsaSignerPublicKeys[i], which therefore must never be - // zero. - uint160 key = uint160(bytes20(ocr3EcdsaSignerPublicKeys[pos:pos + 20])); - if (key == 0) { - revert InvalidKey(); - } - ocr3EcdsaSignerPublicKeysMemory[i] = key; - s_ocr3EcdsaSignerPublicKeys[i] = key; - pos += 20; + // The maximum of 32 keys is based on the width of the attribution bitmask (currently set to 32 bits). + if (n > 32) { + revert MaximumNumberOfAttestationVerificationKeysExceeded(); } - // Check for duplicate keys. Each key must be unique to ensure that no two oracles share the same signing - // identity, which could otherwise lead to incorrect attribution during attestation verification. + // Copy the provided keys to storage (s_ocr3EcdsaSignerPublicKeys). After copying, the i-th 32 byte storage + // slot holds the i-th 20 byte key (i.e., the signer's address) in its lower bytes. for (uint256 i = 0; i < n; ++i) { - for (uint256 j = i + 1; j < n; ++j) { - if (ocr3EcdsaSignerPublicKeysMemory[i] == ocr3EcdsaSignerPublicKeysMemory[j]) { - revert DuplicateKey(); + address key = ocr3EcdsaSignerPublicKeys[i]; + // Ensure the key/address is non-zero. Clearly the value 0x0000000000000000000000000000000000000000 is an + // invalid key/address to sign attestations from. + if (key == address(0)) { + revert InvalidAttestationVerificationKey(); + } + // Reject duplicate keys. Each key must be unique to ensure that no two oracles share the same signing + // identity, which could otherwise lead to incorrect attribution during attestation verification. `n` is at + // most 32, so the quadratic scan over the already-checked keys is cheap. + for (uint256 j = 0; j < i; ++j) { + if (ocr3EcdsaSignerPublicKeys[j] == key) { + revert DuplicateAttestationVerificationKey(); } } + s_ocr3EcdsaSignerPublicKeys[i] = uint256(uint160(key)); } } @@ -81,7 +90,7 @@ library OCR3ECDSAAttestationVerifierLib { /// /// @dev Attestation format: /// a) attribution bitmask (32 bits), and - /// b) `n` signatures + /// b) `f+1` signatures /// - 64 bytes per signature, a tuple of (r, s) values /// - `s` is normalized such that recovery id `v` for the public key is 0 (=27 for the ecrecover call), /// - the signatures are sorted by oracle index (ascending order), the least significant set bit of the @@ -196,19 +205,20 @@ library OCR3ECDSAAttestationVerifierLib { // recoveredKey = mem[0:32] // storedKey = s_ocr3EcdsaSignerPublicKeys[i] let recoveredKey := mload(0) // zero if ecRecover failed - let storedKey := sload(i) // always non-zero, ensured by `setVerificationKeys` + let storedKey := sload(i) // always non-zero, ensured by `setAttestationVerificationKeys` // As a second step for signature verification, compare the recovered public key with the stored // one for the current index `i` and increment the `numValidSignatures` counter if the keys match. // - // Attention: Special care needs to be taken in case the above call to the ecRecover failed and thus - // `recoveredKey` holds the value zero. - // - // The optimized check below relies on the fact that `storedKey` can never be zero - an invariant - // ensured by the implementation of `setVerificationKeys`. Therefore, the equality instruction - // correctly yields zero (and the counter `numValidSignatures` is not incremented) in the particular - // case where the call to ecRecover precompile failed. - numValidSignatures := add(numValidSignatures, eq(recoveredKey, storedKey)) + // Attention: Special care needs to be taken in case the above call to ecRecover failed, in which + // case `recoveredKey` holds the value zero. The `gt(recoveredKey, 0)` guard ensures such a failed + // recovery is never counted as valid. Under normal operation this is redundant with the equality + // check, because `storedKey` is guaranteed non-zero by `setAttestationVerificationKeys` and a zero + // `recoveredKey` therefore cannot match it. The guard is defense in depth: should that invariant + // ever be violated and a stored slot hold zero, a failed ecRecover (also zero) would otherwise + // match the zero slot and be counted as valid. The guard adds ~15 gas per signature. + numValidSignatures := + add(numValidSignatures, and(eq(recoveredKey, storedKey), gt(recoveredKey, 0))) } // i += 1 diff --git a/contract3/dev/DemoBLSAttestationVerifier.sol b/contract3/dev/DemoBLSAttestationVerifier.sol index e063b3f8..9ad93d64 100644 --- a/contract3/dev/DemoBLSAttestationVerifier.sol +++ b/contract3/dev/DemoBLSAttestationVerifier.sol @@ -23,7 +23,7 @@ contract DemoBLSAttestationVerifier is OCR3BLSAttestationVerifier { function setConfig(uint32 configVersion, uint8 n, uint8 f, bytes calldata ocr3BlsSignerPublicKeys) external { s_hotVars = HotVars({configVersion: configVersion, n: n, f: f}); - _setVerificationKeys(n, ocr3BlsSignerPublicKeys); + _setAttestationVerificationKeys(n, ocr3BlsSignerPublicKeys); } // We may want to load configDigest from storage instead. diff --git a/contract3/dev/DemoDynamicallyDispatchedAttestationVerifier.sol b/contract3/dev/DemoDynamicallyDispatchedAttestationVerifier.sol index 90059369..7a22c19f 100644 --- a/contract3/dev/DemoDynamicallyDispatchedAttestationVerifier.sol +++ b/contract3/dev/DemoDynamicallyDispatchedAttestationVerifier.sol @@ -25,7 +25,7 @@ contract DemoDynamicallyDispatchedAttestationVerifier is OCR3DynamicallyDispatch function setConfig(uint32 configVersion, uint8 n, uint8 f, bytes calldata ocr3SignerPublicKeys) external { s_hotVars = HotVars({configVersion: configVersion, n: n, f: f}); - _setVerificationKeys(n, ocr3SignerPublicKeys); + _setAttestationVerificationKeys(n, ocr3SignerPublicKeys); } // We may want to load configDigest from storage instead. diff --git a/contract3/dev/DemoECDSAAttestationVerifier.sol b/contract3/dev/DemoECDSAAttestationVerifier.sol index e2715559..02044026 100644 --- a/contract3/dev/DemoECDSAAttestationVerifier.sol +++ b/contract3/dev/DemoECDSAAttestationVerifier.sol @@ -23,7 +23,7 @@ contract DemoECDSAAttestationVerifier is OCR3ECDSAAttestationVerifier { function setConfig(uint32 configVersion, uint8 n, uint8 f, bytes calldata ocr3EcdsaSignerPublicKeys) external { s_hotVars = HotVars({configVersion: configVersion, n: n, f: f}); - _setVerificationKeys(n, ocr3EcdsaSignerPublicKeys); + _setAttestationVerificationKeys(n, ocr3EcdsaSignerPublicKeys); } // We may want to load configDigest from storage instead. diff --git a/gethwrappers3/demoblsattestationverifier/demoblsattestationverifier.go b/gethwrappers3/demoblsattestationverifier/demoblsattestationverifier.go index ac46d529..44c0923d 100644 --- a/gethwrappers3/demoblsattestationverifier/demoblsattestationverifier.go +++ b/gethwrappers3/demoblsattestationverifier/demoblsattestationverifier.go @@ -31,8 +31,8 @@ var ( // DemoBLSAttestationVerifierMetaData contains all meta data concerning the DemoBLSAttestationVerifier contract. var DemoBLSAttestationVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"DuplicateKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"KeysOfInvalidSize\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfKeysExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"ocr3BlsSignerPublicKeys\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"seqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50611906806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636f289d411461003b57806395fd15c814610050575b600080fd5b61004e610049366004611543565b610063565b005b61004e61005e3660046115f3565b610104565b6040805160608101825263ffffffff871680825260ff8781166020840181905290871692909301829052608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000016909117640100000000909302929092177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff16650100000000009091021790556100fd8483836101d7565b5050505050565b6040805160608101825260805463ffffffff8116825260ff6401000000008204811660208401819052650100000000009092041692820183905290916101519188918891908888886101e9565b805160808054602084015160409094015163ffffffff9093167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009091161764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff166501000000000093909216929092021790555050505050565b6101e46000848484610211565b505050565b60006101f6888886610760565b9050610207600087878487876107a9565b5050505050505050565b61021c60a18261172f565b15610253576040517fadd4994500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff831661026260a183611772565b14610299576040517fa07f647e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208360ff1611156102d7576040517f1ede571b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102df611440565b61030a6040518060800160405280600081526020016000815260200160008152602001600081525090565b610312611491565b7f79537812dfe48a92fc860b8b010e8d6078b5c19e7037c4cf07f7bed69b54fffc815261033d6114af565b6000805b8860ff168160ff1610156105e15787828861035d6020836117b5565b945061036c92859291906117c8565b610375916117f2565b80865260208086019190915288908390899061039190836117b5565b94506103a092859291906117c8565b6103a9916117f2565b602086810182905260408601919091528890839089906103c990836117b5565b94506103d892859291906117c8565b6103e1916117f2565b6040860181905260608501528782886103fb6020836117b5565b945061040a92859291906117c8565b610413916117f2565b606086018190526080850152600088838961042f6020836117b5565b955061043e92869291906117c8565b610447916117f2565b9050600089898581811061045d5761045d611786565b9050013560f81c60f81b905060018461047691906117b5565b60a087208087527fff000000000000000000000000000000000000000000000000000000000000008316602088015260218720919550906104b88982866108c7565b6104ee576040517f76d4e1e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88518a60ff87166020811061050557610505611786565b6020020151600001818152505088602001518a8660ff166020811061052c5761052c611786565b6020020151602001818152505088604001518a8660ff166020811061055357610553611786565b6020020151604001818152505088606001518a8660ff166020811061057a5761057a611786565b60200201516060018181525050888e8660ff166020811061059d5761059d611786565b600402016000820151816000015560208201518160010155604082015181600201556060820151816003015590505050505050806105da9061182e565b9050610341565b5060005b8860ff168110156107545760006105fd8260016117b5565b90505b8960ff168110156107435786816020811061061d5761061d611786565b60200201516000015187836020811061063857610638611786565b60200201515114801561067e575086816020811061065857610658611786565b60200201516020015187836020811061067357610673611786565b602002015160200151145b80156106bd575086816020811061069757610697611786565b6020020151604001518783602081106106b2576106b2611786565b602002015160400151145b80156106fc57508681602081106106d6576106d6611786565b6020020151606001518783602081106106f1576106f1611786565b602002015160600151145b15610733576040517f96bfdb4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073c8161184d565b9050610600565b5061074d8161184d565b90506105e5565b50505050505050505050565b80516020808301919091206040805180840187905267ffffffffffffffff86168183015260608082019390935281518082039093018352608001905280519101205b9392505050565b602581146107e3576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61080e6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061081f888860ff168686610a47565b909250905061082f866001611885565b60ff16811461086a576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080602160048701600037600051915086600052602160002090506108918482846108c7565b610754576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080806108d787610c05565b91965094509250846108f1576000955050505050506107a2565b61091c7fbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8916610c05565b9196509250905084610936576000955050505050506107a2565b60006040518061018001604052808681526020018581526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec81526020017f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d81526020018481526020018381526020018b6000015181526020018b6020015181526020018b6040015181526020018b606001518152509050610a246114cd565b6020816101808460085afa610a3857600080fd5b519a9950505050505050505050565b610a726040518060800160405280600081526020016000815260200160008152602001600081525090565b600080610a8260048286886117c8565b610a8b9161189e565b60e01c9050801580610aa057506001861b8110155b15610ad7576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81600116600003610afc5760019190911c90610af58161184d565b9050610ada565b600192506000610b53898360208110610b1757610b17611786565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610d99565b9050610b5e8261184d565b9150600183901c92505b8215610bee576001831615610bd757610bc9818a8460208110610b8d57610b8d611786565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610e08565b9050610bd48461184d565b93505b60019290921c91610be78261184d565b9150610b68565b610bf7816110a3565b945050505094509492505050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216817f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478210610c6057506000915081905080610d92565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47857f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4787880909089050610d07816002610d007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760016117b5565b901c61114f565b9150807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4783840914610d4457600080600093509350935050610d92565b60ff85901c600183168114610d8b577f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47610d7e84826118e6565b610d88919061172f565b92505b6001945050505b9193909250565b610dd26040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8151815260208083015190820152604080830151908201526060918201519181019190915260006080820152600160a082015290565b610e416040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47608084015160a08501518281830983818208905083848485098503858485090884858286098684860908858684870987038784870908885160208a015188898684098a88840908898a8885098b038b888509088d51935060208e015192508a848c03830891508a838c03820890508a828b0899508a818a089850898b8a8c099a508b8b8c089a508b8c8283098d038d8c8d09089950508a888c038b0899508a878c038a0898508a81830997508a88890897508a8b8384098c038c8384090896508a888c038b0899508a878c038a0898508960808d01528860a08d01528a8860040999508a8760040998508a8b8a84098c8c84090897508a8b8b84098c038c8b84090896508a8b8a86098c8c86090891508a8b8b86098c038c8b860908905060408d0151995060608d015198508a8b868c098c888c090893508a8b878c098c038c878c0908925060408e0151995060608e015198508a8a8c03850895508a898c03840894508a8660020993508a8560020992508a83850995508a86870895508a8b8586098c038c8586090894508a888c03870895508a878c03860894508a8b888c098c8a8c09088b8c8a8d098d038d8a8d09088c826002099b508c816002099a5050508a8260020997508a8160020996508a888c03870897508a878c0386089650878c528660208d01528a888c03830897508a878c0382089650505088898684098a88840908935088898784098a038a878409089250505086868803830895508685880382089450505050508160408501528060608501525050505b92915050565b6110ce6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000806110e384608001518560a001516111b2565b915091506000806110f484846112b6565b9150915061110c82828860000151896020015161137a565b6020870152855261111f8282868661137a565b809250819350505061113b82828860400151896060015161137a565b606087015260408601525092949350505050565b600060405160208152602080820152602060408201528360608201528260808201527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760a082015260208160c08360055afa6111aa57600080fd5b519392505050565b600080807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808687097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478687090890506112368161123160027f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476118e6565b61114f565b90507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4781611284877f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476118e6565b0992507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478185099150505b9250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4784840991507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4782830891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808586097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478586090890509250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808488097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478688090891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808588097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785880908905094509492505050565b6040518061040001604052806020905b61147b6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816114505790505090565b6040518060a001604052806005906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b803560ff811681146114fc57600080fd5b919050565b60008083601f84011261151357600080fd5b50813567ffffffffffffffff81111561152b57600080fd5b6020830191508360208285010111156112af57600080fd5b60008060008060006080868803121561155b57600080fd5b853563ffffffff8116811461156f57600080fd5b945061157d602087016114eb565b935061158b604087016114eb565b9250606086013567ffffffffffffffff8111156115a757600080fd5b6115b388828901611501565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060008060006080868803121561160b57600080fd5b85359450602086013567ffffffffffffffff808216821461162b57600080fd5b9094506040870135908082111561164157600080fd5b818801915088601f83011261165557600080fd5b813581811115611667576116676115c4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156116ad576116ad6115c4565b816040528281528b60208487010111156116c657600080fd5b8260208601602083013760006020848301015280975050505060608801359150808211156116f357600080fd5b506115b388828901611501565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261173e5761173e611700565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008261178157611781611700565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111561109d5761109d611743565b600080858511156117d857600080fd5b838611156117e557600080fd5b5050820193919092039150565b8035602083101561109d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b600060ff821660ff810361184457611844611743565b60010192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361187e5761187e611743565b5060010190565b60ff818116838216019081111561109d5761109d611743565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156118de5780818660040360031b1b83161692505b505092915050565b8181038181111561109d5761109d61174356fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"AttestationVerificationKeysOfInvalidSize\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfAttestationVerificationKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfAttestationVerificationKeysExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"ocr3BlsSignerPublicKeys\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"seqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50611906806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636f289d411461003b57806395fd15c814610050575b600080fd5b61004e610049366004611543565b610063565b005b61004e61005e3660046115f3565b610104565b6040805160608101825263ffffffff871680825260ff8781166020840181905290871692909301829052608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000016909117640100000000909302929092177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff16650100000000009091021790556100fd8483836101d7565b5050505050565b6040805160608101825260805463ffffffff8116825260ff6401000000008204811660208401819052650100000000009092041692820183905290916101519188918891908888886101e9565b805160808054602084015160409094015163ffffffff9093167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009091161764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff166501000000000093909216929092021790555050505050565b6101e46000848484610211565b505050565b60006101f6888886610760565b9050610207600087878487876107a9565b5050505050505050565b61021c60a18261172f565b15610253576040517ff065284400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff831661026260a183611772565b14610299576040517f680d418700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208360ff1611156102d7576040517ffd6c8dce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102df611440565b61030a6040518060800160405280600081526020016000815260200160008152602001600081525090565b610312611491565b7f79537812dfe48a92fc860b8b010e8d6078b5c19e7037c4cf07f7bed69b54fffc815261033d6114af565b6000805b8860ff168160ff1610156105e15787828861035d6020836117b5565b945061036c92859291906117c8565b610375916117f2565b80865260208086019190915288908390899061039190836117b5565b94506103a092859291906117c8565b6103a9916117f2565b602086810182905260408601919091528890839089906103c990836117b5565b94506103d892859291906117c8565b6103e1916117f2565b6040860181905260608501528782886103fb6020836117b5565b945061040a92859291906117c8565b610413916117f2565b606086018190526080850152600088838961042f6020836117b5565b955061043e92869291906117c8565b610447916117f2565b9050600089898581811061045d5761045d611786565b9050013560f81c60f81b905060018461047691906117b5565b60a087208087527fff000000000000000000000000000000000000000000000000000000000000008316602088015260218720919550906104b88982866108c7565b6104ee576040517f51e8c2fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88518a60ff87166020811061050557610505611786565b6020020151600001818152505088602001518a8660ff166020811061052c5761052c611786565b6020020151602001818152505088604001518a8660ff166020811061055357610553611786565b6020020151604001818152505088606001518a8660ff166020811061057a5761057a611786565b60200201516060018181525050888e8660ff166020811061059d5761059d611786565b600402016000820151816000015560208201518160010155604082015181600201556060820151816003015590505050505050806105da9061182e565b9050610341565b5060005b8860ff168110156107545760006105fd8260016117b5565b90505b8960ff168110156107435786816020811061061d5761061d611786565b60200201516000015187836020811061063857610638611786565b60200201515114801561067e575086816020811061065857610658611786565b60200201516020015187836020811061067357610673611786565b602002015160200151145b80156106bd575086816020811061069757610697611786565b6020020151604001518783602081106106b2576106b2611786565b602002015160400151145b80156106fc57508681602081106106d6576106d6611786565b6020020151606001518783602081106106f1576106f1611786565b602002015160600151145b15610733576040517fb717a60a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073c8161184d565b9050610600565b5061074d8161184d565b90506105e5565b50505050505050505050565b80516020808301919091206040805180840187905267ffffffffffffffff86168183015260608082019390935281518082039093018352608001905280519101205b9392505050565b602581146107e3576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61080e6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061081f888860ff168686610a47565b909250905061082f866001611885565b60ff16811461086a576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080602160048701600037600051915086600052602160002090506108918482846108c7565b610754576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080806108d787610c05565b91965094509250846108f1576000955050505050506107a2565b61091c7fbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8916610c05565b9196509250905084610936576000955050505050506107a2565b60006040518061018001604052808681526020018581526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec81526020017f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d81526020018481526020018381526020018b6000015181526020018b6020015181526020018b6040015181526020018b606001518152509050610a246114cd565b6020816101808460085afa610a3857600080fd5b519a9950505050505050505050565b610a726040518060800160405280600081526020016000815260200160008152602001600081525090565b600080610a8260048286886117c8565b610a8b9161189e565b60e01c9050801580610aa057506001861b8110155b15610ad7576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81600116600003610afc5760019190911c90610af58161184d565b9050610ada565b600192506000610b53898360208110610b1757610b17611786565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610d99565b9050610b5e8261184d565b9150600183901c92505b8215610bee576001831615610bd757610bc9818a8460208110610b8d57610b8d611786565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610e08565b9050610bd48461184d565b93505b60019290921c91610be78261184d565b9150610b68565b610bf7816110a3565b945050505094509492505050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216817f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478210610c6057506000915081905080610d92565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47857f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4787880909089050610d07816002610d007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760016117b5565b901c61114f565b9150807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4783840914610d4457600080600093509350935050610d92565b60ff85901c600183168114610d8b577f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47610d7e84826118e6565b610d88919061172f565b92505b6001945050505b9193909250565b610dd26040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8151815260208083015190820152604080830151908201526060918201519181019190915260006080820152600160a082015290565b610e416040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47608084015160a08501518281830983818208905083848485098503858485090884858286098684860908858684870987038784870908885160208a015188898684098a88840908898a8885098b038b888509088d51935060208e015192508a848c03830891508a838c03820890508a828b0899508a818a089850898b8a8c099a508b8b8c089a508b8c8283098d038d8c8d09089950508a888c038b0899508a878c038a0898508a81830997508a88890897508a8b8384098c038c8384090896508a888c038b0899508a878c038a0898508960808d01528860a08d01528a8860040999508a8760040998508a8b8a84098c8c84090897508a8b8b84098c038c8b84090896508a8b8a86098c8c86090891508a8b8b86098c038c8b860908905060408d0151995060608d015198508a8b868c098c888c090893508a8b878c098c038c878c0908925060408e0151995060608e015198508a8a8c03850895508a898c03840894508a8660020993508a8560020992508a83850995508a86870895508a8b8586098c038c8586090894508a888c03870895508a878c03860894508a8b888c098c8a8c09088b8c8a8d098d038d8a8d09088c826002099b508c816002099a5050508a8260020997508a8160020996508a888c03870897508a878c0386089650878c528660208d01528a888c03830897508a878c0382089650505088898684098a88840908935088898784098a038a878409089250505086868803830895508685880382089450505050508160408501528060608501525050505b92915050565b6110ce6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000806110e384608001518560a001516111b2565b915091506000806110f484846112b6565b9150915061110c82828860000151896020015161137a565b6020870152855261111f8282868661137a565b809250819350505061113b82828860400151896060015161137a565b606087015260408601525092949350505050565b600060405160208152602080820152602060408201528360608201528260808201527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760a082015260208160c08360055afa6111aa57600080fd5b519392505050565b600080807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808687097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478687090890506112368161123160027f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476118e6565b61114f565b90507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4781611284877f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476118e6565b0992507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478185099150505b9250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4784840991507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4782830891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808586097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478586090890509250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808488097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478688090891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808588097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785880908905094509492505050565b6040518061040001604052806020905b61147b6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816114505790505090565b6040518060a001604052806005906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b803560ff811681146114fc57600080fd5b919050565b60008083601f84011261151357600080fd5b50813567ffffffffffffffff81111561152b57600080fd5b6020830191508360208285010111156112af57600080fd5b60008060008060006080868803121561155b57600080fd5b853563ffffffff8116811461156f57600080fd5b945061157d602087016114eb565b935061158b604087016114eb565b9250606086013567ffffffffffffffff8111156115a757600080fd5b6115b388828901611501565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060008060006080868803121561160b57600080fd5b85359450602086013567ffffffffffffffff808216821461162b57600080fd5b9094506040870135908082111561164157600080fd5b818801915088601f83011261165557600080fd5b813581811115611667576116676115c4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156116ad576116ad6115c4565b816040528281528b60208487010111156116c657600080fd5b8260208601602083013760006020848301015280975050505060608801359150808211156116f357600080fd5b506115b388828901611501565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261173e5761173e611700565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008261178157611781611700565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111561109d5761109d611743565b600080858511156117d857600080fd5b838611156117e557600080fd5b5050820193919092039150565b8035602083101561109d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b600060ff821660ff810361184457611844611743565b60010192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361187e5761187e611743565b5060010190565b60ff818116838216019081111561109d5761109d611743565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156118de5780818660040360031b1b83161692505b505092915050565b8181038181111561109d5761109d61174356fea164736f6c6343000813000a", } // DemoBLSAttestationVerifierABI is the input ABI used to generate the binding from. diff --git a/gethwrappers3/demoecdsaattestationverifier/demoecdsaattestationverifier.go b/gethwrappers3/demoecdsaattestationverifier/demoecdsaattestationverifier.go index 985bd0d7..33f40d32 100644 --- a/gethwrappers3/demoecdsaattestationverifier/demoecdsaattestationverifier.go +++ b/gethwrappers3/demoecdsaattestationverifier/demoecdsaattestationverifier.go @@ -31,8 +31,8 @@ var ( // DemoECDSAAttestationVerifierMetaData contains all meta data concerning the DemoECDSAAttestationVerifier contract. var DemoECDSAAttestationVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"DuplicateKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"KeysOfInvalidSize\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfKeysExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"ocr3EcdsaSignerPublicKeys\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"seqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610ad3806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636f289d411461003b57806395fd15c814610050575b600080fd5b61004e61004936600461071b565b610063565b005b61004e61005e3660046107cb565b610103565b6040805160608101825263ffffffff871680825260ff87811660208085018290529188169390940183905280547fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000016909117640100000000909302929092177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff16650100000000009091021790556100fc8483836101d5565b5050505050565b604080516060810182526020805463ffffffff8116835260ff64010000000082048116928401839052650100000000009091041692820183905290916101509188918891908888886101e7565b8051602080548184015160409094015163ffffffff9093167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009091161764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff166501000000000093909216929092021790555050505050565b6101e26000848484610241565b505050565b8251602080850191909120604080518084018b905267ffffffffffffffff8a16818301526060808201939093528151808203909301835260800190528051910120610237600087878487876104fd565b5050505050505050565b61024c601482610907565b15610283576040517fadd4994500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff831661029260148361094a565b146102c9576040517fa07f647e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208360ff161115610307576040517f1ede571b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030f61069d565b6000805b8560ff1681101561041857600085838661032e82601461095e565b9261033b93929190610977565b610344916109a1565b60601c90506000819003610384576040517f76d4e1e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80848360208110610397576103976109e9565b602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff168883602081106103f7576103f76109e9565b015561040460148461095e565b9250508061041190610a18565b9050610313565b5060005b8560ff168110156104f457600061043482600161095e565b90505b8660ff168110156104e357838160208110610454576104546109e9565b602002015173ffffffffffffffffffffffffffffffffffffffff16848360208110610481576104816109e9565b602002015173ffffffffffffffffffffffffffffffffffffffff16036104d3576040517f96bfdb4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104dc81610a18565b9050610437565b506104ed81610a18565b905061041c565b50505050505050565b600061050a856001610a50565b60ff16905061051a816040610a69565b61052590600461095e565b821461055d576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061056c6004828587610977565b61057591610a80565b60e01c9050600160ff88161b81106105b9576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080604051878152601b602082015260408101600488018c5b861561061b57600187161561060f576001850194506040828437604082019150600080526020600060808660015afa5060005181541495909501945b600196871c96016105d3565b50505050838214610658576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838114610691576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b6040518061040001604052806020906020820280368337509192915050565b803560ff811681146106cd57600080fd5b919050565b60008083601f8401126106e457600080fd5b50813567ffffffffffffffff8111156106fc57600080fd5b60208301915083602082850101111561071457600080fd5b9250929050565b60008060008060006080868803121561073357600080fd5b853563ffffffff8116811461074757600080fd5b9450610755602087016106bc565b9350610763604087016106bc565b9250606086013567ffffffffffffffff81111561077f57600080fd5b61078b888289016106d2565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806000608086880312156107e357600080fd5b85359450602086013567ffffffffffffffff808216821461080357600080fd5b9094506040870135908082111561081957600080fd5b818801915088601f83011261082d57600080fd5b81358181111561083f5761083f61079c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108855761088561079c565b816040528281528b602084870101111561089e57600080fd5b8260208601602083013760006020848301015280975050505060608801359150808211156108cb57600080fd5b5061078b888289016106d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610916576109166108d8565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082610959576109596108d8565b500490565b808201808211156109715761097161091b565b92915050565b6000808585111561098757600080fd5b8386111561099457600080fd5b5050820193919092039150565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081358181169160148510156109e15780818660140360031b1b83161692505b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a4957610a4961091b565b5060010190565b60ff81811683821601908111156109715761097161091b565b80820281158282048414176109715761097161091b565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156109e15760049490940360031b84901b169092169291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"DuplicateAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfAttestationVerificationKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfAttestationVerificationKeysExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"ocr3EcdsaSignerPublicKeys\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"seqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610a56806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636f289d411461003b57806395fd15c814610050575b600080fd5b61004e61004936600461063f565b610063565b005b61004e61005e36600461073e565b610103565b6040805160608101825263ffffffff871680825260ff87811660208085018290529188169390940183905280547fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000016909117640100000000909302929092177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff16650100000000009091021790556100fc8483836101d5565b5050505050565b604080516060810182526020805463ffffffff8116835260ff64010000000082048116928401839052650100000000009091041692820183905290916101509188918891908888886101e7565b8051602080548184015160409094015163ffffffff9093167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009091161764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff166501000000000093909216929092021790555050505050565b6101e26000848484610241565b505050565b8251602080850191909120604080518084018b905267ffffffffffffffff8a1681830152606080820193909352815180820390930183526080019052805191012061023760008787848787610298565b5050505050505050565b600061024f8284018461082c565b90508360ff1681511461028e576040517f680d418700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6100fc8582610438565b60006102a5856001610927565b60ff1690506102b5816040610946565b6102c090600461095d565b82146102f8576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103076004828587610970565b6103109161099a565b60e01c9050600160ff88161b8110610354576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080604051878152601b602082015260408101600488018c5b86156103b65760018716156103aa576001850194506040828437604082019150600080526020600060808660015afa5060005181541495909501945b600196871c960161036e565b505050508382146103f3576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83811461042c576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b80516020811115610475576040517ffd6c8dce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156105da576000838281518110610494576104946109e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610504576040517f51e8c2fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8281101561059d578173ffffffffffffffffffffffffffffffffffffffff16858281518110610538576105386109e2565b602002602001015173ffffffffffffffffffffffffffffffffffffffff160361058d576040517fb717a60a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61059681610a11565b9050610507565b508073ffffffffffffffffffffffffffffffffffffffff168583602081106105c7576105c76109e2565b0155506105d381610a11565b9050610478565b50505050565b803560ff811681146105f157600080fd5b919050565b60008083601f84011261060857600080fd5b50813567ffffffffffffffff81111561062057600080fd5b60208301915083602082850101111561063857600080fd5b9250929050565b60008060008060006080868803121561065757600080fd5b853563ffffffff8116811461066b57600080fd5b9450610679602087016105e0565b9350610687604087016105e0565b9250606086013567ffffffffffffffff8111156106a357600080fd5b6106af888289016105f6565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610736576107366106c0565b604052919050565b60008060008060006080868803121561075657600080fd5b8535945060208087013567ffffffffffffffff808216821461077757600080fd5b9095506040880135908082111561078d57600080fd5b818901915089601f8301126107a157600080fd5b8135818111156107b3576107b36106c0565b6107e3847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016106ef565b8181528b858386010111156107f757600080fd5b81858501868301376000918101909401529194506060880135918083111561081e57600080fd5b50506106af888289016105f6565b6000602080838503121561083f57600080fd5b823567ffffffffffffffff8082111561085757600080fd5b818501915085601f83011261086b57600080fd5b81358181111561087d5761087d6106c0565b8060051b915061088e8483016106ef565b81815291830184019184810190888411156108a857600080fd5b938501935b838510156108ec578435925073ffffffffffffffffffffffffffffffffffffffff831683146108dc5760008081fd5b82825293850193908501906108ad565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115610940576109406108f8565b92915050565b8082028115828204841417610940576109406108f8565b80820180821115610940576109406108f8565b6000808585111561098057600080fd5b8386111561098d57600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156109da5780818660040360031b1b83161692505b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a4257610a426108f8565b506001019056fea164736f6c6343000813000a", } // DemoECDSAAttestationVerifierABI is the input ABI used to generate the binding from. diff --git a/gethwrappers3/ocr3dynamicallydispatchedblsattestationverifierlib/ocr3dynamicallydispatchedblsattestationverifierlib.go b/gethwrappers3/ocr3dynamicallydispatchedblsattestationverifierlib/ocr3dynamicallydispatchedblsattestationverifierlib.go index c0361b56..9b044d87 100644 --- a/gethwrappers3/ocr3dynamicallydispatchedblsattestationverifierlib/ocr3dynamicallydispatchedblsattestationverifierlib.go +++ b/gethwrappers3/ocr3dynamicallydispatchedblsattestationverifierlib/ocr3dynamicallydispatchedblsattestationverifierlib.go @@ -204,8 +204,8 @@ func (_OCR3BLSAttestationVerifierLib *OCR3BLSAttestationVerifierLibTransactorRaw // OCR3DynamicallyDispatchedBLSAttestationVerifierLibMetaData contains all meta data concerning the OCR3DynamicallyDispatchedBLSAttestationVerifierLib contract. var OCR3DynamicallyDispatchedBLSAttestationVerifierLibMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"DuplicateKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"KeysOfInvalidSize\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfKeysExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"getSelectors\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x6116c961003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c806322c95de3146100505780634b503f0b14610065578063e5eae2f6146100be575b600080fd5b61006361005e3660046113f1565b6100de565b005b604080517fe5eae2f60000000000000000000000000000000000000000000000000000000081527f22c95de300000000000000000000000000000000000000000000000000000000602082015281519081900390910190f35b8180156100ca57600080fd5b506100636100d9366004611469565b6100f4565b6100ec868686868686610106565b505050505050565b61010084848484610230565b50505050565b60258114610140576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61016b6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061017c888860ff168686610773565b909250905061018c8660016114f2565b60ff1681146101c7576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080602160048701600037600051915086600052602160002090506101ee848284610931565b610224576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b61023b60a18261153a565b15610272576040517fadd4994500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff831661028160a18361154e565b146102b8576040517fa07f647e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208360ff1611156102f6576040517f1ede571b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102fe6112ee565b6103296040518060800160405280600081526020016000815260200160008152602001600081525090565b61033161133f565b7f79537812dfe48a92fc860b8b010e8d6078b5c19e7037c4cf07f7bed69b54fffc815261035c61135d565b6000805b8860ff168160ff1610156106005787828861037c602083611591565b945061038b92859291906115a4565b610394916115ce565b8086526020808601919091528890839089906103b09083611591565b94506103bf92859291906115a4565b6103c8916115ce565b602086810182905260408601919091528890839089906103e89083611591565b94506103f792859291906115a4565b610400916115ce565b60408601819052606085015287828861041a602083611591565b945061042992859291906115a4565b610432916115ce565b606086018190526080850152600088838961044e602083611591565b955061045d92869291906115a4565b610466916115ce565b9050600089898581811061047c5761047c611562565b9050013560f81c60f81b90506001846104959190611591565b60a087208087527fff000000000000000000000000000000000000000000000000000000000000008316602088015260218720919550906104d7898286610931565b61050d576040517f76d4e1e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88518a60ff87166020811061052457610524611562565b6020020151600001818152505088602001518a8660ff166020811061054b5761054b611562565b6020020151602001818152505088604001518a8660ff166020811061057257610572611562565b6020020151604001818152505088606001518a8660ff166020811061059957610599611562565b60200201516060018181525050888e8660ff16602081106105bc576105bc611562565b600402016000820151816000015560208201518160010155604082015181600201556060820151816003015590505050505050806105f99061160a565b9050610360565b5060005b8860ff1681101561022457600061061c826001611591565b90505b8960ff168110156107625786816020811061063c5761063c611562565b60200201516000015187836020811061065757610657611562565b60200201515114801561069d575086816020811061067757610677611562565b60200201516020015187836020811061069257610692611562565b602002015160200151145b80156106dc57508681602081106106b6576106b6611562565b6020020151604001518783602081106106d1576106d1611562565b602002015160400151145b801561071b57508681602081106106f5576106f5611562565b60200201516060015187836020811061071057610710611562565b602002015160600151145b15610752576040517f96bfdb4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075b81611629565b905061061f565b5061076c81611629565b9050610604565b61079e6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000806107ae60048286886115a4565b6107b791611661565b60e01c90508015806107cc57506001861b8110155b15610803576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816001166000036108285760019190911c9061082181611629565b9050610806565b60019250600061087f89836020811061084357610843611562565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610ab3565b905061088a82611629565b9150600183901c92505b821561091a576001831615610903576108f5818a84602081106108b9576108b9611562565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610b22565b905061090084611629565b93505b60019290921c9161091382611629565b9150610894565b61092381610dbd565b945050505094509492505050565b6000808080808061094187610e69565b919650945092508461095b57600095505050505050610aac565b6109867fbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8916610e69565b91965092509050846109a057600095505050505050610aac565b60006040518061018001604052808681526020018581526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec81526020017f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d81526020018481526020018381526020018b6000015181526020018b6020015181526020018b6040015181526020018b606001518152509050610a8e61137b565b6020816101808460085afa610aa257600080fd5b5196505050505050505b9392505050565b610aec6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8151815260208083015190820152604080830151908201526060918201519181019190915260006080820152600160a082015290565b610b5b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47608084015160a08501518281830983818208905083848485098503858485090884858286098684860908858684870987038784870908885160208a015188898684098a88840908898a8885098b038b888509088d51935060208e015192508a848c03830891508a838c03820890508a828b0899508a818a089850898b8a8c099a508b8b8c089a508b8c8283098d038d8c8d09089950508a888c038b0899508a878c038a0898508a81830997508a88890897508a8b8384098c038c8384090896508a888c038b0899508a878c038a0898508960808d01528860a08d01528a8860040999508a8760040998508a8b8a84098c8c84090897508a8b8b84098c038c8b84090896508a8b8a86098c8c86090891508a8b8b86098c038c8b860908905060408d0151995060608d015198508a8b868c098c888c090893508a8b878c098c038c878c0908925060408e0151995060608e015198508a8a8c03850895508a898c03840894508a8660020993508a8560020992508a83850995508a86870895508a8b8586098c038c8586090894508a888c03870895508a878c03860894508a8b888c098c8a8c09088b8c8a8d098d038d8a8d09088c826002099b508c816002099a5050508a8260020997508a8160020996508a888c03870897508a878c0386089650878c528660208d01528a888c03830897508a878c0382089650505088898684098a88840908935088898784098a038a878409089250505086868803830895508685880382089450505050508160408501528060608501525050505b92915050565b610de86040518060800160405280600081526020016000815260200160008152602001600081525090565b600080610dfd84608001518560a00151610ffd565b91509150600080610e0e8484611101565b91509150610e268282886000015189602001516111c5565b60208701528552610e39828286866111c5565b8092508193505050610e558282886040015189606001516111c5565b606087015260408601525092949350505050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216817f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478210610ec457506000915081905080610ff6565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47857f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4787880909089050610f6b816002610f647f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476001611591565b901c61128b565b9150807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4783840914610fa857600080600093509350935050610ff6565b60ff85901c600183168114610fef577f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47610fe284826116a9565b610fec919061153a565b92505b6001945050505b9193909250565b600080807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808687097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478687090890506110818161107c60027f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476116a9565b61128b565b90507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47816110cf877f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476116a9565b0992507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478185099150505b9250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4784840991507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4782830891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808586097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478586090890509250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808488097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478688090891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808588097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785880908905094509492505050565b600060405160208152602080820152602060408201528360608201528260808201527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760a082015260208160c08360055afa6112e657600080fd5b519392505050565b6040518061040001604052806020905b6113296040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816112fe5790505090565b6040518060a001604052806005906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b803560ff811681146113aa57600080fd5b919050565b60008083601f8401126113c157600080fd5b50813567ffffffffffffffff8111156113d957600080fd5b6020830191508360208285010111156110fa57600080fd5b60008060008060008060a0878903121561140a57600080fd5b8635955061141a60208801611399565b945061142860408801611399565b935060608701359250608087013567ffffffffffffffff81111561144b57600080fd5b61145789828a016113af565b979a9699509497509295939492505050565b6000806000806060858703121561147f57600080fd5b8435935061148f60208601611399565b9250604085013567ffffffffffffffff8111156114ab57600080fd5b6114b7878288016113af565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115610db757610db76114c3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826115495761154961150b565b500690565b60008261155d5761155d61150b565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80820180821115610db757610db76114c3565b600080858511156115b457600080fd5b838611156115c157600080fd5b5050820193919092039150565b80356020831015610db7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b600060ff821660ff8103611620576116206114c3565b60010192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361165a5761165a6114c3565b5060010190565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156116a15780818660040360031b1b83161692505b505092915050565b81810381811115610db757610db76114c356fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"AttestationVerificationKeysOfInvalidSize\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfAttestationVerificationKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfAttestationVerificationKeysExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"getSelectors\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x6116c961003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c806322c95de3146100505780634b503f0b146100655780635af994ad146100be575b600080fd5b61006361005e3660046113f1565b6100de565b005b604080517f5af994ad0000000000000000000000000000000000000000000000000000000081527f22c95de300000000000000000000000000000000000000000000000000000000602082015281519081900390910190f35b8180156100ca57600080fd5b506100636100d9366004611469565b6100f4565b6100ec868686868686610106565b505050505050565b61010084848484610230565b50505050565b60258114610140576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61016b6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061017c888860ff168686610773565b909250905061018c8660016114f2565b60ff1681146101c7576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080602160048701600037600051915086600052602160002090506101ee848284610931565b610224576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b61023b60a18261153a565b15610272576040517ff065284400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff831661028160a18361154e565b146102b8576040517f680d418700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208360ff1611156102f6576040517ffd6c8dce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102fe6112ee565b6103296040518060800160405280600081526020016000815260200160008152602001600081525090565b61033161133f565b7f79537812dfe48a92fc860b8b010e8d6078b5c19e7037c4cf07f7bed69b54fffc815261035c61135d565b6000805b8860ff168160ff1610156106005787828861037c602083611591565b945061038b92859291906115a4565b610394916115ce565b8086526020808601919091528890839089906103b09083611591565b94506103bf92859291906115a4565b6103c8916115ce565b602086810182905260408601919091528890839089906103e89083611591565b94506103f792859291906115a4565b610400916115ce565b60408601819052606085015287828861041a602083611591565b945061042992859291906115a4565b610432916115ce565b606086018190526080850152600088838961044e602083611591565b955061045d92869291906115a4565b610466916115ce565b9050600089898581811061047c5761047c611562565b9050013560f81c60f81b90506001846104959190611591565b60a087208087527fff000000000000000000000000000000000000000000000000000000000000008316602088015260218720919550906104d7898286610931565b61050d576040517f51e8c2fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88518a60ff87166020811061052457610524611562565b6020020151600001818152505088602001518a8660ff166020811061054b5761054b611562565b6020020151602001818152505088604001518a8660ff166020811061057257610572611562565b6020020151604001818152505088606001518a8660ff166020811061059957610599611562565b60200201516060018181525050888e8660ff16602081106105bc576105bc611562565b600402016000820151816000015560208201518160010155604082015181600201556060820151816003015590505050505050806105f99061160a565b9050610360565b5060005b8860ff1681101561022457600061061c826001611591565b90505b8960ff168110156107625786816020811061063c5761063c611562565b60200201516000015187836020811061065757610657611562565b60200201515114801561069d575086816020811061067757610677611562565b60200201516020015187836020811061069257610692611562565b602002015160200151145b80156106dc57508681602081106106b6576106b6611562565b6020020151604001518783602081106106d1576106d1611562565b602002015160400151145b801561071b57508681602081106106f5576106f5611562565b60200201516060015187836020811061071057610710611562565b602002015160600151145b15610752576040517fb717a60a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075b81611629565b905061061f565b5061076c81611629565b9050610604565b61079e6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000806107ae60048286886115a4565b6107b791611661565b60e01c90508015806107cc57506001861b8110155b15610803576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816001166000036108285760019190911c9061082181611629565b9050610806565b60019250600061087f89836020811061084357610843611562565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610ab3565b905061088a82611629565b9150600183901c92505b821561091a576001831615610903576108f5818a84602081106108b9576108b9611562565b60040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050610b22565b905061090084611629565b93505b60019290921c9161091382611629565b9150610894565b61092381610dbd565b945050505094509492505050565b6000808080808061094187610e69565b919650945092508461095b57600095505050505050610aac565b6109867fbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8916610e69565b91965092509050846109a057600095505050505050610aac565b60006040518061018001604052808681526020018581526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec81526020017f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d81526020018481526020018381526020018b6000015181526020018b6020015181526020018b6040015181526020018b606001518152509050610a8e61137b565b6020816101808460085afa610aa257600080fd5b5196505050505050505b9392505050565b610aec6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8151815260208083015190820152604080830151908201526060918201519181019190915260006080820152600160a082015290565b610b5b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47608084015160a08501518281830983818208905083848485098503858485090884858286098684860908858684870987038784870908885160208a015188898684098a88840908898a8885098b038b888509088d51935060208e015192508a848c03830891508a838c03820890508a828b0899508a818a089850898b8a8c099a508b8b8c089a508b8c8283098d038d8c8d09089950508a888c038b0899508a878c038a0898508a81830997508a88890897508a8b8384098c038c8384090896508a888c038b0899508a878c038a0898508960808d01528860a08d01528a8860040999508a8760040998508a8b8a84098c8c84090897508a8b8b84098c038c8b84090896508a8b8a86098c8c86090891508a8b8b86098c038c8b860908905060408d0151995060608d015198508a8b868c098c888c090893508a8b878c098c038c878c0908925060408e0151995060608e015198508a8a8c03850895508a898c03840894508a8660020993508a8560020992508a83850995508a86870895508a8b8586098c038c8586090894508a888c03870895508a878c03860894508a8b888c098c8a8c09088b8c8a8d098d038d8a8d09088c826002099b508c816002099a5050508a8260020997508a8160020996508a888c03870897508a878c0386089650878c528660208d01528a888c03830897508a878c0382089650505088898684098a88840908935088898784098a038a878409089250505086868803830895508685880382089450505050508160408501528060608501525050505b92915050565b610de86040518060800160405280600081526020016000815260200160008152602001600081525090565b600080610dfd84608001518560a00151610ffd565b91509150600080610e0e8484611101565b91509150610e268282886000015189602001516111c5565b60208701528552610e39828286866111c5565b8092508193505050610e558282886040015189606001516111c5565b606087015260408601525092949350505050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216817f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478210610ec457506000915081905080610ff6565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47857f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4787880909089050610f6b816002610f647f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476001611591565b901c61128b565b9150807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4783840914610fa857600080600093509350935050610ff6565b60ff85901c600183168114610fef577f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47610fe284826116a9565b610fec919061153a565b92505b6001945050505b9193909250565b600080807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808687097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478687090890506110818161107c60027f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476116a9565b61128b565b90507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47816110cf877f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476116a9565b0992507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478185099150505b9250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4784840991507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4782830891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808586097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478586090890509250929050565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808488097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478688090891507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47808588097f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47037f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785880908905094509492505050565b600060405160208152602080820152602060408201528360608201528260808201527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760a082015260208160c08360055afa6112e657600080fd5b519392505050565b6040518061040001604052806020905b6113296040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816112fe5790505090565b6040518060a001604052806005906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b803560ff811681146113aa57600080fd5b919050565b60008083601f8401126113c157600080fd5b50813567ffffffffffffffff8111156113d957600080fd5b6020830191508360208285010111156110fa57600080fd5b60008060008060008060a0878903121561140a57600080fd5b8635955061141a60208801611399565b945061142860408801611399565b935060608701359250608087013567ffffffffffffffff81111561144b57600080fd5b61145789828a016113af565b979a9699509497509295939492505050565b6000806000806060858703121561147f57600080fd5b8435935061148f60208601611399565b9250604085013567ffffffffffffffff8111156114ab57600080fd5b6114b7878288016113af565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115610db757610db76114c3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826115495761154961150b565b500690565b60008261155d5761155d61150b565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80820180821115610db757610db76114c3565b600080858511156115b457600080fd5b838611156115c157600080fd5b5050820193919092039150565b80356020831015610db7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b600060ff821660ff8103611620576116206114c3565b60010192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361165a5761165a6114c3565b5060010190565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156116a15780818660040360031b1b83161692505b505092915050565b81810381811115610db757610db76114c356fea164736f6c6343000813000a", } // OCR3DynamicallyDispatchedBLSAttestationVerifierLibABI is the input ABI used to generate the binding from. diff --git a/gethwrappers3/ocr3dynamicallydispatchedecdsaattestationverifierlib/ocr3dynamicallydispatchedecdsaattestationverifierlib.go b/gethwrappers3/ocr3dynamicallydispatchedecdsaattestationverifierlib/ocr3dynamicallydispatchedecdsaattestationverifierlib.go index 8ab5faaa..6c8ed778 100644 --- a/gethwrappers3/ocr3dynamicallydispatchedecdsaattestationverifierlib/ocr3dynamicallydispatchedecdsaattestationverifierlib.go +++ b/gethwrappers3/ocr3dynamicallydispatchedecdsaattestationverifierlib/ocr3dynamicallydispatchedecdsaattestationverifierlib.go @@ -31,8 +31,8 @@ var ( // OCR3DynamicallyDispatchedECDSAAttestationVerifierLibMetaData contains all meta data concerning the OCR3DynamicallyDispatchedECDSAAttestationVerifierLib contract. var OCR3DynamicallyDispatchedECDSAAttestationVerifierLibMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"DuplicateKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"KeysOfInvalidSize\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfKeysExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"getSelectors\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x6108ad61003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c806349e333a6146100505780634b503f0b146100725780635cc513a6146100cb575b600080fd5b81801561005c57600080fd5b5061007061006b3660046105e0565b6100de565b005b604080517f49e333a60000000000000000000000000000000000000000000000000000000081527f5cc513a600000000000000000000000000000000000000000000000000000000602082015281519081900390910190f35b6100706100d936600461063a565b6100f0565b6100ea84848484610106565b50505050565b6100fe8686868686866103c2565b505050505050565b6101116014826106e1565b15610148576040517fadd4994500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff8316610157601483610724565b1461018e576040517fa07f647e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208360ff1611156101cc576040517f1ede571b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101d4610562565b6000805b8560ff168110156102dd5760008583866101f3826014610738565b9261020093929190610751565b6102099161077b565b60601c90506000819003610249576040517f76d4e1e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8084836020811061025c5761025c6107c3565b602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff168883602081106102bc576102bc6107c3565b01556102c9601484610738565b925050806102d6906107f2565b90506101d8565b5060005b8560ff168110156103b95760006102f9826001610738565b90505b8660ff168110156103a857838160208110610319576103196107c3565b602002015173ffffffffffffffffffffffffffffffffffffffff16848360208110610346576103466107c3565b602002015173ffffffffffffffffffffffffffffffffffffffff1603610398576040517f96bfdb4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103a1816107f2565b90506102fc565b506103b2816107f2565b90506102e1565b50505050505050565b60006103cf85600161082a565b60ff1690506103df816040610843565b6103ea906004610738565b8214610422576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104316004828587610751565b61043a9161085a565b60e01c9050600160ff88161b811061047e576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080604051878152601b602082015260408101600488018c5b86156104e05760018716156104d4576001850194506040828437604082019150600080526020600060808660015afa5060005181541495909501945b600196871c9601610498565b5050505083821461051d576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838114610556576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b6040518061040001604052806020906020820280368337509192915050565b803560ff8116811461059257600080fd5b919050565b60008083601f8401126105a957600080fd5b50813567ffffffffffffffff8111156105c157600080fd5b6020830191508360208285010111156105d957600080fd5b9250929050565b600080600080606085870312156105f657600080fd5b8435935061060660208601610581565b9250604085013567ffffffffffffffff81111561062257600080fd5b61062e87828801610597565b95989497509550505050565b60008060008060008060a0878903121561065357600080fd5b8635955061066360208801610581565b945061067160408801610581565b935060608701359250608087013567ffffffffffffffff81111561069457600080fd5b6106a089828a01610597565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826106f0576106f06106b2565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082610733576107336106b2565b500490565b8082018082111561074b5761074b6106f5565b92915050565b6000808585111561076157600080fd5b8386111561076e57600080fd5b5050820193919092039150565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081358181169160148510156107bb5780818660140360031b1b83161692505b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610823576108236106f5565b5060010190565b60ff818116838216019081111561074b5761074b6106f5565b808202811582820484141761074b5761074b6106f5565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156107bb5760049490940360031b84901b169092169291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"DuplicateAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationAttributionBitmask\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestationVerificationKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNumberOfAttestationVerificationKeys\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaximumNumberOfAttestationVerificationKeysExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"getSelectors\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x61086b61003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c80634b503f0b146100505780635cc513a6146100a9578063eb9a9c11146100be575b600080fd5b604080517feb9a9c110000000000000000000000000000000000000000000000000000000081527f5cc513a600000000000000000000000000000000000000000000000000000000602082015281519081900390910190f35b6100bc6100b7366004610505565b6100de565b005b8180156100ca57600080fd5b506100bc6100d936600461057d565b6100f4565b6100ec868686868686610106565b505050505050565b610100848484846102a6565b50505050565b6000610113856001610606565b60ff169050610123816040610625565b61012e90600461063c565b8214610166576040517f1174ad8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610175600482858761064f565b61017e91610679565b60e01c9050600160ff88161b81106101c2576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080604051878152601b602082015260408101600488018c5b8615610224576001871615610218576001850194506040828437604082019150600080526020600060808660015afa5060005181541495909501945b600196871c96016101dc565b50505050838214610261576040517fddbf0b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83811461029a576040517ff4e04eaa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b60006102b482840184610714565b90508360ff168151146102f3576040517f680d418700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102fd8582610304565b5050505050565b80516020811115610341576040517ffd6c8dce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610100576000838281518110610360576103606107f7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036103d0576040517f51e8c2fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610469578173ffffffffffffffffffffffffffffffffffffffff16858281518110610404576104046107f7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610459576040517fb717a60a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61046281610826565b90506103d3565b508073ffffffffffffffffffffffffffffffffffffffff16858360208110610493576104936107f7565b01555061049f81610826565b9050610344565b803560ff811681146104b757600080fd5b919050565b60008083601f8401126104ce57600080fd5b50813567ffffffffffffffff8111156104e657600080fd5b6020830191508360208285010111156104fe57600080fd5b9250929050565b60008060008060008060a0878903121561051e57600080fd5b8635955061052e602088016104a6565b945061053c604088016104a6565b935060608701359250608087013567ffffffffffffffff81111561055f57600080fd5b61056b89828a016104bc565b979a9699509497509295939492505050565b6000806000806060858703121561059357600080fd5b843593506105a3602086016104a6565b9250604085013567ffffffffffffffff8111156105bf57600080fd5b6105cb878288016104bc565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff818116838216019081111561061f5761061f6105d7565b92915050565b808202811582820484141761061f5761061f6105d7565b8082018082111561061f5761061f6105d7565b6000808585111561065f57600080fd5b8386111561066c57600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156106b95780818660040360031b1b83161692505b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803573ffffffffffffffffffffffffffffffffffffffff811681146104b757600080fd5b6000602080838503121561072757600080fd5b823567ffffffffffffffff8082111561073f57600080fd5b818501915085601f83011261075357600080fd5b813581811115610765576107656106c1565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811085821117156107a8576107a86106c1565b6040529182528482019250838101850191888311156107c657600080fd5b938501935b828510156107eb576107dc856106f0565b845293850193928501926107cb565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610857576108576105d7565b506001019056fea164736f6c6343000813000a", } // OCR3DynamicallyDispatchedECDSAAttestationVerifierLibABI is the input ABI used to generate the binding from. diff --git a/internal/mt/mt.go b/internal/mt/mt.go index c3f4aec2..1a98535c 100644 --- a/internal/mt/mt.go +++ b/internal/mt/mt.go @@ -126,6 +126,14 @@ func Verify(expectedRootDigest Digest, index uint64, leafPreimage []byte, proof currentIndex /= 2 } + // Each proof element consumes one bit of the index. If any bits remain, the + // index is larger than what a proof of this length can encode + // (index >= 2^len(proof)). Such indices must be rejected, otherwise the + // same (leaf, proof) pair verifies for multiple indices (index malleability). + if currentIndex != 0 { + return fmt.Errorf("index %d out of bounds for proof of length %d", index, len(proof)) + } + if currentDigest != expectedRootDigest { return fmt.Errorf("computed root digest mismatch: computed %x, expected %x", currentDigest, expectedRootDigest) } diff --git a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go index 702262df..87d80f05 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go +++ b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go @@ -80,40 +80,26 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp } notBadCount := 0 // Note: just because a request is not marked bad does not mean it's good. Tertium datur! - for _, epochStartRequest := range outgen.leaderState.epochStartRequests { - if epochStartRequest.bad { - continue - } - notBadCount++ - } - - if notBadCount < outgen.config.ByzQuorumSize() { - return - } - - // The not-bad entries in epochStartRequests here are guaranteed to be - // nonempty due to definition of ByzQuorumSize. var maxSender *commontypes.OracleID for sender, epochStartRequest := range outgen.leaderState.epochStartRequests { if epochStartRequest.bad { continue } - if maxSender != nil { - maxTimestamp := outgen.leaderState.epochStartRequests[*maxSender].message.HighestCertified.Timestamp() - if !maxTimestamp.Less(epochStartRequest.message.HighestCertified.Timestamp()) { - continue - } + notBadCount++ + + if maxSender == nil || outgen.leaderState.epochStartRequests[*maxSender].message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp.Less(epochStartRequest.message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp) { + sender := sender + maxSender = &sender } - maxSender = &sender } - if maxSender == nil { + if maxSender == nil || notBadCount < outgen.config.ByzQuorumSize() { return } maxRequest := outgen.leaderState.epochStartRequests[*maxSender] - if !maxRequest.message.HighestCertified.Timestamp().Equal(maxRequest.message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp) { + if maxRequest.message.HighestCertified.Timestamp() != maxRequest.message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp { maxRequest.bad = true outgen.logger.Warn("timestamp mismatch in MessageEpochStartRequest", commontypes.LogFields{ "sender": *maxSender, @@ -163,16 +149,11 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp if err := epochStartProof.Verify(outgen.ID(), outgen.config.OracleIdentities, outgen.config.ByzQuorumSize()); err != nil { outgen.logger.Critical("EpochStartProof is invalid, very surprising!", commontypes.LogFields{ "proof": epochStartProof, + "error": err, }) return } - outgen.leaderState.phase = outgenLeaderPhaseSentEpochStart - - outgen.logger.Info("broadcasting MessageEpochStart", commontypes.LogFields{ - "contributors": contributors, - }) - epochStartSignature31, err := MakeEpochStartSignature31( outgen.ID(), epochStartProof, @@ -186,6 +167,13 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp return } + outgen.leaderState.phase = outgenLeaderPhaseSentEpochStart + + outgen.logger.Info("broadcasting MessageEpochStart", commontypes.LogFields{ + "contributors": contributors, + "highestCertifiedTimestamp": epochStartProof.HighestCertified.Timestamp(), + }) + outgen.netSender.Broadcast(MessageEpochStart[RI]{ outgen.sharedState.e, epochStartProof, diff --git a/offchainreporting2plus/internal/ocr3/protocol/signed_data.go b/offchainreporting2plus/internal/ocr3/protocol/signed_data.go index 91c4f779..3cab3807 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/signed_data.go +++ b/offchainreporting2plus/internal/ocr3/protocol/signed_data.go @@ -274,10 +274,6 @@ func (t HighestCertifiedTimestamp) Less(t2 HighestCertifiedTimestamp) bool { t.SeqNr == t2.SeqNr && t.CommittedElsePrepared == t2.CommittedElsePrepared && t.Epoch < t2.Epoch } -func (t HighestCertifiedTimestamp) Equal(t2 HighestCertifiedTimestamp) bool { - return t.SeqNr == t2.SeqNr && t.CommittedElsePrepared == t2.CommittedElsePrepared && t.Epoch == t2.Epoch -} - const signedHighestCertifiedTimestampDomainSeparator = "ocr3 SignedHighestCertifiedTimestamp" type SignedHighestCertifiedTimestamp struct { @@ -414,7 +410,7 @@ func (qc *EpochStartProof) Verify( } } - if !qc.HighestCertified.Timestamp().Equal(maximumTimestamp) { + if qc.HighestCertified.Timestamp() != maximumTimestamp { return fmt.Errorf("mismatch between timestamp of HighestCertified (%v) and the max from HighestCertifiedProof (%v)", qc.HighestCertified.Timestamp(), maximumTimestamp) } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/event.go b/offchainreporting2plus/internal/ocr3_1/protocol/event.go index 2e31ad35..a46585b6 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/event.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/event.go @@ -10,20 +10,24 @@ type EventToPacemaker[RI any] interface { processPacemaker(pace *pacemakerState[RI]) } -type EventProgress[RI any] struct{} +type EventProgress[RI any] struct { + Epoch uint64 +} var _ EventToPacemaker[struct{}] = (*EventProgress[struct{}])(nil) // implements EventToPacemaker func (ev EventProgress[RI]) processPacemaker(pace *pacemakerState[RI]) { - pace.eventProgress() + pace.eventProgress(ev) } -type EventNewEpochRequest[RI any] struct{} +type EventNewEpochRequest[RI any] struct { + Epoch uint64 +} var _ EventToPacemaker[struct{}] = (*EventNewEpochRequest[struct{}])(nil) // implements EventToPacemaker func (ev EventNewEpochRequest[RI]) processPacemaker(pace *pacemakerState[RI]) { - pace.eventNewEpochRequest() + pace.eventNewEpochRequest(ev) } type EventToOutcomeGeneration[RI any] interface { diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/metrics.go b/offchainreporting2plus/internal/ocr3_1/protocol/metrics.go index 286f8ac5..6b2b1c72 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/metrics.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/metrics.go @@ -11,10 +11,38 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3_1types" ) +type attestedStateTransitionBlockWriter string + +const ( + attestedStateTransitionBlockWriterOutcomeGeneration attestedStateTransitionBlockWriter = "outcome_generation" + attestedStateTransitionBlockWriterStateSync attestedStateTransitionBlockWriter = "state_sync" +) + +// newAttestedStateTransitionBlocksWrittenTotal is shared by +// outcomeGenerationMetrics and stateSyncMetrics. The two variants are +// registered from separate structs against the same registerer, and prometheus +// only tolerates that if the name, help and label names match exactly. +func newAttestedStateTransitionBlocksWrittenTotal( + registerer prometheus.Registerer, + logger commontypes.Logger, + writer attestedStateTransitionBlockWriter, +) prometheus.Counter { + c := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "ocr3_1_experimental_attested_state_transition_blocks_written_total", + Help: fmt.Sprintf("Total number of attested state transition blocks written with writer being one of %v", + []attestedStateTransitionBlockWriter{ + attestedStateTransitionBlockWriterOutcomeGeneration, attestedStateTransitionBlockWriterStateSync}), + ConstLabels: prometheus.Labels{"writer": string(writer)}, + }) + metricshelper.RegisterOrLogError(logger, registerer, c, "ocr3_1_experimental_attested_state_transition_blocks_written_total") + return c +} + type pacemakerMetrics struct { - registerer prometheus.Registerer - epoch prometheus.Gauge - leader prometheus.Gauge + registerer prometheus.Registerer + epoch prometheus.Gauge + leader prometheus.Gauge + tProgressTimeoutsTotal prometheus.Counter } func newPacemakerMetrics(registerer prometheus.Registerer, @@ -32,24 +60,33 @@ func newPacemakerMetrics(registerer prometheus.Registerer, }) metricshelper.RegisterOrLogError(logger, registerer, leader, "ocr3_1_experimental_leader_oid") + tProgressTimeoutsTotal := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "ocr3_1_experimental_t_progress_timeouts_total", + Help: "Total number of TProgress timeouts", + }) + metricshelper.RegisterOrLogError(logger, registerer, tProgressTimeoutsTotal, "ocr3_1_experimental_t_progress_timeouts_total") + return &pacemakerMetrics{ registerer, epoch, leader, + tProgressTimeoutsTotal, } } func (pm *pacemakerMetrics) Close() { pm.registerer.Unregister(pm.epoch) pm.registerer.Unregister(pm.leader) + pm.registerer.Unregister(pm.tProgressTimeoutsTotal) } type outcomeGenerationMetrics struct { - registerer prometheus.Registerer - committedSeqNr prometheus.Gauge - sentObservationsTotal prometheus.Counter - includedObservationsTotal prometheus.Counter - ledCommittedRoundsTotal prometheus.Counter + registerer prometheus.Registerer + committedSeqNr prometheus.Gauge + sentObservationsTotal prometheus.Counter + includedObservationsTotal prometheus.Counter + ledCommittedRoundsTotal prometheus.Counter + attestedBlocksWrittenTotal prometheus.Counter } func newOutcomeGenerationMetrics(registerer prometheus.Registerer, @@ -88,12 +125,15 @@ func newOutcomeGenerationMetrics(registerer prometheus.Registerer, }) metricshelper.RegisterOrLogError(logger, registerer, ledCommittedRoundsTotal, "ocr3_1_led_committed_rounds_total") + attestedBlocksWrittenTotal := newAttestedStateTransitionBlocksWrittenTotal(registerer, logger, attestedStateTransitionBlockWriterOutcomeGeneration) + return &outcomeGenerationMetrics{ registerer, committedSeqNr, sentObservationsTotal, includedObservationsTotal, ledCommittedRoundsTotal, + attestedBlocksWrittenTotal, } } @@ -102,6 +142,45 @@ func (om *outcomeGenerationMetrics) Close() { om.registerer.Unregister(om.sentObservationsTotal) om.registerer.Unregister(om.includedObservationsTotal) om.registerer.Unregister(om.ledCommittedRoundsTotal) + om.registerer.Unregister(om.attestedBlocksWrittenTotal) +} + +type stateSyncMetrics struct { + registerer prometheus.Registerer + attestedBlocksWrittenTotal prometheus.Counter + attestedBlocksReplayedTotal prometheus.Counter + treeSyncCompletedTotal prometheus.Counter +} + +func newStateSyncMetrics(registerer prometheus.Registerer, + logger commontypes.Logger) *stateSyncMetrics { + + attestedBlocksWrittenTotal := newAttestedStateTransitionBlocksWrittenTotal(registerer, logger, attestedStateTransitionBlockWriterStateSync) + + attestedBlocksReplayedTotal := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "ocr3_1_experimental_attested_state_transition_blocks_replayed_total", + Help: "Total number of attested state transition blocks replayed", + }) + metricshelper.RegisterOrLogError(logger, registerer, attestedBlocksReplayedTotal, "ocr3_1_experimental_attested_state_transition_blocks_replayed_total") + + treeSyncCompletedTotal := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "ocr3_1_experimental_tree_sync_completed_total", + Help: "Total number of tree synchronizations to a snapshot successfully completed", + }) + metricshelper.RegisterOrLogError(logger, registerer, treeSyncCompletedTotal, "ocr3_1_experimental_tree_sync_completed_total") + + return &stateSyncMetrics{ + registerer, + attestedBlocksWrittenTotal, + attestedBlocksReplayedTotal, + treeSyncCompletedTotal, + } +} + +func (sm *stateSyncMetrics) Close() { + sm.registerer.Unregister(sm.attestedBlocksWrittenTotal) + sm.registerer.Unregister(sm.attestedBlocksReplayedTotal) + sm.registerer.Unregister(sm.treeSyncCompletedTotal) } type blobExchangeMetrics struct { diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go b/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go index a2fa2a18..51fb9b8c 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/oracle.go @@ -288,6 +288,7 @@ func (o *oracleState[RI]) run() { o.id, o.kvDb, o.logger, + o.metricsRegisterer, o.netEndpoint, o.reportingPlugin, ) diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go index 8434d5a8..be6f99bc 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go @@ -649,6 +649,8 @@ func (outgen *outcomeGenerationState[RI]) tryToMoveCertAndKVStateToCommitQC(comm return } + outgen.metrics.attestedBlocksWrittenTotal.Inc() + outgen.logger.Debug("successfully moved kv state to commit qc", commontypes.LogFields{ "oldCommittedKVSeqNr": committedKVSeqNr, "newCommittedKVSeqNr": commitQC.CommitSeqNr, diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go index b511bf89..9b6e18dc 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go @@ -33,7 +33,7 @@ func (outgen *outcomeGenerationState[RI]) eventTInitialTimeout() { "deltaInitial": outgen.config.GetDeltaInitial().String(), }) select { - case outgen.chOutcomeGenerationToPacemaker <- EventNewEpochRequest[RI]{}: + case outgen.chOutcomeGenerationToPacemaker <- EventNewEpochRequest[RI]{outgen.sharedState.e}: case <-outgen.ctx.Done(): return } @@ -981,7 +981,10 @@ func (outgen *outcomeGenerationState[RI]) tryProcessCommitPool() { }) return } + } + } else { + outgen.metrics.attestedBlocksWrittenTotal.Inc() } } @@ -1087,7 +1090,7 @@ func (outgen *outcomeGenerationState[RI]) completeRound() { "rMax": outgen.config.RMax, }) select { - case outgen.chOutcomeGenerationToPacemaker <- EventNewEpochRequest[RI]{}: + case outgen.chOutcomeGenerationToPacemaker <- EventNewEpochRequest[RI]{outgen.sharedState.e}: case <-outgen.ctx.Done(): return } @@ -1100,7 +1103,7 @@ func (outgen *outcomeGenerationState[RI]) completeRound() { "seqNr": outgen.sharedState.seqNr, }) select { - case outgen.chOutcomeGenerationToPacemaker <- EventProgress[RI]{}: + case outgen.chOutcomeGenerationToPacemaker <- EventProgress[RI]{outgen.sharedState.e}: case <-outgen.ctx.Done(): return } @@ -1120,7 +1123,7 @@ func (outgen *outcomeGenerationState[RI]) sendNewEpochRequestToPacemakerDueToLea "seqNr": outgen.sharedState.seqNr, }) select { - case outgen.chOutcomeGenerationToPacemaker <- EventNewEpochRequest[RI]{}: + case outgen.chOutcomeGenerationToPacemaker <- EventNewEpochRequest[RI]{outgen.sharedState.e}: case <-outgen.ctx.Done(): return } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go index 8862bf1f..4c917ae5 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_leader.go @@ -87,13 +87,13 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp return } - goodCount := 0 + notBadCount := 0 // Note: just because a request is not marked bad does not mean it's good. Tertium datur! var maxSender *commontypes.OracleID for sender, epochStartRequest := range outgen.leaderState.epochStartRequests { if epochStartRequest.bad { continue } - goodCount++ + notBadCount++ if maxSender == nil || outgen.leaderState.epochStartRequests[*maxSender].message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp.Less(epochStartRequest.message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp) { sender := sender @@ -101,7 +101,7 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp } } - if maxSender == nil || goodCount < outgen.config.ByzQuorumSize() { + if maxSender == nil || notBadCount < outgen.config.ByzQuorumSize() { return } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/pacemaker.go b/offchainreporting2plus/internal/ocr3_1/protocol/pacemaker.go index 57eadf0f..d74ddf79 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/pacemaker.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/pacemaker.go @@ -188,7 +188,28 @@ func (pace *pacemakerState[RI]) run(restoredState PacemakerState) { } } -func (pace *pacemakerState[RI]) eventProgress() { +func (pace *pacemakerState[RI]) eventProgress(ev EventProgress[RI]) { + if ev.Epoch > pace.e { + pace.logger.Critical("received progress event for future epoch, ignoring. This should not be possible", commontypes.LogFields{ + "eventEpoch": ev.Epoch, + "epoch": pace.e, + }) + // Ignoring progress events from future epochs is the safer choice for + // liveness: if we processed them, we would reset the progress timer and + // could get stuck in the current epoch indefinitely (e.g. if a burst of + // spurious future-epoch progress events keeps arriving). By ignoring, the + // worst case is that we time out after config.DeltaProgress and move to + // the next epoch, devolving into a simpler "1-round per epoch" algorithm + // with leader rotation — which is still live. + return + } + if ev.Epoch < pace.e { + pace.logger.Trace("received progress event for past epoch, ignoring", commontypes.LogFields{ + "eventEpoch": ev.Epoch, + "epoch": pace.e, + }) + return + } pace.tProgress = time.After(pace.config.DeltaProgress) } @@ -202,13 +223,42 @@ func (pace *pacemakerState[RI]) eventTResendTimeout() { } func (pace *pacemakerState[RI]) eventTProgressTimeout() { + pace.metrics.tProgressTimeoutsTotal.Inc() pace.logger.Debug("TProgress fired", commontypes.LogFields{ "deltaProgress": pace.config.DeltaProgress.String(), + "e": pace.e, + "l": pace.l, }) - pace.eventNewEpochRequest() + pace.requestNewEpoch() +} + +func (pace *pacemakerState[RI]) eventNewEpochRequest(ev EventNewEpochRequest[RI]) { + if ev.Epoch > pace.e { + pace.logger.Critical("received new epoch request event for future epoch, ignoring. This should not be possible", commontypes.LogFields{ + "eventEpoch": ev.Epoch, + "epoch": pace.e, + }) + // Ignoring new-epoch requests from future epochs is the safer choice for + // liveness: if we processed them, a burst of spurious future-epoch requests + // could cause us to request new epochs constantly and earlier than expected, + // posing a potential censorship threat. By ignoring, the worst case is that + // we time out after config.DeltaProgress and move to the next epoch, + // devolving into a simpler "1-round per epoch" algorithm with leader + // rotation — which is still live. + return + } + if ev.Epoch < pace.e { + pace.logger.Trace("received new epoch request event for past epoch, ignoring", commontypes.LogFields{ + "eventEpoch": ev.Epoch, + "epoch": pace.e, + }) + return + } + + pace.requestNewEpoch() } -func (pace *pacemakerState[RI]) eventNewEpochRequest() { +func (pace *pacemakerState[RI]) requestNewEpoch() { pace.tProgress = nil epochPlusOne := pace.e + 1 if epochPlusOne <= pace.e { @@ -218,7 +268,7 @@ func (pace *pacemakerState[RI]) eventNewEpochRequest() { if pace.ne < epochPlusOne { // ne ← max{e + 1, ne} if err := pace.persist(PacemakerState{pace.e, epochPlusOne}); err != nil { - pace.logger.Error("could not persist pacemaker state in eventNewEpochRequest", commontypes.LogFields{ + pace.logger.Error("could not persist pacemaker state in requestNewEpoch", commontypes.LogFields{ "error": err, }) } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go index 19aec6e8..b71d4498 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync.go @@ -6,6 +6,7 @@ import ( "time" "github.com/google/btree" + "github.com/prometheus/client_golang/prometheus" "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/internal/loghelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/internal/config/ocr3_1config" @@ -25,9 +26,14 @@ func RunStateSync[RI any]( id commontypes.OracleID, kvDb KeyValueDatabase, logger loghelper.LoggerWithContext, + metricsRegisterer prometheus.Registerer, netSender NetworkSender[RI], reportingPlugin ocr3_1types.ReportingPlugin[RI], ) { + + metrics := newStateSyncMetrics(metricsRegisterer, logger) + defer metrics.Close() + subs := subprocesses.Subprocesses{} defer subs.Wait() @@ -45,7 +51,7 @@ func RunStateSync[RI any]( RunStateSyncReap(ctx, config, logger, database, kvDb) }) subs.Go(func() { - RunStateSyncBlockReplay(ctx, logger, kvDb, chStateSyncToStateSyncBlockReplay, chStateSyncBlockReplayToStateSync) + RunStateSyncBlockReplay(ctx, logger, kvDb, metrics, chStateSyncToStateSyncBlockReplay, chStateSyncBlockReplayToStateSync) }) newStateSyncState(ctx, @@ -55,7 +61,7 @@ func RunStateSync[RI any]( chStateSyncToStateSyncDestroyIfNeeded, chOutcomeGenerationToStateSync, chReportAttestationToStateSync, - config, database, id, kvDb, logger, netSender).run() + config, database, id, kvDb, logger, metrics, netSender).run() } type syncMode int @@ -81,6 +87,7 @@ type stateSyncState[RI any] struct { id commontypes.OracleID kvDb KeyValueDatabase logger loghelper.LoggerWithContext + metrics *stateSyncMetrics netSender NetworkSender[RI] genesisSeqNr uint64 @@ -489,6 +496,7 @@ func newStateSyncState[RI any]( id commontypes.OracleID, kvDb KeyValueDatabase, logger loghelper.LoggerWithContext, + metrics *stateSyncMetrics, netSender NetworkSender[RI], ) *stateSyncState[RI] { oracles := make([]*syncOracle, 0) @@ -516,6 +524,7 @@ func newStateSyncState[RI any]( id, kvDb, logger.MakeUpdated(commontypes.LogFields{"proto": "stasy"}), + metrics, netSender, genesisSeqNr, diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go index 19b5c36b..8f31ec19 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block.go @@ -432,6 +432,7 @@ func (stasy *stateSyncState[RI]) tryCompleteBlockSync() { defer tx.Discard() lastSeqNr := stasy.highestPersistedStateTransitionBlockSeqNr + blocksWritten := 0 for { astb, ok := stasy.blockSyncState.sortedBlockBuffer.Min() if !ok { @@ -457,6 +458,7 @@ func (stasy *stateSyncState[RI]) tryCompleteBlockSync() { } lastSeqNr = seqNr + blocksWritten++ stasy.blockSyncState.sortedBlockBuffer.DeleteMin() } @@ -467,6 +469,7 @@ func (stasy *stateSyncState[RI]) tryCompleteBlockSync() { }) return } + stasy.metrics.attestedBlocksWrittenTotal.Add(float64(blocksWritten)) stasy.highestPersistedStateTransitionBlockSeqNr = lastSeqNr stasy.pleaseTryToReplayBlock() } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block_replay.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block_replay.go index a37d2767..6f619526 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block_replay.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_block_replay.go @@ -30,7 +30,7 @@ func (e *errReplayVerifiedBlock) Unwrap() error { return e.Cause } -func tryReplay(ctx context.Context, kvDb KeyValueDatabase, logger loghelper.LoggerWithContext) error { +func tryReplay(ctx context.Context, kvDb KeyValueDatabase, logger loghelper.LoggerWithContext, metrics *stateSyncMetrics) error { kvReadTxn, err := kvDb.NewReadTransactionUnchecked() if err != nil { return fmt.Errorf("failed to create read transaction") @@ -77,6 +77,7 @@ func tryReplay(ctx context.Context, kvDb KeyValueDatabase, logger loghelper.Logg if err != nil { return fmt.Errorf("failed to replay block %d: %w", seqNr, err) } + metrics.attestedBlocksReplayedTotal.Inc() logger.Debug("StateBlockReplay: 🐌✅ committed", commontypes.LogFields{ "seqNr": seqNr, }) @@ -126,6 +127,7 @@ func RunStateSyncBlockReplay( ctx context.Context, logger loghelper.LoggerWithContext, kvDb KeyValueDatabase, + metrics *stateSyncMetrics, chStateSyncToStateSyncBlockReplay <-chan EventStateSyncBlockReplayWake, chStateSyncBlockReplayToStateSync chan<- EventStateSyncBlockReplayFailure, ) { @@ -159,7 +161,7 @@ func RunStateSyncBlockReplay( } logger.Trace("StateBlockReplay: calling tryReplay", nil) - err := tryReplay(ctx, kvDb, logger) + err := tryReplay(ctx, kvDb, logger, metrics) if err != nil { logger.Warn("StateBlockReplay: failed while trying to replay blocks", commontypes.LogFields{ "error": err, diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go index ffee5bff..5fc6037c 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/state_sync_tree.go @@ -550,6 +550,7 @@ func (stasy *stateSyncState[RI]) messageTreeSyncChunkResponse(msg MessageTreeSyn "targetSeqNr": stasy.treeSyncState.targetSeqNr, "rootDigest": fmt.Sprintf("%x", stasy.treeSyncState.targetStateRootDigest), }) + stasy.metrics.treeSyncCompletedTotal.Inc() stasy.treeSyncCompleted() return case VerifyAndWriteTreeSyncChunkResultOkNeedMore: diff --git a/ragep2p/doc.go b/ragep2p/doc.go index bd33b9d7..4c37f3de 100644 --- a/ragep2p/doc.go +++ b/ragep2p/doc.go @@ -124,4 +124,18 @@ // to a misconfiguration in my infrastructure. // // rate(ragep2p_host_inbound_dials_total[48h]) > 0 +// +// Is my ragep2p host able to accept the inbound connections it receives? +// Isolated failures are expected and harmless, ragep2p retries them with a +// bounded backoff and recovers on its own. A failure that persists, however, +// means that inbound connectivity is degraded and that the host depends +// entirely on its own outbound dials succeeding. This usually points to +// resource limits imposed on the process by the operating system. +// +// While accepts keep failing, ragep2p retries them at least once every five +// seconds. A failure that persists for a full minute therefore shows up as +// about twenty errors, whereas one that resolves within a few seconds shows up +// as no more than a dozen. +// +// increase(ragep2p_host_accept_errors_total[1m]) < 20 package ragep2p diff --git a/ragep2p/metrics.go b/ragep2p/metrics.go index 8be0e1b0..bb908c53 100644 --- a/ragep2p/metrics.go +++ b/ragep2p/metrics.go @@ -10,6 +10,7 @@ import ( type hostMetrics struct { registerer prometheus.Registerer inboundDialsTotal prometheus.Counter + acceptErrorsTotal prometheus.Counter } func newHostMetrics(registerer prometheus.Registerer, logger commontypes.Logger, self types.PeerID) *hostMetrics { @@ -17,20 +18,31 @@ func newHostMetrics(registerer prometheus.Registerer, logger commontypes.Logger, inboundDialsTotal := prometheus.NewCounter(prometheus.CounterOpts{ Name: "ragep2p_host_inbound_dials_total", - Help: "The number of inbound dial attempts received by the host", + Help: "The number of inbound dials successfully accepted by the host", ConstLabels: labels, }) metricshelper.RegisterOrLogError(logger, registerer, inboundDialsTotal, "ragep2p_host_inbound_dials_total") + acceptErrorsTotal := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "ragep2p_host_accept_errors_total", + Help: "The number of errors encountered by the host while accepting inbound connections. " + + "A sustained increase indicates that the host is unable to accept inbound connections.", + ConstLabels: labels, + }) + + metricshelper.RegisterOrLogError(logger, registerer, acceptErrorsTotal, "ragep2p_host_accept_errors_total") + return &hostMetrics{ registerer, inboundDialsTotal, + acceptErrorsTotal, } } func (m *hostMetrics) Close() { m.registerer.Unregister(m.inboundDialsTotal) + m.registerer.Unregister(m.acceptErrorsTotal) } type peerMetrics struct { diff --git a/ragep2p/ragep2p.go b/ragep2p/ragep2p.go index 924c1f2d..3ac17331 100644 --- a/ragep2p/ragep2p.go +++ b/ragep2p/ragep2p.go @@ -44,6 +44,14 @@ const controlRate = MaxStreamsPerPeer / (10.0 * 60) * (frameHeaderEncodedSize + // https://cs.opensource.google/go/go/+/master:src/crypto/tls/conn.go;drc=059a9eedf45f4909db6a24242c106be15fb27193;l=1454 const netTimeout = 5 * time.Second +// Bounds for the exponential backoff applied between failed Accepts in +// Host.listenLoop. Some Accept errors are transient (eg. EMFILE/ENFILE when the +// process has run out of file descriptors), so we must not stop accepting +// inbound connections when we encounter one, but we also must not spin while +// the condition persists. +const minAcceptBackoff = 5 * time.Millisecond +const maxAcceptBackoff = netTimeout + type hostState uint8 const ( @@ -668,13 +676,36 @@ func (ho *Host) listenLoop(ln net.Listener) { } }) + backoff := minAcceptBackoff for { conn, err := ln.Accept() - ho.hostMetrics.inboundDialsTotal.Inc() if err != nil { - ho.logger.Info("Exiting Host.listenLoop due to error while Accepting", commontypes.LogFields{"error": err}) - return + // The listener is closed during shutdown, which makes Accept fail. That's the + // expected way for this loop to exit. + if ho.ctx.Err() != nil { + ho.logger.Info("Exiting Host.listenLoop", nil) + return + } + // Any other error may well be transient, so back off and keep accepting rather + // than permanently giving up on inbound connections. + ho.hostMetrics.acceptErrorsTotal.Inc() + ho.logger.Warn("Error in Host.listenLoop while Accepting, backing off", commontypes.LogFields{ + "error": err, + "backoff": backoff, + "min": minAcceptBackoff, + "max": maxAcceptBackoff, + }) + select { + case <-time.After(backoff): + case <-ho.ctx.Done(): + ho.logger.Info("Exiting Host.listenLoop", nil) + return + } + backoff = min(2*backoff, maxAcceptBackoff) + continue } + backoff = minAcceptBackoff + ho.hostMetrics.inboundDialsTotal.Inc() ho.subprocesses.Go(func() { ho.handleIncomingConnection(conn) }) diff --git a/ragep2p/ragep2pnew/doc.go b/ragep2p/ragep2pnew/doc.go index 77536e2e..1fa9c19b 100644 --- a/ragep2p/ragep2pnew/doc.go +++ b/ragep2p/ragep2pnew/doc.go @@ -124,4 +124,18 @@ // to a misconfiguration in my infrastructure. // // rate(ragep2p_host_inbound_dials_total[48h]) > 0 +// +// Is my ragep2p host able to accept the inbound connections it receives? +// Isolated failures are expected and harmless, ragep2p retries them with a +// bounded backoff and recovers on its own. A failure that persists, however, +// means that inbound connectivity is degraded and that the host depends +// entirely on its own outbound dials succeeding. This usually points to +// resource limits imposed on the process by the operating system. +// +// While accepts keep failing, ragep2p retries them at least once every five +// seconds. A failure that persists for a full minute therefore shows up as +// about twenty errors, whereas one that resolves within a few seconds shows up +// as no more than a dozen. +// +// increase(ragep2p_host_accept_errors_total[1m]) < 20 package ragep2pnew diff --git a/ragep2p/ragep2pnew/metrics.go b/ragep2p/ragep2pnew/metrics.go index f3fad659..cc8c4dc4 100644 --- a/ragep2p/ragep2pnew/metrics.go +++ b/ragep2p/ragep2pnew/metrics.go @@ -11,6 +11,7 @@ import ( type hostMetrics struct { registerer prometheus.Registerer inboundDialsTotal prometheus.Counter + acceptErrorsTotal prometheus.Counter } func newHostMetrics(registerer prometheus.Registerer, logger commontypes.Logger, self types.PeerID) *hostMetrics { @@ -18,20 +19,31 @@ func newHostMetrics(registerer prometheus.Registerer, logger commontypes.Logger, inboundDialsTotal := prometheus.NewCounter(prometheus.CounterOpts{ Name: "ragep2p_host_inbound_dials_total", - Help: "The number of inbound dial attempts received by the host", + Help: "The number of inbound dials successfully accepted by the host", ConstLabels: labels, }) metricshelper.RegisterOrLogError(logger, registerer, inboundDialsTotal, "ragep2p_host_inbound_dials_total") + acceptErrorsTotal := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "ragep2p_host_accept_errors_total", + Help: "The number of errors encountered by the host while accepting inbound connections. " + + "A sustained increase indicates that the host is unable to accept inbound connections.", + ConstLabels: labels, + }) + + metricshelper.RegisterOrLogError(logger, registerer, acceptErrorsTotal, "ragep2p_host_accept_errors_total") + return &hostMetrics{ registerer, inboundDialsTotal, + acceptErrorsTotal, } } func (m *hostMetrics) Close() { m.registerer.Unregister(m.inboundDialsTotal) + m.registerer.Unregister(m.acceptErrorsTotal) } type peerMetrics struct { diff --git a/ragep2p/ragep2pnew/ragep2p.go b/ragep2p/ragep2pnew/ragep2p.go index bb9a90e4..7a214e86 100644 --- a/ragep2p/ragep2pnew/ragep2p.go +++ b/ragep2p/ragep2pnew/ragep2p.go @@ -48,6 +48,14 @@ const MaxMessageLength = types.MaxMessageLength // https://cs.opensource.google/go/go/+/master:src/crypto/tls/conn.go;drc=059a9eedf45f4909db6a24242c106be15fb27193;l=1454 const netTimeout = 5 * time.Second +// Bounds for the exponential backoff applied between failed Accepts in +// Host.listenLoop. Some Accept errors are transient (eg. EMFILE/ENFILE when the +// process has run out of file descriptors), so we must not stop accepting +// inbound connections when we encounter one, but we also must not spin while +// the condition persists. +const minAcceptBackoff = 5 * time.Millisecond +const maxAcceptBackoff = netTimeout + type hostState uint8 const ( @@ -753,13 +761,36 @@ func (ho *Host) listenLoop(ln net.Listener) { } }) + backoff := minAcceptBackoff for { conn, err := ln.Accept() - ho.hostMetrics.inboundDialsTotal.Inc() if err != nil { - ho.logger.Info("Exiting Host.listenLoop due to error while Accepting", commontypes.LogFields{"error": err}) - return + // The listener is closed during shutdown, which makes Accept fail. That's the + // expected way for this loop to exit. + if ho.ctx.Err() != nil { + ho.logger.Info("Exiting Host.listenLoop", nil) + return + } + // Any other error may well be transient, so back off and keep accepting rather + // than permanently giving up on inbound connections. + ho.hostMetrics.acceptErrorsTotal.Inc() + ho.logger.Warn("Error in Host.listenLoop while Accepting, backing off", commontypes.LogFields{ + "error": err, + "backoff": backoff, + "min": minAcceptBackoff, + "max": maxAcceptBackoff, + }) + select { + case <-time.After(backoff): + case <-ho.ctx.Done(): + ho.logger.Info("Exiting Host.listenLoop", nil) + return + } + backoff = min(2*backoff, maxAcceptBackoff) + continue } + backoff = minAcceptBackoff + ho.hostMetrics.inboundDialsTotal.Inc() ho.subprocesses.Go(func() { ho.handleIncomingConnection(conn) })