From 4254eaf04ea7197715c3fb585f00c501110dddf3 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Thu, 5 Dec 2024 21:35:16 -0500 Subject: [PATCH 01/44] feat: adds initial structure for the contract --- contracts/contracts/core/ProviderRegistry.sol | 82 ++++++++++++++++--- .../core/ProviderRegistryStorage.sol | 2 + .../interfaces/IProviderRegistry.sol | 2 +- 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 3d5c63770..2d1a82478 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -302,20 +302,82 @@ contract ProviderRegistry is emit FundsDeposited(provider, msg.value); } - function _registerAndStake(address provider, bytes[] calldata blsPublicKeys) internal { + /** + * @dev Adds a verified BLS key to the provider's account. + * @param provider The address of the provider. + * @param blsPublicKey The BLS public key to be added. + * @param message The message hash (32 bytes) used for verification. + * @param signature The signature (96 bytes) used for verification. + */ + function addVerifiedBLSKey( + bytes calldata blsPublicKey, + bytes calldata signature + ) external { + address provider = msg.sender; + + require(providerRegistered[provider], "Provider not registered"); + require(blsPublicKey.length == 48, "Public key must be 48 bytes"); + require(signature.length == 96, "Signature must be 96 bytes"); + + + bytes32 message = keccak256(abi.encodePacked(provider)); + + // Verify the BLS signature + bool isValid = verifySignature(blsPublicKey, message, signature); + require(isValid, "Invalid BLS signature"); + + // Add the BLS public key to the provider's account + eoaToBlsPubkeys[provider].push(blsPublicKey); + blockBuilderBLSKeyToAddress[blsPublicKey] = provider; + + emit BLSKeyAdded(provider, blsPublicKey); + } + + /** + * @dev Verifies a BLS signature using the precompile + * @param pubKey The public key (48 bytes G1 point) + * @param message The message hash (32 bytes) + * @param signature The signature (96 bytes G2 point) + * @return success True if verification succeeded + */ + function verifySignature( + bytes calldata pubKey, + bytes32 message, + bytes calldata signature + ) public view returns (bool) { + // Input validation + require(pubKey.length == 48, "Public key must be 48 bytes"); + require(signature.length == 96, "Signature must be 96 bytes"); + + // Concatenate inputs in required format: + // [pubkey (48 bytes) | message (32 bytes) | signature (96 bytes)] + bytes memory input = bytes.concat( + pubKey, + message, + signature + ); + + // Call precompile + (bool success, bytes memory result) = BLS_PRECOMPILE.staticcall(input); + + // Check if call was successful + if (!success) { + return false; + } + + // If we got a result back and it's not empty, verification succeeded + return result.length > 0; + } + + event BLSKeyAdded(address indexed provider, bytes blsPublicKey); + + function _registerAndStake(address provider) internal { require(!providerRegistered[provider], ProviderAlreadyRegistered(provider)); require(msg.value >= minStake, InsufficientStake(msg.value, minStake)); - require(blsPublicKeys.length != 0, AtLeastOneBLSKeyRequired()); - uint256 numKeys = blsPublicKeys.length; - for (uint256 i = 0; i < numKeys; ++i) { - bytes memory key = blsPublicKeys[i]; - require(key.length == 48, InvalidBLSPublicKeyLength(key.length, 48)); - blockBuilderBLSKeyToAddress[key] = provider; - } - eoaToBlsPubkeys[provider] = blsPublicKeys; + providerStakes[provider] = msg.value; providerRegistered[provider] = true; - emit ProviderRegistered(provider, msg.value, blsPublicKeys); + emit ProviderRegistered(provider, msg.value); } // solhint-disable-next-line no-empty-blocks diff --git a/contracts/contracts/core/ProviderRegistryStorage.sol b/contracts/contracts/core/ProviderRegistryStorage.sol index 926b8c362..994e7e9b0 100644 --- a/contracts/contracts/core/ProviderRegistryStorage.sol +++ b/contracts/contracts/core/ProviderRegistryStorage.sol @@ -10,6 +10,8 @@ abstract contract ProviderRegistryStorage { uint256 public constant PRECISION = 1e16; uint256 public constant ONE_HUNDRED_PERCENT = 100 * PRECISION; + address private constant BLS_PRECOMPILE = 0xf0; + /// @dev Minimum stake required for registration uint256 public minStake; diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index 089060927..03d63b1d0 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.26; interface IProviderRegistry { /// @dev Event emitted when a provider is registered - event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes[] blsPublicKeys); + event ProviderRegistered(address indexed provider, uint256 stakedAmount); /// @dev Event emitted when funds are deposited event FundsDeposited(address indexed provider, uint256 amount); From 152cdb42ef545b3bc5999f6c4504a073c9027018 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 6 Dec 2024 17:27:08 -0500 Subject: [PATCH 02/44] feat: updates tests with bls verfication --- contracts/contracts/core/ProviderRegistry.sol | 16 +-- .../core/ProviderRegistryStorage.sol | 2 - .../interfaces/IProviderRegistry.sol | 4 +- contracts/test/core/OracleTest.sol | 36 +++++- contracts/test/core/PreconfManagerTest.sol | 33 ++++-- contracts/test/core/ProviderRegistryTest.sol | 103 +++++++++++++----- .../BLSVerifyPreCompileMockTest.sol | 70 ++++++++++++ 7 files changed, 212 insertions(+), 52 deletions(-) create mode 100644 contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 2d1a82478..6b66ddb5a 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -272,20 +272,18 @@ contract ProviderRegistry is /** * @dev Register and stake function for providers. - * @param blsPublicKeys The BLS public keys of the provider. * The validity of this key must be verified manually off-chain. */ - function registerAndStake(bytes[] calldata blsPublicKeys) public payable whenNotPaused { - _registerAndStake(msg.sender, blsPublicKeys); + function registerAndStake() public payable whenNotPaused { + _registerAndStake(msg.sender); } /** * @dev Register and stake on behalf of a provider. * @param provider Address of the provider. - * @param blsPublicKeys BLS public keys of the provider. */ - function delegateRegisterAndStake(address provider, bytes[] calldata blsPublicKeys) public payable whenNotPaused onlyOwner { - _registerAndStake(provider, blsPublicKeys); + function delegateRegisterAndStake(address provider) public payable whenNotPaused onlyOwner { + _registerAndStake(provider); } /// @dev Ensure the provider's balance is greater than minStake and no pending withdrawal @@ -304,9 +302,7 @@ contract ProviderRegistry is /** * @dev Adds a verified BLS key to the provider's account. - * @param provider The address of the provider. * @param blsPublicKey The BLS public key to be added. - * @param message The message hash (32 bytes) used for verification. * @param signature The signature (96 bytes) used for verification. */ function addVerifiedBLSKey( @@ -314,7 +310,7 @@ contract ProviderRegistry is bytes calldata signature ) external { address provider = msg.sender; - + require(providerRegistered[provider], "Provider not registered"); require(blsPublicKey.length == 48, "Public key must be 48 bytes"); require(signature.length == 96, "Signature must be 96 bytes"); @@ -358,7 +354,7 @@ contract ProviderRegistry is ); // Call precompile - (bool success, bytes memory result) = BLS_PRECOMPILE.staticcall(input); + (bool success, bytes memory result) = address(0xf0).staticcall(input); // Check if call was successful if (!success) { diff --git a/contracts/contracts/core/ProviderRegistryStorage.sol b/contracts/contracts/core/ProviderRegistryStorage.sol index 994e7e9b0..926b8c362 100644 --- a/contracts/contracts/core/ProviderRegistryStorage.sol +++ b/contracts/contracts/core/ProviderRegistryStorage.sol @@ -10,8 +10,6 @@ abstract contract ProviderRegistryStorage { uint256 public constant PRECISION = 1e16; uint256 public constant ONE_HUNDRED_PERCENT = 100 * PRECISION; - address private constant BLS_PRECOMPILE = 0xf0; - /// @dev Minimum stake required for registration uint256 public minStake; diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index 03d63b1d0..e7a85272a 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -68,7 +68,7 @@ interface IProviderRegistry { error BidderAmountIsZero(address sender); error BidderWithdrawalTransferFailed(address sender, uint256 amount); - function registerAndStake(bytes[] calldata blsPublicKeys) external payable; + function registerAndStake() external payable; function stake() external payable; @@ -82,4 +82,6 @@ interface IProviderRegistry { function isProviderValid(address committerAddress) external view; function getEoaFromBLSKey(bytes calldata blsKey) external view returns (address); + + function addVerifiedBLSKey(bytes calldata blsPublicKey, bytes calldata signature) external; } diff --git a/contracts/test/core/OracleTest.sol b/contracts/test/core/OracleTest.sol index db6823b4a..595a20ce0 100644 --- a/contracts/test/core/OracleTest.sol +++ b/contracts/test/core/OracleTest.sol @@ -10,6 +10,7 @@ import {BlockTracker} from "../../contracts/core/BlockTracker.sol"; import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; import {WindowFromBlockNumber} from "../../contracts/utils/WindowFromBlockNumber.sol"; import {ECDSA} from "@openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; +import {MockBLSVerify} from "../precompiles/BLSVerifyPreCompileMockTest.sol"; contract OracleTest is Test { using ECDSA for bytes32; @@ -29,6 +30,7 @@ contract OracleTest is Test { bytes public sharedSecretKey; bytes public constant validBLSPubkey = hex"80000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82b"; bytes[] public validBLSPubkeys = [validBLSPubkey]; + bytes public dummyBLSSignature = hex"bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2"; uint256 public constant withdrawalDelay = 24 hours ; // 24 hours uint256 public constant protocolFeePayoutPeriodBlocks = 100; struct TestCommitment { @@ -59,6 +61,10 @@ contract OracleTest is Test { ); function setUp() public { + address BLS_VERIFY_ADDRESS = address(0xf0); + bytes memory code = type(MockBLSVerify).creationCode; + vm.etch(BLS_VERIFY_ADDRESS, code); + testNumber = 2; testNumber2 = 2; sharedSecretKey = bytes("0xsecret"); @@ -178,7 +184,11 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 250 ether}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } +// TODO(@ckartik): Adds a manual register cal vm.stopPrank(); bytes32 index = constructAndStoreCommitment( @@ -226,7 +236,11 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 250 ether}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } +// TODO(@ckartik): Adds a manual register cal vm.stopPrank(); bytes32 index = constructAndStoreCommitment( @@ -280,7 +294,11 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 250 ether}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } +// TODO(@ckartik): Adds a manual register cal vm.stopPrank(); bytes32 index1 = constructAndStoreCommitment( @@ -357,7 +375,11 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 250 ether}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } +// TODO(@ckartik): Adds a manual register cal vm.stopPrank(); bytes32 index1 = constructAndStoreCommitment( @@ -472,7 +494,11 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 250 ether}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } +// TODO(@ckartik): Adds a manual register cal vm.stopPrank(); bytes32[] memory commitments = new bytes32[](4); diff --git a/contracts/test/core/PreconfManagerTest.sol b/contracts/test/core/PreconfManagerTest.sol index 4c8f558d3..ea189d182 100644 --- a/contracts/test/core/PreconfManagerTest.sol +++ b/contracts/test/core/PreconfManagerTest.sol @@ -10,7 +10,7 @@ import {BlockTracker} from "../../contracts/core/BlockTracker.sol"; import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; import {WindowFromBlockNumber} from "../../contracts/utils/WindowFromBlockNumber.sol"; import {IProviderRegistry} from "../../contracts/interfaces/IProviderRegistry.sol"; - +import {MockBLSVerify} from "../precompiles/BLSVerifyPreCompileMockTest.sol"; contract PreconfManagerTest is Test { struct TestCommitment { uint256 bidAmt; @@ -42,10 +42,15 @@ contract PreconfManagerTest is Test { bytes public validBLSPubkey2 = hex"90000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82c"; bytes public validBLSPubkey3 = hex"a0000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82d"; bytes[] public validMultiBLSPubkeys = [validBLSPubkey, validBLSPubkey2, validBLSPubkey3]; + bytes public dummyBLSSignature = hex"bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2"; uint256 public withdrawalDelay; uint256 public protocolFeePayoutPeriodBlocks; address public oracleContract; function setUp() public { + address BLS_VERIFY_ADDRESS = address(0xf0); + bytes memory code = type(MockBLSVerify).creationCode; + vm.etch(BLS_VERIFY_ADDRESS, code); + _testCommitmentAliceBob = TestCommitment( 2, 2, @@ -207,8 +212,14 @@ vm.prank(address(this)); // Optional: Ensure the committer has enough ETH if needed for the operation vm.deal(committer, 1 ether); - vm.prank(committer); - providerRegistry.registerAndStake{value: 1 ether}(validBLSPubkeys); + vm.startPrank(committer); + providerRegistry.registerAndStake{value: 1 ether}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } + vm.stopPrank(); +// TODO: add manaul BLS key registration + // Step 2: Store the commitment vm.prank(committer); @@ -506,7 +517,10 @@ vm.prank(address(this)); ); vm.deal(committer, 11 ether); vm.startPrank(committer); - providerRegistry.registerAndStake{value: 10 ether}(validMultiBLSPubkeys); + providerRegistry.registerAndStake{value: 10 ether}(); + for (uint256 i = 0; i < validMultiBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validMultiBLSPubkeys[i], dummyBLSSignature); + } bytes32 commitmentIndex = preconfManager.storeUnopenedCommitment( commitmentDigest, @@ -626,7 +640,6 @@ vm.prank(address(this)); ); // Step 2: Store the commitment (address committer, ) = makeAddrAndKey("bob"); - providerRegistry.registerAndStake{value: 10 ether}(validBLSPubkeys); bytes32 commitmentIndex = storeCommitment( committer, _testCommitmentAliceBob.bidAmt, @@ -961,8 +974,14 @@ vm.prank(address(this)); // Ensure the committer has enough ETH for the required stake vm.deal(committer, 2 ether); - vm.prank(committer); - providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkeys); + vm.startPrank(committer); + providerRegistry.registerAndStake{value: 2 ether}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } + vm.stopPrank(); +// TODO: add manaul BLS key registration + // Request a withdrawal to create a pending withdrawal request vm.prank(committer); diff --git a/contracts/test/core/ProviderRegistryTest.sol b/contracts/test/core/ProviderRegistryTest.sol index 0c125b237..97cbbdda9 100644 --- a/contracts/test/core/ProviderRegistryTest.sol +++ b/contracts/test/core/ProviderRegistryTest.sol @@ -8,7 +8,7 @@ import {PreconfManager} from "../../contracts/core/PreconfManager.sol"; import {BlockTracker} from "../../contracts/core/BlockTracker.sol"; import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; import {IProviderRegistry} from "../../contracts/interfaces/IProviderRegistry.sol"; - +import {MockBLSVerify} from "../precompiles/BLSVerifyPreCompileMockTest.sol"; contract ProviderRegistryTest is Test { uint256 public testNumber; ProviderRegistry public providerRegistry; @@ -21,9 +21,10 @@ contract ProviderRegistryTest is Test { BlockTracker public blockTracker; uint256 public withdrawalDelay; bytes public validBLSPubkey = hex"80000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82b"; + bytes public dummyBLSSignature = hex"bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2"; bytes[] public validBLSPubkeys = [validBLSPubkey]; uint256 public penaltyFeePayoutPeriodBlocks; - event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes []blsPublicKeys); + event ProviderRegistered(address indexed provider, uint256 stakedAmount); event WithdrawalRequested(address indexed provider, uint256 timestamp); event WithdrawalCompleted(address indexed provider, uint256 amount); event FeeTransfer(uint256 amount, address indexed recipient); @@ -37,6 +38,10 @@ contract ProviderRegistryTest is Test { ); function setUp() public { + address BLS_VERIFY_ADDRESS = address(0xf0); + bytes memory code = type(MockBLSVerify).creationCode; + vm.etch(BLS_VERIFY_ADDRESS, code); + testNumber = 42; feePercent = 10 * 1e16; minStake = 1e18 wei; @@ -109,7 +114,9 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); vm.expectRevert(bytes("")); - providerRegistry.registerAndStake{value: 1 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 1 wei}(); + + } function testFail_ProviderStakeAndRegisterInvalidBLSKey() public { @@ -118,18 +125,23 @@ contract ProviderRegistryTest is Test { vm.expectRevert("Invalid BLS public key length"); bytes[] memory invalidBLSPubkeys = new bytes[](1); invalidBLSPubkeys[0] = abi.encodePacked(uint256(134)); - providerRegistry.registerAndStake{value: 1 wei}(invalidBLSPubkeys); + providerRegistry.registerAndStake{value: 1 wei}(); +// TODO: add manaul BLS key registration + } function test_ProviderStakeAndRegister() public { vm.deal(provider, 3 ether); - vm.prank(provider); + vm.startPrank(provider); vm.expectEmit(true, false, false, true); - emit ProviderRegistered(provider, 1e18 wei, validBLSPubkeys); - - providerRegistry.registerAndStake{value: 1e18 wei}(validBLSPubkeys); + emit ProviderRegistered(provider, 1e18 wei); + providerRegistry.registerAndStake{value: 1e18 wei}(); + for (uint256 i = 0; i < validBLSPubkeys.length; i++) { + providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); + } + vm.stopPrank(); bool isProviderRegistered = providerRegistry.providerRegistered( provider ); @@ -152,9 +164,13 @@ contract ProviderRegistryTest is Test { function testFail_ProviderStakeAndRegisterAlreadyRegistered() public { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + vm.expectRevert(bytes("")); - providerRegistry.registerAndStake{value: 1 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 1 wei}(); +// TODO: add manaul BLS key registration + } function testFail_Receive() public { @@ -236,7 +252,9 @@ contract ProviderRegistryTest is Test { providerRegistry.setPreconfManager(address(this)); vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2 ether}(); +// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.expectCall(bidder, 1000000000000000000 wei, new bytes(0)); @@ -254,7 +272,9 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2 ether}(); +// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.expectCall(bidder, 1000000000000000000 wei, new bytes(0)); @@ -267,7 +287,9 @@ contract ProviderRegistryTest is Test { function testFail_ShouldRetrieveFundsNotPreConf() public { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2 ether}(); +// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.expectRevert(bytes("")); providerRegistry.slash(1 ether, provider, payable(bidder), providerRegistry.ONE_HUNDRED_PERCENT()); @@ -278,7 +300,9 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2 ether}(); +// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.prank(address(this)); @@ -296,7 +320,9 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 3 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 3 ether}(); +// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.prank(address(this)); @@ -314,7 +340,9 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3.1 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 3.1 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 3.1 ether}(); +// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.prank(address(this)); @@ -332,7 +360,9 @@ contract ProviderRegistryTest is Test { address bidder = vm.addr(4); - providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2 ether}(); +// TODO: add manaul BLS key registration + providerRegistry.setPreconfManager(address(this)); providerRegistry.slash(1e18 wei, provider, payable(bidder), 50 * providerRegistry.PRECISION()); assertEq( @@ -344,7 +374,9 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(11); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2 ether}(); +// TODO: add manaul BLS key registration + vm.roll(350); // roll past protocol fee payout period @@ -371,7 +403,9 @@ contract ProviderRegistryTest is Test { uint256 percent = providerRegistry.ONE_HUNDRED_PERCENT(); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + providerRegistry.setPreconfManager( address(preconfManager) ); @@ -398,7 +432,9 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + vm.expectRevert(bytes("")); address wrongNewProvider = vm.addr(12); vm.prank(wrongNewProvider); @@ -409,7 +445,9 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(5); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + assertEq( providerRegistry.providerStakes(newProvider), 2e18 wei, @@ -426,7 +464,9 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + providerRegistry.unstake(); vm.warp(block.timestamp + 24 hours); // Move forward in time vm.expectRevert("Provider Commitments still pending"); @@ -437,7 +477,9 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + vm.prank(newProvider); providerRegistry.unstake(); assertEq( @@ -453,7 +495,9 @@ contract ProviderRegistryTest is Test { uint256 percent = providerRegistry.ONE_HUNDRED_PERCENT(); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + providerRegistry.setPreconfManager( address(preconfManager) ); @@ -480,7 +524,9 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + vm.prank(newProvider); providerRegistry.unstake(); vm.warp(block.timestamp + 23 hours); // Move forward less than 24 hours @@ -500,7 +546,9 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkeys); + providerRegistry.registerAndStake{value: 2e18 wei}(); +// TODO: add manaul BLS key registration + vm.prank(newProvider); vm.expectRevert( abi.encodeWithSelector(IProviderRegistry.NoUnstakeRequest.selector, newProvider) @@ -512,7 +560,8 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(7); vm.prank(address(this)); - providerRegistry.delegateRegisterAndStake{value: 2e18 wei}(newProvider, validBLSPubkeys); + providerRegistry.delegateRegisterAndStake{value: 2e18 wei}(newProvider); + // TODO(@ckartik): Add a manual register call for BLS keys assertEq( providerRegistry.providerStakes(newProvider), 2e18 wei, diff --git a/contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol b/contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol new file mode 100644 index 000000000..b449781c7 --- /dev/null +++ b/contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: BSL 1.1 +pragma solidity 0.8.26; + +import {Test} from "forge-std/Test.sol"; + +contract BLSVerifyPreCompileMock is Test { + address constant BLS_VERIFY = address(0xf0); + + function setUp() public { + // Deploy the mock contract to the precompile address + bytes memory code = type(MockBLSVerify).creationCode; + vm.etch(BLS_VERIFY, code); + } + + function testVerifySignature() public { + // Store the values as constants or immutable variables since they're fixed test data + bytes memory pubKeyData = hex"b67a5148a03229926e34b190af81a82a81c4df66831c98c03a139778418dd09a3b542ced0022620d19f35781ece6dc36"; + bytes32 messageData = keccak256(abi.encodePacked("test message")); + bytes memory signatureData = hex"bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2"; + + // Call verifySignature with the abi.encodePacked data to convert to calldata + bool result = this.verifySignature( + pubKeyData, + messageData, + signatureData + ); + assertTrue(result, "Signature verification should succeed."); + } + /** + * @dev Verifies a BLS signature using the precompile + * @param pubKey The public key (48 bytes G1 point) + * @param message The message hash (32 bytes) + * @param signature The signature (96 bytes G2 point) + * @return success True if verification succeeded + */ + function verifySignature( + bytes calldata pubKey, + bytes32 message, + bytes calldata signature + ) public view returns (bool) { + // Input validation + require(pubKey.length == 48, "Public key must be 48 bytes"); + require(signature.length == 96, "Signature must be 96 bytes"); + + // Concatenate inputs in required format: + // [pubkey (48 bytes) | message (32 bytes) | signature (96 bytes)] + bytes memory input = bytes.concat( + pubKey, + message, + signature + ); + + // Call precompile + (bool success, bytes memory result) = BLS_VERIFY.staticcall(input); + + // Check if call was successful + if (!success) { + return false; + } + + // If we got a result back and it's not empty, verification succeeded + return result.length > 0; + } +} + +contract MockBLSVerify { + function VERIFY(bytes calldata) external pure returns (bool) { + return true; + } +} From ca2310b062fd7a11a9138fd9f89bbd434a5a050d Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sat, 7 Dec 2024 13:45:27 -0500 Subject: [PATCH 03/44] chore: gets rid of stale todos --- contracts/test/core/OracleTest.sol | 10 +++--- contracts/test/core/PreconfManagerTest.sol | 4 +-- contracts/test/core/ProviderRegistryTest.sol | 38 ++++++++++---------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/contracts/test/core/OracleTest.sol b/contracts/test/core/OracleTest.sol index 595a20ce0..6dbc39625 100644 --- a/contracts/test/core/OracleTest.sol +++ b/contracts/test/core/OracleTest.sol @@ -188,7 +188,7 @@ contract OracleTest is Test { for (uint256 i = 0; i < validBLSPubkeys.length; i++) { providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); } -// TODO(@ckartik): Adds a manual register cal + vm.stopPrank(); bytes32 index = constructAndStoreCommitment( @@ -240,7 +240,7 @@ contract OracleTest is Test { for (uint256 i = 0; i < validBLSPubkeys.length; i++) { providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); } -// TODO(@ckartik): Adds a manual register cal + vm.stopPrank(); bytes32 index = constructAndStoreCommitment( @@ -298,7 +298,7 @@ contract OracleTest is Test { for (uint256 i = 0; i < validBLSPubkeys.length; i++) { providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); } -// TODO(@ckartik): Adds a manual register cal + vm.stopPrank(); bytes32 index1 = constructAndStoreCommitment( @@ -379,7 +379,7 @@ contract OracleTest is Test { for (uint256 i = 0; i < validBLSPubkeys.length; i++) { providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); } -// TODO(@ckartik): Adds a manual register cal + vm.stopPrank(); bytes32 index1 = constructAndStoreCommitment( @@ -498,7 +498,7 @@ contract OracleTest is Test { for (uint256 i = 0; i < validBLSPubkeys.length; i++) { providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); } -// TODO(@ckartik): Adds a manual register cal + vm.stopPrank(); bytes32[] memory commitments = new bytes32[](4); diff --git a/contracts/test/core/PreconfManagerTest.sol b/contracts/test/core/PreconfManagerTest.sol index ea189d182..6a48a9ada 100644 --- a/contracts/test/core/PreconfManagerTest.sol +++ b/contracts/test/core/PreconfManagerTest.sol @@ -218,7 +218,7 @@ vm.prank(address(this)); providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); } vm.stopPrank(); -// TODO: add manaul BLS key registration + // Step 2: Store the commitment @@ -980,7 +980,7 @@ vm.prank(address(this)); providerRegistry.addVerifiedBLSKey(validBLSPubkeys[i], dummyBLSSignature); } vm.stopPrank(); -// TODO: add manaul BLS key registration + // Request a withdrawal to create a pending withdrawal request diff --git a/contracts/test/core/ProviderRegistryTest.sol b/contracts/test/core/ProviderRegistryTest.sol index 97cbbdda9..1fa627b48 100644 --- a/contracts/test/core/ProviderRegistryTest.sol +++ b/contracts/test/core/ProviderRegistryTest.sol @@ -126,7 +126,7 @@ contract ProviderRegistryTest is Test { bytes[] memory invalidBLSPubkeys = new bytes[](1); invalidBLSPubkeys[0] = abi.encodePacked(uint256(134)); providerRegistry.registerAndStake{value: 1 wei}(); -// TODO: add manaul BLS key registration + } @@ -165,11 +165,11 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + vm.expectRevert(bytes("")); providerRegistry.registerAndStake{value: 1 wei}(); -// TODO: add manaul BLS key registration + } @@ -253,7 +253,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); providerRegistry.registerAndStake{value: 2 ether}(); -// TODO: add manaul BLS key registration + address bidder = vm.addr(4); @@ -273,7 +273,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); providerRegistry.registerAndStake{value: 2 ether}(); -// TODO: add manaul BLS key registration + address bidder = vm.addr(4); @@ -288,7 +288,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); providerRegistry.registerAndStake{value: 2 ether}(); -// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.expectRevert(bytes("")); @@ -301,7 +301,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); providerRegistry.registerAndStake{value: 2 ether}(); -// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.prank(address(this)); @@ -321,7 +321,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); providerRegistry.registerAndStake{value: 3 ether}(); -// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.prank(address(this)); @@ -341,7 +341,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3.1 ether); vm.prank(provider); providerRegistry.registerAndStake{value: 3.1 ether}(); -// TODO: add manaul BLS key registration + address bidder = vm.addr(4); vm.prank(address(this)); @@ -361,7 +361,7 @@ contract ProviderRegistryTest is Test { address bidder = vm.addr(4); providerRegistry.registerAndStake{value: 2 ether}(); -// TODO: add manaul BLS key registration + providerRegistry.setPreconfManager(address(this)); providerRegistry.slash(1e18 wei, provider, payable(bidder), 50 * providerRegistry.PRECISION()); @@ -375,7 +375,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2 ether}(); -// TODO: add manaul BLS key registration + vm.roll(350); // roll past protocol fee payout period @@ -404,7 +404,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + providerRegistry.setPreconfManager( address(preconfManager) @@ -433,7 +433,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + vm.expectRevert(bytes("")); address wrongNewProvider = vm.addr(12); @@ -446,7 +446,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + assertEq( providerRegistry.providerStakes(newProvider), @@ -465,7 +465,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + providerRegistry.unstake(); vm.warp(block.timestamp + 24 hours); // Move forward in time @@ -478,7 +478,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + vm.prank(newProvider); providerRegistry.unstake(); @@ -496,7 +496,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + providerRegistry.setPreconfManager( address(preconfManager) @@ -525,7 +525,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + vm.prank(newProvider); providerRegistry.unstake(); @@ -547,7 +547,7 @@ contract ProviderRegistryTest is Test { vm.deal(newProvider, 3 ether); vm.prank(newProvider); providerRegistry.registerAndStake{value: 2e18 wei}(); -// TODO: add manaul BLS key registration + vm.prank(newProvider); vm.expectRevert( From cf9a264ca8ffa047f9fe24cd9f37bd00b75d8317 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sat, 7 Dec 2024 14:01:38 -0500 Subject: [PATCH 04/44] chore: remove todo --- contracts/test/core/ProviderRegistryTest.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/test/core/ProviderRegistryTest.sol b/contracts/test/core/ProviderRegistryTest.sol index 1fa627b48..19ce5a07c 100644 --- a/contracts/test/core/ProviderRegistryTest.sol +++ b/contracts/test/core/ProviderRegistryTest.sol @@ -561,7 +561,7 @@ contract ProviderRegistryTest is Test { vm.prank(address(this)); providerRegistry.delegateRegisterAndStake{value: 2e18 wei}(newProvider); - // TODO(@ckartik): Add a manual register call for BLS keys + assertEq( providerRegistry.providerStakes(newProvider), 2e18 wei, From 1587dd8193664684728474cd13cd661d73df03ba Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sat, 7 Dec 2024 14:24:59 -0500 Subject: [PATCH 05/44] feat: adds overrideable BLS key addition --- contracts-abi/abi/ProviderRegistry.abi | 103 +++++-- .../ProviderRegistry/ProviderRegistry.go | 287 +++++++++++++++--- contracts/contracts/core/ProviderRegistry.sol | 6 + .../interfaces/IProviderRegistry.sol | 2 + 4 files changed, 345 insertions(+), 53 deletions(-) diff --git a/contracts-abi/abi/ProviderRegistry.abi b/contracts-abi/abi/ProviderRegistry.abi index edf97cf4b..bbc87bc40 100644 --- a/contracts-abi/abi/ProviderRegistry.abi +++ b/contracts-abi/abi/ProviderRegistry.abi @@ -58,6 +58,24 @@ "outputs": [], "stateMutability": "nonpayable" }, + { + "type": "function", + "name": "addVerifiedBLSKey", + "inputs": [ + { + "name": "blsPublicKey", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, { "type": "function", "name": "bidderSlashedAmount", @@ -104,11 +122,6 @@ "name": "provider", "type": "address", "internalType": "address" - }, - { - "name": "blsPublicKeys", - "type": "bytes[]", - "internalType": "bytes[]" } ], "outputs": [], @@ -305,6 +318,24 @@ ], "stateMutability": "view" }, + { + "type": "function", + "name": "overrideAddBLSKey", + "inputs": [ + { + "name": "provider", + "type": "address", + "internalType": "address" + }, + { + "name": "blsPublicKey", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, { "type": "function", "name": "owner", @@ -446,13 +477,7 @@ { "type": "function", "name": "registerAndStake", - "inputs": [ - { - "name": "blsPublicKeys", - "type": "bytes[]", - "internalType": "bytes[]" - } - ], + "inputs": [], "outputs": [], "stateMutability": "payable" }, @@ -621,6 +646,35 @@ "outputs": [], "stateMutability": "payable" }, + { + "type": "function", + "name": "verifySignature", + "inputs": [ + { + "name": "pubKey", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "message", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, { "type": "function", "name": "withdraw", @@ -667,6 +721,25 @@ ], "stateMutability": "view" }, + { + "type": "event", + "name": "BLSKeyAdded", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "blsPublicKey", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, { "type": "event", "name": "BidderWithdrawSlashedAmount", @@ -918,12 +991,6 @@ "type": "uint256", "indexed": false, "internalType": "uint256" - }, - { - "name": "blsPublicKeys", - "type": "bytes[]", - "indexed": false, - "internalType": "bytes[]" } ], "anonymous": false diff --git a/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go b/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go index 5c961014c..caa63664a 100644 --- a/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go +++ b/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go @@ -31,7 +31,7 @@ var ( // ProviderregistryMetaData contains all meta data concerning the Providerregistry contract. var ProviderregistryMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"ONE_HUNDRED_PERCENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PRECISION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bidderSlashedAmount\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blockBuilderBLSKeyToAddress\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delegateRegisterAndStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blsPublicKeys\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"delegateStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"eoaToBlsPubkeys\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAccumulatedPenaltyFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBLSKeys\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getEoaFromBLSKey\",\"inputs\":[{\"name\":\"blsKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getProviderStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isProviderValid\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"manuallyWithdrawPenaltyFee\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"minStake\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"penaltyFeeTracker\",\"inputs\":[],\"outputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"accumulatedAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"lastPayoutBlock\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preconfManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerRegistered\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerStakes\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerAndStake\",\"inputs\":[{\"name\":\"blsPublicKeys\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFeePayoutPeriodBlocks\",\"inputs\":[{\"name\":\"_feePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMinStake\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewPenaltyFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfManager\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelay\",\"inputs\":[{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slash\",\"inputs\":[{\"name\":\"amt\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"residualBidPercentAfterDecay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unstake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSlashedAmount\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawalDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalRequests\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"BidderWithdrawSlashedAmount\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePayoutPeriodBlocksUpdated\",\"inputs\":[{\"name\":\"newFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePercentUpdated\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeeTransfer\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsDeposited\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsSlashed\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InsufficientFundsToSlash\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"providerStake\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"residualAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"penaltyFee\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinStakeUpdated\",\"inputs\":[{\"name\":\"newMinStake\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PenaltyFeeRecipientUpdated\",\"inputs\":[{\"name\":\"newPenaltyFeeRecipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PreconfManagerUpdated\",\"inputs\":[{\"name\":\"newPreconfManager\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProviderRegistered\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"stakedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"blsPublicKeys\",\"type\":\"bytes[]\",\"indexed\":false,\"internalType\":\"bytes[]\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransferToBidderFailed\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unstake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdraw\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayUpdated\",\"inputs\":[{\"name\":\"newWithdrawalDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AtLeastOneBLSKeyRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BidderAmountIsZero\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"BidderWithdrawalTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"DelayNotPassed\",\"inputs\":[{\"name\":\"withdrawalRequestTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"currentBlockTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FeeRecipientIsZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientStake\",\"inputs\":[{\"name\":\"stake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidBLSPublicKeyLength\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedLength\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidFallback\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReceive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoStakeToWithdraw\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NoUnstakeRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotPreconfContract\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"preconfManager\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PayoutPeriodMustBePositive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PendingWithdrawalRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PreconfManagerNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ProviderAlreadyRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ProviderCommitmentsPending\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"numPending\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProviderNotRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StakeTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TransferToRecipientFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"UnstakeRequestExists\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"ONE_HUNDRED_PERCENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PRECISION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addVerifiedBLSKey\",\"inputs\":[{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bidderSlashedAmount\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blockBuilderBLSKeyToAddress\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delegateRegisterAndStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"delegateStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"eoaToBlsPubkeys\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAccumulatedPenaltyFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBLSKeys\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getEoaFromBLSKey\",\"inputs\":[{\"name\":\"blsKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getProviderStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isProviderValid\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"manuallyWithdrawPenaltyFee\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"minStake\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"overrideAddBLSKey\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"penaltyFeeTracker\",\"inputs\":[],\"outputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"accumulatedAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"lastPayoutBlock\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preconfManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerRegistered\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerStakes\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerAndStake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFeePayoutPeriodBlocks\",\"inputs\":[{\"name\":\"_feePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMinStake\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewPenaltyFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfManager\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelay\",\"inputs\":[{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slash\",\"inputs\":[{\"name\":\"amt\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"residualBidPercentAfterDecay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unstake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifySignature\",\"inputs\":[{\"name\":\"pubKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"message\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSlashedAmount\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawalDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalRequests\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"BLSKeyAdded\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BidderWithdrawSlashedAmount\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePayoutPeriodBlocksUpdated\",\"inputs\":[{\"name\":\"newFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePercentUpdated\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeeTransfer\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsDeposited\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsSlashed\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InsufficientFundsToSlash\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"providerStake\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"residualAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"penaltyFee\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinStakeUpdated\",\"inputs\":[{\"name\":\"newMinStake\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PenaltyFeeRecipientUpdated\",\"inputs\":[{\"name\":\"newPenaltyFeeRecipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PreconfManagerUpdated\",\"inputs\":[{\"name\":\"newPreconfManager\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProviderRegistered\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"stakedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransferToBidderFailed\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unstake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdraw\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayUpdated\",\"inputs\":[{\"name\":\"newWithdrawalDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AtLeastOneBLSKeyRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BidderAmountIsZero\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"BidderWithdrawalTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"DelayNotPassed\",\"inputs\":[{\"name\":\"withdrawalRequestTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"currentBlockTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FeeRecipientIsZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientStake\",\"inputs\":[{\"name\":\"stake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidBLSPublicKeyLength\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedLength\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidFallback\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReceive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoStakeToWithdraw\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NoUnstakeRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotPreconfContract\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"preconfManager\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PayoutPeriodMustBePositive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PendingWithdrawalRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PreconfManagerNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ProviderAlreadyRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ProviderCommitmentsPending\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"numPending\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProviderNotRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StakeTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TransferToRecipientFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"UnstakeRequestExists\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]}]", } // ProviderregistryABI is the input ABI used to generate the binding from. @@ -853,6 +853,37 @@ func (_Providerregistry *ProviderregistryCallerSession) ProxiableUUID() ([32]byt return _Providerregistry.Contract.ProxiableUUID(&_Providerregistry.CallOpts) } +// VerifySignature is a free data retrieval call binding the contract method 0x2222e36f. +// +// Solidity: function verifySignature(bytes pubKey, bytes32 message, bytes signature) view returns(bool) +func (_Providerregistry *ProviderregistryCaller) VerifySignature(opts *bind.CallOpts, pubKey []byte, message [32]byte, signature []byte) (bool, error) { + var out []interface{} + err := _Providerregistry.contract.Call(opts, &out, "verifySignature", pubKey, message, signature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// VerifySignature is a free data retrieval call binding the contract method 0x2222e36f. +// +// Solidity: function verifySignature(bytes pubKey, bytes32 message, bytes signature) view returns(bool) +func (_Providerregistry *ProviderregistrySession) VerifySignature(pubKey []byte, message [32]byte, signature []byte) (bool, error) { + return _Providerregistry.Contract.VerifySignature(&_Providerregistry.CallOpts, pubKey, message, signature) +} + +// VerifySignature is a free data retrieval call binding the contract method 0x2222e36f. +// +// Solidity: function verifySignature(bytes pubKey, bytes32 message, bytes signature) view returns(bool) +func (_Providerregistry *ProviderregistryCallerSession) VerifySignature(pubKey []byte, message [32]byte, signature []byte) (bool, error) { + return _Providerregistry.Contract.VerifySignature(&_Providerregistry.CallOpts, pubKey, message, signature) +} + // WithdrawalDelay is a free data retrieval call binding the contract method 0xa7ab6961. // // Solidity: function withdrawalDelay() view returns(uint256) @@ -936,25 +967,46 @@ func (_Providerregistry *ProviderregistryTransactorSession) AcceptOwnership() (* return _Providerregistry.Contract.AcceptOwnership(&_Providerregistry.TransactOpts) } -// DelegateRegisterAndStake is a paid mutator transaction binding the contract method 0xd9b735e7. +// AddVerifiedBLSKey is a paid mutator transaction binding the contract method 0x7fd358e4. // -// Solidity: function delegateRegisterAndStake(address provider, bytes[] blsPublicKeys) payable returns() -func (_Providerregistry *ProviderregistryTransactor) DelegateRegisterAndStake(opts *bind.TransactOpts, provider common.Address, blsPublicKeys [][]byte) (*types.Transaction, error) { - return _Providerregistry.contract.Transact(opts, "delegateRegisterAndStake", provider, blsPublicKeys) +// Solidity: function addVerifiedBLSKey(bytes blsPublicKey, bytes signature) returns() +func (_Providerregistry *ProviderregistryTransactor) AddVerifiedBLSKey(opts *bind.TransactOpts, blsPublicKey []byte, signature []byte) (*types.Transaction, error) { + return _Providerregistry.contract.Transact(opts, "addVerifiedBLSKey", blsPublicKey, signature) } -// DelegateRegisterAndStake is a paid mutator transaction binding the contract method 0xd9b735e7. +// AddVerifiedBLSKey is a paid mutator transaction binding the contract method 0x7fd358e4. // -// Solidity: function delegateRegisterAndStake(address provider, bytes[] blsPublicKeys) payable returns() -func (_Providerregistry *ProviderregistrySession) DelegateRegisterAndStake(provider common.Address, blsPublicKeys [][]byte) (*types.Transaction, error) { - return _Providerregistry.Contract.DelegateRegisterAndStake(&_Providerregistry.TransactOpts, provider, blsPublicKeys) +// Solidity: function addVerifiedBLSKey(bytes blsPublicKey, bytes signature) returns() +func (_Providerregistry *ProviderregistrySession) AddVerifiedBLSKey(blsPublicKey []byte, signature []byte) (*types.Transaction, error) { + return _Providerregistry.Contract.AddVerifiedBLSKey(&_Providerregistry.TransactOpts, blsPublicKey, signature) } -// DelegateRegisterAndStake is a paid mutator transaction binding the contract method 0xd9b735e7. +// AddVerifiedBLSKey is a paid mutator transaction binding the contract method 0x7fd358e4. // -// Solidity: function delegateRegisterAndStake(address provider, bytes[] blsPublicKeys) payable returns() -func (_Providerregistry *ProviderregistryTransactorSession) DelegateRegisterAndStake(provider common.Address, blsPublicKeys [][]byte) (*types.Transaction, error) { - return _Providerregistry.Contract.DelegateRegisterAndStake(&_Providerregistry.TransactOpts, provider, blsPublicKeys) +// Solidity: function addVerifiedBLSKey(bytes blsPublicKey, bytes signature) returns() +func (_Providerregistry *ProviderregistryTransactorSession) AddVerifiedBLSKey(blsPublicKey []byte, signature []byte) (*types.Transaction, error) { + return _Providerregistry.Contract.AddVerifiedBLSKey(&_Providerregistry.TransactOpts, blsPublicKey, signature) +} + +// DelegateRegisterAndStake is a paid mutator transaction binding the contract method 0x3d75c0ba. +// +// Solidity: function delegateRegisterAndStake(address provider) payable returns() +func (_Providerregistry *ProviderregistryTransactor) DelegateRegisterAndStake(opts *bind.TransactOpts, provider common.Address) (*types.Transaction, error) { + return _Providerregistry.contract.Transact(opts, "delegateRegisterAndStake", provider) +} + +// DelegateRegisterAndStake is a paid mutator transaction binding the contract method 0x3d75c0ba. +// +// Solidity: function delegateRegisterAndStake(address provider) payable returns() +func (_Providerregistry *ProviderregistrySession) DelegateRegisterAndStake(provider common.Address) (*types.Transaction, error) { + return _Providerregistry.Contract.DelegateRegisterAndStake(&_Providerregistry.TransactOpts, provider) +} + +// DelegateRegisterAndStake is a paid mutator transaction binding the contract method 0x3d75c0ba. +// +// Solidity: function delegateRegisterAndStake(address provider) payable returns() +func (_Providerregistry *ProviderregistryTransactorSession) DelegateRegisterAndStake(provider common.Address) (*types.Transaction, error) { + return _Providerregistry.Contract.DelegateRegisterAndStake(&_Providerregistry.TransactOpts, provider) } // DelegateStake is a paid mutator transaction binding the contract method 0xf094cc39. @@ -1020,6 +1072,27 @@ func (_Providerregistry *ProviderregistryTransactorSession) ManuallyWithdrawPena return _Providerregistry.Contract.ManuallyWithdrawPenaltyFee(&_Providerregistry.TransactOpts) } +// OverrideAddBLSKey is a paid mutator transaction binding the contract method 0xed5219de. +// +// Solidity: function overrideAddBLSKey(address provider, bytes blsPublicKey) returns() +func (_Providerregistry *ProviderregistryTransactor) OverrideAddBLSKey(opts *bind.TransactOpts, provider common.Address, blsPublicKey []byte) (*types.Transaction, error) { + return _Providerregistry.contract.Transact(opts, "overrideAddBLSKey", provider, blsPublicKey) +} + +// OverrideAddBLSKey is a paid mutator transaction binding the contract method 0xed5219de. +// +// Solidity: function overrideAddBLSKey(address provider, bytes blsPublicKey) returns() +func (_Providerregistry *ProviderregistrySession) OverrideAddBLSKey(provider common.Address, blsPublicKey []byte) (*types.Transaction, error) { + return _Providerregistry.Contract.OverrideAddBLSKey(&_Providerregistry.TransactOpts, provider, blsPublicKey) +} + +// OverrideAddBLSKey is a paid mutator transaction binding the contract method 0xed5219de. +// +// Solidity: function overrideAddBLSKey(address provider, bytes blsPublicKey) returns() +func (_Providerregistry *ProviderregistryTransactorSession) OverrideAddBLSKey(provider common.Address, blsPublicKey []byte) (*types.Transaction, error) { + return _Providerregistry.Contract.OverrideAddBLSKey(&_Providerregistry.TransactOpts, provider, blsPublicKey) +} + // Pause is a paid mutator transaction binding the contract method 0x8456cb59. // // Solidity: function pause() returns() @@ -1041,25 +1114,25 @@ func (_Providerregistry *ProviderregistryTransactorSession) Pause() (*types.Tran return _Providerregistry.Contract.Pause(&_Providerregistry.TransactOpts) } -// RegisterAndStake is a paid mutator transaction binding the contract method 0x140f2e60. +// RegisterAndStake is a paid mutator transaction binding the contract method 0x84d180ee. // -// Solidity: function registerAndStake(bytes[] blsPublicKeys) payable returns() -func (_Providerregistry *ProviderregistryTransactor) RegisterAndStake(opts *bind.TransactOpts, blsPublicKeys [][]byte) (*types.Transaction, error) { - return _Providerregistry.contract.Transact(opts, "registerAndStake", blsPublicKeys) +// Solidity: function registerAndStake() payable returns() +func (_Providerregistry *ProviderregistryTransactor) RegisterAndStake(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Providerregistry.contract.Transact(opts, "registerAndStake") } -// RegisterAndStake is a paid mutator transaction binding the contract method 0x140f2e60. +// RegisterAndStake is a paid mutator transaction binding the contract method 0x84d180ee. // -// Solidity: function registerAndStake(bytes[] blsPublicKeys) payable returns() -func (_Providerregistry *ProviderregistrySession) RegisterAndStake(blsPublicKeys [][]byte) (*types.Transaction, error) { - return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts, blsPublicKeys) +// Solidity: function registerAndStake() payable returns() +func (_Providerregistry *ProviderregistrySession) RegisterAndStake() (*types.Transaction, error) { + return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts) } -// RegisterAndStake is a paid mutator transaction binding the contract method 0x140f2e60. +// RegisterAndStake is a paid mutator transaction binding the contract method 0x84d180ee. // -// Solidity: function registerAndStake(bytes[] blsPublicKeys) payable returns() -func (_Providerregistry *ProviderregistryTransactorSession) RegisterAndStake(blsPublicKeys [][]byte) (*types.Transaction, error) { - return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts, blsPublicKeys) +// Solidity: function registerAndStake() payable returns() +func (_Providerregistry *ProviderregistryTransactorSession) RegisterAndStake() (*types.Transaction, error) { + return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. @@ -1419,6 +1492,151 @@ func (_Providerregistry *ProviderregistryTransactorSession) Receive() (*types.Tr return _Providerregistry.Contract.Receive(&_Providerregistry.TransactOpts) } +// ProviderregistryBLSKeyAddedIterator is returned from FilterBLSKeyAdded and is used to iterate over the raw logs and unpacked data for BLSKeyAdded events raised by the Providerregistry contract. +type ProviderregistryBLSKeyAddedIterator struct { + Event *ProviderregistryBLSKeyAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ProviderregistryBLSKeyAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ProviderregistryBLSKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ProviderregistryBLSKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ProviderregistryBLSKeyAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProviderregistryBLSKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProviderregistryBLSKeyAdded represents a BLSKeyAdded event raised by the Providerregistry contract. +type ProviderregistryBLSKeyAdded struct { + Provider common.Address + BlsPublicKey []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBLSKeyAdded is a free log retrieval operation binding the contract event 0xc81315c03024fb67ddfe902ce0153b3d56572c0569de9564fcb90cc174a960bf. +// +// Solidity: event BLSKeyAdded(address indexed provider, bytes blsPublicKey) +func (_Providerregistry *ProviderregistryFilterer) FilterBLSKeyAdded(opts *bind.FilterOpts, provider []common.Address) (*ProviderregistryBLSKeyAddedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + + logs, sub, err := _Providerregistry.contract.FilterLogs(opts, "BLSKeyAdded", providerRule) + if err != nil { + return nil, err + } + return &ProviderregistryBLSKeyAddedIterator{contract: _Providerregistry.contract, event: "BLSKeyAdded", logs: logs, sub: sub}, nil +} + +// WatchBLSKeyAdded is a free log subscription operation binding the contract event 0xc81315c03024fb67ddfe902ce0153b3d56572c0569de9564fcb90cc174a960bf. +// +// Solidity: event BLSKeyAdded(address indexed provider, bytes blsPublicKey) +func (_Providerregistry *ProviderregistryFilterer) WatchBLSKeyAdded(opts *bind.WatchOpts, sink chan<- *ProviderregistryBLSKeyAdded, provider []common.Address) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + + logs, sub, err := _Providerregistry.contract.WatchLogs(opts, "BLSKeyAdded", providerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ProviderregistryBLSKeyAdded) + if err := _Providerregistry.contract.UnpackLog(event, "BLSKeyAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseBLSKeyAdded is a log parse operation binding the contract event 0xc81315c03024fb67ddfe902ce0153b3d56572c0569de9564fcb90cc174a960bf. +// +// Solidity: event BLSKeyAdded(address indexed provider, bytes blsPublicKey) +func (_Providerregistry *ProviderregistryFilterer) ParseBLSKeyAdded(log types.Log) (*ProviderregistryBLSKeyAdded, error) { + event := new(ProviderregistryBLSKeyAdded) + if err := _Providerregistry.contract.UnpackLog(event, "BLSKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // ProviderregistryBidderWithdrawSlashedAmountIterator is returned from FilterBidderWithdrawSlashedAmount and is used to iterate over the raw logs and unpacked data for BidderWithdrawSlashedAmount events raised by the Providerregistry contract. type ProviderregistryBidderWithdrawSlashedAmountIterator struct { Event *ProviderregistryBidderWithdrawSlashedAmount // Event containing the contract specifics and raw log @@ -3499,15 +3717,14 @@ func (it *ProviderregistryProviderRegisteredIterator) Close() error { // ProviderregistryProviderRegistered represents a ProviderRegistered event raised by the Providerregistry contract. type ProviderregistryProviderRegistered struct { - Provider common.Address - StakedAmount *big.Int - BlsPublicKeys [][]byte - Raw types.Log // Blockchain specific contextual infos + Provider common.Address + StakedAmount *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterProviderRegistered is a free log retrieval operation binding the contract event 0x43b9a402bb7e7ede3b3d372b9a0be4a09659bc821f4662eb999faa8756553042. +// FilterProviderRegistered is a free log retrieval operation binding the contract event 0x90c9734131c1e4fb36cde2d71e6feb93fb258f71be8a85411c173d25e1516e80. // -// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes[] blsPublicKeys) +// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount) func (_Providerregistry *ProviderregistryFilterer) FilterProviderRegistered(opts *bind.FilterOpts, provider []common.Address) (*ProviderregistryProviderRegisteredIterator, error) { var providerRule []interface{} @@ -3522,9 +3739,9 @@ func (_Providerregistry *ProviderregistryFilterer) FilterProviderRegistered(opts return &ProviderregistryProviderRegisteredIterator{contract: _Providerregistry.contract, event: "ProviderRegistered", logs: logs, sub: sub}, nil } -// WatchProviderRegistered is a free log subscription operation binding the contract event 0x43b9a402bb7e7ede3b3d372b9a0be4a09659bc821f4662eb999faa8756553042. +// WatchProviderRegistered is a free log subscription operation binding the contract event 0x90c9734131c1e4fb36cde2d71e6feb93fb258f71be8a85411c173d25e1516e80. // -// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes[] blsPublicKeys) +// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount) func (_Providerregistry *ProviderregistryFilterer) WatchProviderRegistered(opts *bind.WatchOpts, sink chan<- *ProviderregistryProviderRegistered, provider []common.Address) (event.Subscription, error) { var providerRule []interface{} @@ -3564,9 +3781,9 @@ func (_Providerregistry *ProviderregistryFilterer) WatchProviderRegistered(opts }), nil } -// ParseProviderRegistered is a log parse operation binding the contract event 0x43b9a402bb7e7ede3b3d372b9a0be4a09659bc821f4662eb999faa8756553042. +// ParseProviderRegistered is a log parse operation binding the contract event 0x90c9734131c1e4fb36cde2d71e6feb93fb258f71be8a85411c173d25e1516e80. // -// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes[] blsPublicKeys) +// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount) func (_Providerregistry *ProviderregistryFilterer) ParseProviderRegistered(log types.Log) (*ProviderregistryProviderRegistered, error) { event := new(ProviderregistryProviderRegistered) if err := _Providerregistry.contract.UnpackLog(event, "ProviderRegistered", log); err != nil { diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 6b66ddb5a..397077bf4 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -183,6 +183,12 @@ contract ProviderRegistry is emit FeePayoutPeriodBlocksUpdated(_feePayoutPeriodBlocks); } + function overrideAddBLSKey(address provider, bytes calldata blsPublicKey) external onlyOwner { + require(providerRegistered[provider], ProviderNotRegistered(provider)); + eoaToBlsPubkeys[provider].push(blsPublicKey); + blockBuilderBLSKeyToAddress[blsPublicKey] = provider; + } + /// @dev Requests unstake of the staked amount. function unstake() external whenNotPaused { require(providerStakes[msg.sender] != 0, NoStakeToWithdraw(msg.sender)); diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index e7a85272a..acc38f447 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -84,4 +84,6 @@ interface IProviderRegistry { function getEoaFromBLSKey(bytes calldata blsKey) external view returns (address); function addVerifiedBLSKey(bytes calldata blsPublicKey, bytes calldata signature) external; + + function overrideAddBLSKey(address provider, bytes calldata blsPublicKey) external; } From 34b6a39bd4e0dd510d34d95f3c84e062a9620154 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 10:26:28 -0500 Subject: [PATCH 06/44] feat: adds use of bls sigs in p2p layer --- p2p/gen/go/providerapi/v1/providerapi.pb.go | 652 +++++++++--------- .../providerapi/v1/providerapi.swagger.yaml | 9 + p2p/pkg/rpc/provider/service.go | 23 +- p2p/pkg/rpc/provider/service_test.go | 23 +- p2p/rpc/providerapi/v1/providerapi.proto | 8 + 5 files changed, 387 insertions(+), 328 deletions(-) diff --git a/p2p/gen/go/providerapi/v1/providerapi.pb.go b/p2p/gen/go/providerapi/v1/providerapi.pb.go index 297f6ed45..af6d4e524 100644 --- a/p2p/gen/go/providerapi/v1/providerapi.pb.go +++ b/p2p/gen/go/providerapi/v1/providerapi.pb.go @@ -79,6 +79,7 @@ type StakeRequest struct { Amount string `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` BlsPublicKeys []string `protobuf:"bytes,2,rep,name=bls_public_keys,json=blsPublicKeys,proto3" json:"bls_public_keys,omitempty"` + BlsSignatures []string `protobuf:"bytes,3,rep,name=bls_signatures,json=blsSignatures,proto3" json:"bls_signatures,omitempty"` } func (x *StakeRequest) Reset() { @@ -127,6 +128,13 @@ func (x *StakeRequest) GetBlsPublicKeys() []string { return nil } +func (x *StakeRequest) GetBlsSignatures() []string { + if x != nil { + return x.BlsSignatures + } + return nil +} + type StakeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -445,7 +453,7 @@ var file_providerapi_v1_providerapi_proto_rawDesc = []byte{ 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcc, 0x05, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf4, 0x07, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xb2, 0x01, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x01, 0x92, 0x41, 0x3b, 0x32, 0x30, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, @@ -475,321 +483,339 @@ var file_providerapi_v1_providerapi_proto_rawDesc = []byte{ 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x28, 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x39, 0x36, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x0d, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0xf3, 0x01, 0x92, 0x41, 0xef, 0x01, 0x0a, 0x53, 0x2a, - 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0x28, - 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x69, - 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0xd2, 0x01, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0xd2, 0x01, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, - 0x65, 0x79, 0x32, 0x97, 0x01, 0x7b, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, - 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x38, 0x30, 0x30, 0x30, 0x30, 0x63, - 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, 0x38, 0x30, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, - 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, - 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, - 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, - 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, 0x34, 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, - 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, 0x62, 0x22, 0x7d, 0x22, 0x9f, 0x03, 0x0a, - 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0d, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0xcd, - 0x02, 0x92, 0x41, 0xc9, 0x02, 0x0a, 0x4a, 0x2a, 0x0e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x38, 0x47, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, - 0x6b, 0x65, 0x64, 0x20, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x32, 0xfa, 0x01, 0x7b, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, - 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x39, 0x30, 0x30, 0x30, 0x30, - 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, 0x38, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, - 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, - 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, - 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, - 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, - 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, 0x62, 0x22, 0x2c, 0x20, 0x22, 0x38, 0x30, 0x30, - 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, 0x38, 0x30, 0x65, 0x30, 0x30, - 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, - 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, - 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, - 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, - 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, 0x62, 0x22, 0x5d, 0x7d, 0x22, 0xa5, - 0x01, 0x0a, 0x12, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x77, 0x92, - 0x41, 0x74, 0x0a, 0x4f, 0x2a, 0x13, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, - 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x38, 0x57, 0x69, 0x74, 0x68, 0x64, - 0x72, 0x61, 0x77, 0x61, 0x6c, 0x20, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x79, 0x2e, 0x32, 0x21, 0x7b, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, - 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x22, 0x0e, 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xec, 0x11, 0x0a, 0x03, 0x42, 0x69, 0x64, 0x12, 0x8f, - 0x02, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x42, 0xf1, 0x01, 0x92, 0x41, 0x78, 0x32, 0x64, 0x48, 0x65, 0x78, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, - 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x8a, 0x01, - 0x0f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, - 0xba, 0x48, 0x73, 0xba, 0x01, 0x70, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, - 0x73, 0x12, 0x36, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, - 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x61, 0x72, 0x72, - 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, - 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, - 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, - 0x34, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, - 0x12, 0xfc, 0x01, 0x0a, 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xdc, 0x01, 0x92, 0x41, 0x76, 0x32, 0x6b, 0x41, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x45, 0x54, 0x48, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x77, 0x69, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x8a, 0x01, 0x06, 0x5b, 0x30, 0x2d, 0x39, 0x5d, - 0x2b, 0xba, 0x48, 0x60, 0xba, 0x01, 0x5d, 0x0a, 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x23, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, - 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, - 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x2a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, - 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, - 0x20, 0x3e, 0x20, 0x30, 0x52, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x74, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x51, 0x92, 0x41, 0x47, 0x32, 0x45, 0x4d, 0x61, 0x78, 0x20, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, - 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, - 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, - 0x2e, 0xba, 0x48, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x5c, 0x0a, 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x64, 0x69, 0x67, - 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x3d, 0x92, 0x41, 0x31, 0x32, 0x2f, - 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, - 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, - 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x2e, 0xba, - 0x48, 0x06, 0x7a, 0x04, 0x10, 0x01, 0x18, 0x40, 0x52, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, - 0x65, 0x73, 0x74, 0x12, 0xc2, 0x01, 0x0a, 0x15, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x03, 0x42, 0x8d, 0x01, 0x92, 0x41, 0x2d, 0x32, 0x2b, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x20, 0x64, 0x65, 0x63, - 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, 0x48, 0x5a, 0xba, 0x01, 0x57, 0x0a, 0x15, 0x64, 0x65, - 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, - 0x65, 0x72, 0x2e, 0x1a, 0x0e, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, - 0x3e, 0x20, 0x30, 0x52, 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0xb8, 0x01, 0x0a, 0x13, 0x64, 0x65, 0x63, - 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x42, 0x87, 0x01, 0x92, 0x41, 0x2b, 0x32, 0x29, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x65, - 0x63, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x13, 0x64, - 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x2c, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0xa5, 0x02, 0x0a, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, + 0xfd, 0x01, 0x92, 0x41, 0x50, 0x32, 0x34, 0x42, 0x4c, 0x53, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x4c, 0x53, 0x20, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x8a, 0x01, 0x17, 0x5e, 0x28, + 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, + 0x31, 0x39, 0x32, 0x7d, 0x24, 0xba, 0x48, 0xa6, 0x01, 0xba, 0x01, 0xa2, 0x01, 0x0a, 0x0e, 0x62, + 0x6c, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x4b, 0x62, + 0x6c, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x39, 0x36, + 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x68, 0x65, 0x78, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, + 0x30, 0x78, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x2e, 0x1a, 0x43, 0x73, 0x69, 0x7a, 0x65, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x28, 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, + 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x31, 0x39, 0x32, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, + 0x0d, 0x62, 0x6c, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x3a, 0xf3, + 0x01, 0x92, 0x41, 0xef, 0x01, 0x0a, 0x53, 0x2a, 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0x28, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, + 0xd2, 0x01, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0xd2, 0x01, 0x0e, 0x62, 0x6c, 0x73, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x32, 0x97, 0x01, 0x7b, 0x22, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, + 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x3a, + 0x20, 0x22, 0x38, 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, + 0x38, 0x30, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, + 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, + 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, + 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, + 0x34, 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, + 0x32, 0x62, 0x22, 0x7d, 0x22, 0x9f, 0x03, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, + 0x0a, 0x0f, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0xcd, 0x02, 0x92, 0x41, 0xc9, 0x02, 0x0a, 0x4a, 0x2a, + 0x0e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, + 0x38, 0x47, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x64, 0x20, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x32, 0xfa, 0x01, 0x7b, 0x22, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, + 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, + 0x20, 0x5b, 0x22, 0x39, 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, + 0x61, 0x38, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, + 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, + 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, + 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, + 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, + 0x62, 0x22, 0x2c, 0x20, 0x22, 0x38, 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, + 0x36, 0x36, 0x61, 0x38, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, + 0x66, 0x31, 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, + 0x39, 0x65, 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, + 0x38, 0x32, 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, + 0x39, 0x64, 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, + 0x38, 0x32, 0x62, 0x22, 0x5d, 0x7d, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x57, 0x69, 0x74, 0x68, 0x64, + 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x77, 0x92, 0x41, 0x74, 0x0a, 0x4f, 0x2a, 0x13, 0x57, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x32, 0x38, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x20, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x32, 0x21, 0x7b, 0x22, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x22, 0x0e, + 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xec, + 0x11, 0x0a, 0x03, 0x42, 0x69, 0x64, 0x12, 0x8f, 0x02, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0xf1, 0x01, 0x92, 0x41, 0x78, + 0x32, 0x64, 0x48, 0x65, 0x78, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, + 0x68, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x8a, 0x01, 0x0f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, + 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, 0xba, 0x48, 0x73, 0xba, 0x01, 0x70, 0x0a, 0x09, + 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x36, 0x74, 0x78, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x2e, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, + 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, + 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x08, + 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0xfc, 0x01, 0x0a, 0x0a, 0x62, 0x69, 0x64, + 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xdc, 0x01, + 0x92, 0x41, 0x76, 0x32, 0x6b, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x45, + 0x54, 0x48, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, + 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, + 0x20, 0x70, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x8a, 0x01, 0x06, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0xba, 0x48, 0x60, 0xba, 0x01, 0x5d, 0x0a, + 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x62, 0x69, 0x64, + 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, - 0x1a, 0x0e, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, - 0x52, 0x11, 0x64, 0x65, 0x63, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x8a, 0x02, 0x0a, 0x13, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x42, 0xd9, 0x01, 0x92, 0x41, 0x49, 0x32, 0x47, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, - 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x78, 0x20, 0x68, 0x61, - 0x73, 0x68, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, - 0x6f, 0x72, 0x20, 0x62, 0x65, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x2e, - 0xba, 0x48, 0x89, 0x01, 0xba, 0x01, 0x85, 0x01, 0x0a, 0x13, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x41, 0x72, - 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, - 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, - 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, - 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x11, 0x72, - 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, - 0x12, 0x9d, 0x02, 0x0a, 0x10, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x42, 0xf1, 0x01, 0x92, 0x41, - 0x6e, 0x32, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, - 0x79, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x4c, 0x50, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, - 0x20, 0x72, 0x61, 0x77, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, - 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, - 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0xba, - 0x48, 0x7d, 0xba, 0x01, 0x7a, 0x0a, 0x10, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, - 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x1a, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, - 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, - 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x29, 0x52, - 0x0f, 0x72, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x3a, 0xd2, 0x04, 0x92, 0x41, 0xce, 0x04, 0x0a, 0x70, 0x2a, 0x0b, 0x42, 0x69, 0x64, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x30, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, - 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, - 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0xd2, 0x01, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, - 0x68, 0x65, 0x73, 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0xd2, - 0x01, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0xd2, 0x01, 0x09, - 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x32, 0xd9, 0x03, 0x7b, 0x22, 0x74, 0x78, - 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x66, 0x65, 0x34, 0x63, 0x62, - 0x34, 0x37, 0x64, 0x62, 0x33, 0x36, 0x33, 0x30, 0x35, 0x35, 0x31, 0x62, 0x65, 0x65, 0x64, 0x66, - 0x62, 0x64, 0x30, 0x32, 0x61, 0x37, 0x31, 0x65, 0x63, 0x63, 0x36, 0x39, 0x66, 0x64, 0x35, 0x39, - 0x37, 0x35, 0x38, 0x65, 0x32, 0x62, 0x61, 0x36, 0x39, 0x39, 0x36, 0x30, 0x36, 0x65, 0x32, 0x64, - 0x35, 0x63, 0x37, 0x34, 0x32, 0x38, 0x34, 0x66, 0x66, 0x61, 0x37, 0x22, 0x2c, 0x20, 0x22, 0x37, - 0x31, 0x63, 0x31, 0x33, 0x34, 0x38, 0x66, 0x32, 0x64, 0x37, 0x66, 0x66, 0x37, 0x65, 0x38, 0x31, - 0x34, 0x66, 0x39, 0x63, 0x33, 0x36, 0x31, 0x37, 0x39, 0x38, 0x33, 0x37, 0x30, 0x33, 0x34, 0x33, - 0x35, 0x65, 0x61, 0x37, 0x34, 0x34, 0x36, 0x64, 0x65, 0x34, 0x32, 0x30, 0x61, 0x65, 0x61, 0x63, - 0x34, 0x38, 0x38, 0x62, 0x66, 0x31, 0x64, 0x65, 0x33, 0x35, 0x37, 0x33, 0x37, 0x65, 0x38, 0x22, - 0x5d, 0x2c, 0x20, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x2c, 0x20, 0x22, 0x62, 0x69, 0x64, 0x44, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x39, 0x64, 0x4a, 0x69, 0x6e, 0x77, 0x4c, - 0x2b, 0x46, 0x5a, 0x36, 0x42, 0x31, 0x78, 0x73, 0x49, 0x51, 0x51, 0x6f, 0x38, 0x74, 0x38, 0x42, - 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x62, 0x4a, 0x77, 0x59, 0x38, 0x36, 0x6c, 0x2f, 0x59, 0x75, 0x37, - 0x79, 0x41, 0x48, 0x31, 0x35, 0x39, 0x51, 0x72, 0x50, 0x48, 0x55, 0x30, 0x71, 0x6a, 0x32, 0x50, - 0x2b, 0x59, 0x46, 0x6a, 0x2b, 0x6c, 0x6c, 0x62, 0x75, 0x49, 0x31, 0x5a, 0x79, 0x67, 0x64, 0x78, - 0x47, 0x73, 0x58, 0x38, 0x2b, 0x50, 0x33, 0x62, 0x79, 0x4d, 0x45, 0x41, 0x35, 0x69, 0x67, 0x3d, - 0x3d, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x31, 0x37, 0x32, 0x35, 0x33, 0x36, - 0x35, 0x33, 0x30, 0x31, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, 0x61, 0x79, 0x45, - 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x31, 0x37, 0x32, - 0x35, 0x33, 0x36, 0x35, 0x33, 0x30, 0x32, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x22, 0x72, 0x65, 0x76, - 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x3a, - 0x5b, 0x22, 0x66, 0x65, 0x34, 0x63, 0x62, 0x34, 0x37, 0x64, 0x62, 0x33, 0x36, 0x33, 0x30, 0x35, - 0x35, 0x31, 0x62, 0x65, 0x65, 0x64, 0x66, 0x62, 0x64, 0x30, 0x32, 0x61, 0x37, 0x31, 0x65, 0x63, - 0x63, 0x36, 0x39, 0x66, 0x64, 0x35, 0x39, 0x37, 0x35, 0x38, 0x65, 0x32, 0x62, 0x61, 0x36, 0x39, - 0x39, 0x36, 0x30, 0x36, 0x65, 0x32, 0x64, 0x35, 0x63, 0x37, 0x34, 0x32, 0x38, 0x34, 0x66, 0x66, - 0x61, 0x37, 0x22, 0x5d, 0x7d, 0x22, 0x81, 0x06, 0x0a, 0x0b, 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x64, 0x69, 0x67, - 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x34, 0x92, 0x41, 0x31, 0x32, 0x2f, - 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, - 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, - 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x2e, 0x52, - 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, + 0x1a, 0x2a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, + 0x5e, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x75, 0x69, + 0x6e, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x09, 0x62, 0x69, + 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x74, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x51, 0x92, + 0x41, 0x47, 0x32, 0x45, 0x4d, 0x61, 0x78, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, + 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x2e, 0xba, 0x48, 0x04, 0x22, 0x02, 0x20, 0x00, + 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x5c, 0x0a, + 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x3d, 0x92, 0x41, 0x31, 0x32, 0x2f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x2e, 0xba, 0x48, 0x06, 0x7a, 0x04, 0x10, 0x01, 0x18, 0x40, + 0x52, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0xc2, 0x01, 0x0a, 0x15, + 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x8d, 0x01, 0x92, 0x41, + 0x2d, 0x32, 0x2b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x73, 0x20, 0x64, 0x65, 0x63, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, 0x48, + 0x5a, 0xba, 0x01, 0x57, 0x0a, 0x15, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x64, 0x65, 0x63, + 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x0e, 0x75, 0x69, 0x6e, + 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x13, 0x64, 0x65, 0x63, + 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0xb8, 0x01, 0x0a, 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x42, 0x87, + 0x01, 0x92, 0x41, 0x2b, 0x32, 0x29, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, + 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, + 0x20, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x65, 0x63, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, + 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2c, 0x64, 0x65, 0x63, 0x61, + 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x0e, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x11, 0x64, 0x65, 0x63, 0x61, 0x79, 0x45, + 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x8a, 0x02, 0x0a, 0x13, + 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x42, 0xd9, 0x01, 0x92, 0x41, 0x49, 0x32, + 0x47, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x78, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x62, 0x65, 0x20, 0x64, 0x69, + 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x2e, 0xba, 0x48, 0x89, 0x01, 0xba, 0x01, 0x85, 0x01, + 0x0a, 0x13, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x41, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, + 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, + 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, + 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, + 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x11, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x9d, 0x02, 0x0a, 0x10, 0x72, 0x61, 0x77, + 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x09, 0x42, 0xf1, 0x01, 0x92, 0x41, 0x6e, 0x32, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x4c, 0x50, + 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0xba, 0x48, 0x7d, 0xba, 0x01, 0x7a, 0x0a, 0x10, 0x72, + 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x3c, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x1a, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, + 0x39, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x29, 0x52, 0x0f, 0x72, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0xd2, 0x04, 0x92, 0x41, 0xce, 0x04, 0x0a, + 0x70, 0x2a, 0x0b, 0x42, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x30, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0xd2, 0x01, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0xd2, 0x01, 0x09, 0x62, 0x69, + 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0xd2, 0x01, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x32, 0xd9, 0x03, 0x7b, 0x22, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x3a, + 0x20, 0x5b, 0x22, 0x66, 0x65, 0x34, 0x63, 0x62, 0x34, 0x37, 0x64, 0x62, 0x33, 0x36, 0x33, 0x30, + 0x35, 0x35, 0x31, 0x62, 0x65, 0x65, 0x64, 0x66, 0x62, 0x64, 0x30, 0x32, 0x61, 0x37, 0x31, 0x65, + 0x63, 0x63, 0x36, 0x39, 0x66, 0x64, 0x35, 0x39, 0x37, 0x35, 0x38, 0x65, 0x32, 0x62, 0x61, 0x36, + 0x39, 0x39, 0x36, 0x30, 0x36, 0x65, 0x32, 0x64, 0x35, 0x63, 0x37, 0x34, 0x32, 0x38, 0x34, 0x66, + 0x66, 0x61, 0x37, 0x22, 0x2c, 0x20, 0x22, 0x37, 0x31, 0x63, 0x31, 0x33, 0x34, 0x38, 0x66, 0x32, + 0x64, 0x37, 0x66, 0x66, 0x37, 0x65, 0x38, 0x31, 0x34, 0x66, 0x39, 0x63, 0x33, 0x36, 0x31, 0x37, + 0x39, 0x38, 0x33, 0x37, 0x30, 0x33, 0x34, 0x33, 0x35, 0x65, 0x61, 0x37, 0x34, 0x34, 0x36, 0x64, + 0x65, 0x34, 0x32, 0x30, 0x61, 0x65, 0x61, 0x63, 0x34, 0x38, 0x38, 0x62, 0x66, 0x31, 0x64, 0x65, + 0x33, 0x35, 0x37, 0x33, 0x37, 0x65, 0x38, 0x22, 0x5d, 0x2c, 0x20, 0x22, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x2c, 0x20, 0x22, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, + 0x22, 0x39, 0x64, 0x4a, 0x69, 0x6e, 0x77, 0x4c, 0x2b, 0x46, 0x5a, 0x36, 0x42, 0x31, 0x78, 0x73, + 0x49, 0x51, 0x51, 0x6f, 0x38, 0x74, 0x38, 0x42, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x62, 0x4a, 0x77, + 0x59, 0x38, 0x36, 0x6c, 0x2f, 0x59, 0x75, 0x37, 0x79, 0x41, 0x48, 0x31, 0x35, 0x39, 0x51, 0x72, + 0x50, 0x48, 0x55, 0x30, 0x71, 0x6a, 0x32, 0x50, 0x2b, 0x59, 0x46, 0x6a, 0x2b, 0x6c, 0x6c, 0x62, + 0x75, 0x49, 0x31, 0x5a, 0x79, 0x67, 0x64, 0x78, 0x47, 0x73, 0x58, 0x38, 0x2b, 0x50, 0x33, 0x62, + 0x79, 0x4d, 0x45, 0x41, 0x35, 0x69, 0x67, 0x3d, 0x3d, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, + 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x22, 0x3a, 0x31, 0x37, 0x32, 0x35, 0x33, 0x36, 0x35, 0x33, 0x30, 0x31, 0x30, 0x30, 0x30, 0x2c, + 0x20, 0x22, 0x64, 0x65, 0x63, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x31, 0x37, 0x32, 0x35, 0x33, 0x36, 0x35, 0x33, 0x30, 0x32, 0x30, + 0x30, 0x30, 0x2c, 0x20, 0x22, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x78, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x66, 0x65, 0x34, 0x63, 0x62, 0x34, + 0x37, 0x64, 0x62, 0x33, 0x36, 0x33, 0x30, 0x35, 0x35, 0x31, 0x62, 0x65, 0x65, 0x64, 0x66, 0x62, + 0x64, 0x30, 0x32, 0x61, 0x37, 0x31, 0x65, 0x63, 0x63, 0x36, 0x39, 0x66, 0x64, 0x35, 0x39, 0x37, + 0x35, 0x38, 0x65, 0x32, 0x62, 0x61, 0x36, 0x39, 0x39, 0x36, 0x30, 0x36, 0x65, 0x32, 0x64, 0x35, + 0x63, 0x37, 0x34, 0x32, 0x38, 0x34, 0x66, 0x66, 0x61, 0x37, 0x22, 0x5d, 0x7d, 0x22, 0x81, 0x06, + 0x0a, 0x0b, 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, + 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x34, 0x92, 0x41, 0x31, 0x32, 0x2f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x23, 0x92, 0x41, 0x14, 0x32, 0x12, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x2e, 0xba, + 0x48, 0x09, 0x82, 0x01, 0x06, 0x10, 0x01, 0x1a, 0x02, 0x01, 0x02, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0xb4, 0x01, 0x0a, 0x12, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x42, 0x84, 0x01, 0x92, 0x41, 0x80, 0x01, 0x32, 0x7e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, + 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, + 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x3a, 0xb8, 0x02, 0x92, 0x41, 0xb4, 0x02, 0x0a, 0x82, 0x01, + 0x2a, 0x0c, 0x42, 0x69, 0x64, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x44, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x64, 0x2e, 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, + 0xd2, 0x01, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0xd2, 0x01, 0x16, 0x64, 0x65, 0x63, 0x61, + 0x79, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x32, 0xac, 0x01, 0x7b, 0x22, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x22, 0x3a, 0x20, 0x22, 0x39, 0x64, 0x4a, 0x69, 0x6e, 0x77, 0x4c, 0x2b, 0x46, 0x5a, 0x36, 0x42, + 0x31, 0x78, 0x73, 0x49, 0x51, 0x51, 0x6f, 0x38, 0x74, 0x38, 0x42, 0x30, 0x5a, 0x58, 0x4a, 0x75, + 0x62, 0x4a, 0x77, 0x59, 0x38, 0x36, 0x6c, 0x2f, 0x59, 0x75, 0x37, 0x79, 0x41, 0x48, 0x31, 0x35, + 0x39, 0x51, 0x72, 0x50, 0x48, 0x55, 0x30, 0x71, 0x6a, 0x32, 0x50, 0x2b, 0x59, 0x46, 0x6a, 0x2b, + 0x6c, 0x6c, 0x62, 0x75, 0x49, 0x31, 0x5a, 0x79, 0x67, 0x64, 0x78, 0x47, 0x73, 0x58, 0x38, 0x2b, + 0x50, 0x33, 0x62, 0x79, 0x4d, 0x45, 0x41, 0x35, 0x69, 0x67, 0x3d, 0x3d, 0x22, 0x2c, 0x20, 0x22, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3a, 0x20, 0x22, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, + 0x61, 0x79, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, + 0x7d, 0x32, 0x91, 0x06, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, + 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x42, 0x69, 0x64, 0x73, 0x12, 0x1c, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x13, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, + 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x62, + 0x69, 0x64, 0x73, 0x30, 0x01, 0x12, 0x7d, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x42, 0x69, 0x64, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x23, - 0x92, 0x41, 0x14, 0x32, 0x12, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x2e, 0xba, 0x48, 0x09, 0x82, 0x01, 0x06, 0x10, 0x01, 0x1a, - 0x02, 0x01, 0x02, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0xb4, 0x01, 0x0a, 0x12, - 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x84, 0x01, 0x92, 0x41, 0x80, 0x01, 0x32, - 0x7e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, - 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, - 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x20, 0x62, - 0x79, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, - 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x72, - 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x11, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, - 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x3a, 0xb8, - 0x02, 0x92, 0x41, 0xb4, 0x02, 0x0a, 0x82, 0x01, 0x2a, 0x0c, 0x42, 0x69, 0x64, 0x20, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, - 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, - 0x69, 0x64, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x2e, 0xd2, 0x01, 0x09, 0x62, - 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0xd2, 0x01, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0xd2, 0x01, 0x16, 0x64, 0x65, 0x63, 0x61, 0x79, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, - 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x32, 0xac, 0x01, 0x7b, 0x22, 0x62, - 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x39, 0x64, 0x4a, 0x69, - 0x6e, 0x77, 0x4c, 0x2b, 0x46, 0x5a, 0x36, 0x42, 0x31, 0x78, 0x73, 0x49, 0x51, 0x51, 0x6f, 0x38, - 0x74, 0x38, 0x42, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x62, 0x4a, 0x77, 0x59, 0x38, 0x36, 0x6c, 0x2f, - 0x59, 0x75, 0x37, 0x79, 0x41, 0x48, 0x31, 0x35, 0x39, 0x51, 0x72, 0x50, 0x48, 0x55, 0x30, 0x71, - 0x6a, 0x32, 0x50, 0x2b, 0x59, 0x46, 0x6a, 0x2b, 0x6c, 0x6c, 0x62, 0x75, 0x49, 0x31, 0x5a, 0x79, - 0x67, 0x64, 0x78, 0x47, 0x73, 0x58, 0x38, 0x2b, 0x50, 0x33, 0x62, 0x79, 0x4d, 0x45, 0x41, 0x35, - 0x69, 0x67, 0x3d, 0x3d, 0x22, 0x2c, 0x20, 0x22, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3a, - 0x20, 0x22, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, - 0x44, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, 0x61, 0x79, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, - 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x20, 0x31, 0x32, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x7d, 0x32, 0x91, 0x06, 0x0a, 0x08, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, - 0x65, 0x42, 0x69, 0x64, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, - 0x12, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x72, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x69, 0x64, 0x73, 0x30, 0x01, 0x12, 0x7d, 0x0a, - 0x11, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x42, 0x69, - 0x64, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, - 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2b, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x64, 0x73, 0x28, 0x01, 0x12, 0x69, 0x0a, 0x05, - 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x2f, 0x7b, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x12, 0x67, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, - 0x12, 0x6e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, - 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1d, 0x2e, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, + 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x73, + 0x65, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x69, + 0x64, 0x73, 0x28, 0x01, 0x12, 0x69, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, - 0x12, 0x76, 0x0a, 0x0d, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x53, 0x74, 0x61, 0x6b, - 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, - 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x76, 0x31, - 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, - 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x63, 0x0a, 0x07, 0x55, 0x6e, 0x73, 0x74, - 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x42, 0xbc, 0x02, - 0x92, 0x41, 0x74, 0x12, 0x72, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, - 0x41, 0x50, 0x49, 0x2a, 0x55, 0x0a, 0x1b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x31, - 0x2e, 0x31, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x76, 0x2f, 0x6d, 0x65, - 0x76, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, - 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x0b, 0x31, 0x2e, 0x30, 0x2e, - 0x30, 0x2d, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x69, 0x6d, - 0x65, 0x76, 0x2f, 0x6d, 0x65, 0x76, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2f, 0x70, 0x32, - 0x70, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x61, 0x70, 0x69, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0e, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1a, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, + 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x2f, 0x7b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x12, + 0x67, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, + 0x12, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x67, + 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x6e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, + 0x69, 0x6e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, + 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x6d, + 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x76, 0x0a, 0x0d, 0x57, 0x69, 0x74, 0x68, + 0x64, 0x72, 0x61, 0x77, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, + 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x2f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, + 0x12, 0x63, 0x0a, 0x07, 0x55, 0x6e, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, + 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x75, 0x6e, + 0x73, 0x74, 0x61, 0x6b, 0x65, 0x42, 0xbc, 0x02, 0x92, 0x41, 0x74, 0x12, 0x72, 0x0a, 0x0c, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x2a, 0x55, 0x0a, 0x1b, 0x42, + 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x4c, + 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x31, 0x2e, 0x31, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, + 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x72, 0x69, 0x6d, 0x65, 0x76, 0x2f, 0x6d, 0x65, 0x76, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, + 0x53, 0x45, 0x32, 0x0b, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x0a, + 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x42, 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x76, 0x2f, 0x6d, 0x65, 0x76, 0x2d, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, + 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x76, 0x31, 0xa2, 0x02, 0x03, + 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, + 0x69, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, + 0x70, 0x69, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x70, 0x69, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml b/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml index db9561cb9..d84e1835b 100644 --- a/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml +++ b/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml @@ -114,6 +114,15 @@ paths: type: string pattern: ^(0x)?[a-fA-F0-9]{96}$ collectionFormat: multi + - name: blsSignatures + description: BLS signatures corresponding to the BLS public keys. + in: query + required: false + type: array + items: + type: string + pattern: ^(0x)?[a-fA-F0-9]{192}$ + collectionFormat: multi /v1/provider/unstake: post: summary: Unstake diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index f6b1a0f15..9e8f5287b 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -45,7 +45,8 @@ type Service struct { type ProviderRegistryContract interface { ProviderRegistered(opts *bind.CallOpts, address common.Address) (bool, error) Stake(opts *bind.TransactOpts) (*types.Transaction, error) - RegisterAndStake(opts *bind.TransactOpts, blsPublicKey [][]byte) (*types.Transaction, error) + RegisterAndStake(opts *bind.TransactOpts) (*types.Transaction, error) + AddVerifiedBLSKey(opts *bind.TransactOpts, blsPublicKey []byte, signature []byte) (*types.Transaction, error) GetProviderStake(*bind.CallOpts, common.Address) (*big.Int, error) GetBLSKeys(*bind.CallOpts, common.Address) ([][]byte, error) MinStake(*bind.CallOpts) (*big.Int, error) @@ -237,18 +238,18 @@ func (s *Service) Stake( return nil, status.Errorf(codes.Internal, "checking registration: %v", err) } if !registered { - blsPubkeyBytesArray := make([][]byte, len(stake.BlsPublicKeys)) - for i, key := range stake.BlsPublicKeys { - stake.BlsPublicKeys[i] = strings.TrimPrefix(key, "0x") - blsPubkeyBytes, err := hex.DecodeString(stake.BlsPublicKeys[i]) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "decoding bls public key: %v", err) - } - blsPubkeyBytesArray[i] = blsPubkeyBytes + tx, txErr = s.registryContract.RegisterAndStake(opts) + receipt, err := s.watcher.WaitForReceipt(ctx, tx) + if err != nil { + return nil, status.Errorf(codes.Internal, "waiting for receipt: %v", err) + } + if receipt.Status != types.ReceiptStatusSuccessful { + return nil, status.Errorf(codes.Internal, "receipt status: %v", receipt.Status) } - tx, txErr = s.registryContract.RegisterAndStake(opts, blsPubkeyBytesArray) - + for i, _ := range stake.BlsPublicKeys { + tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, []byte(stake.BlsPublicKeys[i]), []byte(stake.BlsSignatures[i])) + } } else { tx, txErr = s.registryContract.Stake(opts) } diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index cf7f825a9..a469bd58b 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -38,9 +38,13 @@ func (t *testRegistryContract) ProviderRegistered(opts *bind.CallOpts, address c return true, nil } -func (t *testRegistryContract) RegisterAndStake(opts *bind.TransactOpts, blsPublicKey [][]byte) (*types.Transaction, error) { +func (t *testRegistryContract) RegisterAndStake(opts *bind.TransactOpts) (*types.Transaction, error) { t.stake = opts.Value - t.blsKey = blsPublicKey[0] + return types.NewTransaction(1, common.Address{}, nil, 0, nil, nil), nil +} + +func (t *testRegistryContract) AddVerifiedBLSKey(opts *bind.TransactOpts, blsPublicKey []byte, blsSignature []byte) (*types.Transaction, error) { + t.blsKey = blsPublicKey return types.NewTransaction(1, common.Address{}, nil, 0, nil, nil), nil } @@ -187,11 +191,12 @@ func TestStakeHandling(t *testing.T) { client, _ := startServer(t) validBLSKey := "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" - + validSignature := "bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" t.Run("register stake", func(t *testing.T) { type testCase struct { amount string blsPublicKey string + blsSignature string err string } @@ -199,6 +204,7 @@ func TestStakeHandling(t *testing.T) { { amount: "", blsPublicKey: "", + blsSignature: "", err: "amount must be a valid integer", }, { @@ -222,16 +228,24 @@ func TestStakeHandling(t *testing.T) { { amount: "1000000000000000000", blsPublicKey: validBLSKey, + blsSignature: "", + err: "bls_signatures must be a valid 96-byte hex string, with optional 0x prefix.", + }, + { + amount: "1000000000000000000", + blsPublicKey: validBLSKey, + blsSignature: validSignature, err: "", }, { amount: "1000000000000000000", blsPublicKey: validBLSKey, + blsSignature: validSignature, err: "", }, } { stake, err := client.Stake(context.Background(), - &providerapiv1.StakeRequest{Amount: tc.amount, BlsPublicKeys: []string{tc.blsPublicKey}}) + &providerapiv1.StakeRequest{Amount: tc.amount, BlsPublicKeys: []string{tc.blsPublicKey}, BlsSignatures: []string{tc.blsSignature}}) if tc.err != "" { if err == nil || !strings.Contains(err.Error(), tc.err) { t.Fatalf("expected error staking: %s got %v", tc.err, err) @@ -470,6 +484,7 @@ func TestWithdrawStakedAmount(t *testing.T) { _, err := client.Stake(context.Background(), &providerapiv1.StakeRequest{ Amount: "1000000000000000000", BlsPublicKeys: []string{"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"}, + BlsSignatures: []string{"bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2"}, }) if err != nil { t.Fatalf("error depositing stake: %v", err) diff --git a/p2p/rpc/providerapi/v1/providerapi.proto b/p2p/rpc/providerapi/v1/providerapi.proto index c0f8fa32b..0b1559ad9 100644 --- a/p2p/rpc/providerapi/v1/providerapi.proto +++ b/p2p/rpc/providerapi/v1/providerapi.proto @@ -94,6 +94,14 @@ message StakeRequest { message: "bls_public_key must be a valid 48-byte hex string, with optional 0x prefix.", expression: "size(this) > 0 && this.all(r, r.matches('^(0x)?[a-fA-F0-9]{96}$'))" }]; + repeated string bls_signatures = 3 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "BLS signatures corresponding to the BLS public keys." + pattern: "^(0x)?[a-fA-F0-9]{192}$" + }, (buf.validate.field).cel = { + id: "bls_signatures", + message: "bls_signatures must be a valid 96-byte hex string, with optional 0x prefix.", + expression: "size(this) > 0 && this.all(r, r.matches('^(0x)?[a-fA-F0-9]{192}$'))" + }]; }; message StakeResponse { From b5bc395c67535bf38358d8d2493b8b1ea80fcdd9 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 11:27:38 -0500 Subject: [PATCH 07/44] feat: adds bls key registration to e2e test --- go.work.sum | 1 + testing/pkg/tests/staking/staking.go | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/go.work.sum b/go.work.sum index 75012cf83..4418417fd 100644 --- a/go.work.sum +++ b/go.work.sum @@ -788,6 +788,7 @@ github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyX github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625 h1:ckJgFhFWywOx+YLEMIJsTb+NV6NexWICk5+AMSuz3ss= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= diff --git a/testing/pkg/tests/staking/staking.go b/testing/pkg/tests/staking/staking.go index 8f383d796..f6acab3e1 100644 --- a/testing/pkg/tests/staking/staking.go +++ b/testing/pkg/tests/staking/staking.go @@ -11,6 +11,9 @@ import ( "net/http" "slices" + "github.com/cloudflare/circl/sign/bls" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" providerregistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" providerapiv1 "github.com/primev/mev-commit/p2p/gen/go/providerapi/v1" "github.com/primev/mev-commit/testing/pkg/orchestrator" @@ -96,18 +99,22 @@ func Run(ctx context.Context, cluster orchestrator.Orchestrator, cfg any) error stakeAmount := big.NewInt(0).Mul(amount, big.NewInt(10)) - blsPubkeyBytes := make([]byte, 48) - _, err = rand.Read(blsPubkeyBytes) - if err != nil { - l.Error("failed to generate mock BLS public key", "err", err) - return fmt.Errorf("failed to generate mock BLS public key: %w", err) - } + iv := make([]byte, 32) + _, _ = rand.Read(iv) + blsPrivKey, _ := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) + pubKey := blsPrivKey.PublicKey() + pubKeyBytes, _ := pubKey.MarshalBinary() + value := common.Hex2Bytes(p.EthAddress()) + hash := crypto.Keccak256Hash(value) + signature := bls.Sign(blsPrivKey, hash.Bytes()) // Register a provider resp, err := providerAPI.Stake(ctx, &providerapiv1.StakeRequest{ Amount: stakeAmount.String(), - BlsPublicKeys: []string{hex.EncodeToString(blsPubkeyBytes)}, + BlsPublicKeys: []string{hex.EncodeToString(pubKeyBytes)}, + BlsSignatures: []string{hex.EncodeToString(signature)}, }) + if err != nil { l.Error("failed to register stake", "error", err) return fmt.Errorf("failed to register stake: %w", err) @@ -118,7 +125,7 @@ func Run(ctx context.Context, cluster orchestrator.Orchestrator, cfg any) error return fmt.Errorf("invalid stake amount returned: %s", resp.Amount) } - reqBytes, err := json.Marshal([]string{hex.EncodeToString(blsPubkeyBytes)}) + reqBytes, err := json.Marshal([]string{hex.EncodeToString(pubKeyBytes)}) if err != nil { l.Error("failed to create bls key upload req", "error", err) return fmt.Errorf("failed to marshal bls keys: %w", err) From a6285fa514075284c33f5c35435839ed13cb1a09 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 12:02:02 -0500 Subject: [PATCH 08/44] chore: updates go mod files --- testing/go.mod | 1 + testing/go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/testing/go.mod b/testing/go.mod index a8a71c205..17fc6f85f 100644 --- a/testing/go.mod +++ b/testing/go.mod @@ -23,6 +23,7 @@ require ( github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudflare/circl v1.5.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect diff --git a/testing/go.sum b/testing/go.sum index de12dee7e..362da558d 100644 --- a/testing/go.sum +++ b/testing/go.sum @@ -22,6 +22,8 @@ github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= +github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a h1:f52TdbU4D5nozMAhO9TvTJ2ZMCXtN4VIAmfrrZ0JXQ4= From 132c431a7880967ba3de4976ae9abf6eeff9a0d2 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 12:06:31 -0500 Subject: [PATCH 09/44] chore: updates ordering of contract functions --- contracts/contracts/core/ProviderRegistry.sol | 60 ++++++++++--------- .../interfaces/IProviderRegistry.sol | 4 +- .../BLSVerifyPreCompileMockTest.sol | 2 +- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 397077bf4..fb1ed7fed 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -234,6 +234,35 @@ contract ProviderRegistry is emit BidderWithdrawSlashedAmount(msg.sender, amount); } + /** + * @dev Adds a verified BLS key to the provider's account. + * @param blsPublicKey The BLS public key to be added. + * @param signature The signature (96 bytes) used for verification. + */ + function addVerifiedBLSKey( + bytes calldata blsPublicKey, + bytes calldata signature + ) external { + address provider = msg.sender; + + require(providerRegistered[provider], "Provider not registered"); + require(blsPublicKey.length == 48, "Public key must be 48 bytes"); + require(signature.length == 96, "Signature must be 96 bytes"); + + + bytes32 message = keccak256(abi.encodePacked(provider)); + + // Verify the BLS signature + bool isValid = verifySignature(blsPublicKey, message, signature); + require(isValid, "Invalid BLS signature"); + + // Add the BLS public key to the provider's account + eoaToBlsPubkeys[provider].push(blsPublicKey); + blockBuilderBLSKeyToAddress[blsPublicKey] = provider; + + emit BLSKeyAdded(provider, blsPublicKey); + } + /** * @dev Manually withdraws accumulated penalty fees to the recipient * to cover the edge case that oracle doesn't slash/reward, and funds still need to be withdrawn. @@ -276,6 +305,8 @@ contract ProviderRegistry is return penaltyFeeTracker.accumulatedAmount; } + + /** * @dev Register and stake function for providers. * The validity of this key must be verified manually off-chain. @@ -306,35 +337,6 @@ contract ProviderRegistry is emit FundsDeposited(provider, msg.value); } - /** - * @dev Adds a verified BLS key to the provider's account. - * @param blsPublicKey The BLS public key to be added. - * @param signature The signature (96 bytes) used for verification. - */ - function addVerifiedBLSKey( - bytes calldata blsPublicKey, - bytes calldata signature - ) external { - address provider = msg.sender; - - require(providerRegistered[provider], "Provider not registered"); - require(blsPublicKey.length == 48, "Public key must be 48 bytes"); - require(signature.length == 96, "Signature must be 96 bytes"); - - - bytes32 message = keccak256(abi.encodePacked(provider)); - - // Verify the BLS signature - bool isValid = verifySignature(blsPublicKey, message, signature); - require(isValid, "Invalid BLS signature"); - - // Add the BLS public key to the provider's account - eoaToBlsPubkeys[provider].push(blsPublicKey); - blockBuilderBLSKeyToAddress[blsPublicKey] = provider; - - emit BLSKeyAdded(provider, blsPublicKey); - } - /** * @dev Verifies a BLS signature using the precompile * @param pubKey The public key (48 bytes G1 point) diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index acc38f447..5b3df083e 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -79,11 +79,11 @@ interface IProviderRegistry { uint256 residualBidPercentAfterDecay ) external; + function addVerifiedBLSKey(bytes calldata blsPublicKey, bytes calldata signature) external; + function isProviderValid(address committerAddress) external view; function getEoaFromBLSKey(bytes calldata blsKey) external view returns (address); - function addVerifiedBLSKey(bytes calldata blsPublicKey, bytes calldata signature) external; - function overrideAddBLSKey(address provider, bytes calldata blsPublicKey) external; } diff --git a/contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol b/contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol index b449781c7..8cb035c10 100644 --- a/contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol +++ b/contracts/test/precompiles/BLSVerifyPreCompileMockTest.sol @@ -12,7 +12,7 @@ contract BLSVerifyPreCompileMock is Test { vm.etch(BLS_VERIFY, code); } - function testVerifySignature() public { + function testVerifySignature() public view { // Store the values as constants or immutable variables since they're fixed test data bytes memory pubKeyData = hex"b67a5148a03229926e34b190af81a82a81c4df66831c98c03a139778418dd09a3b542ced0022620d19f35781ece6dc36"; bytes32 messageData = keccak256(abi.encodePacked("test message")); From bb3327dd801d9bd985d2db5bad842ddaf9f929b7 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 12:09:29 -0500 Subject: [PATCH 10/44] chore: attempt to sync mod files --- testing/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/go.mod b/testing/go.mod index 17fc6f85f..f42c8a48f 100644 --- a/testing/go.mod +++ b/testing/go.mod @@ -4,6 +4,7 @@ go 1.23 require ( github.com/armon/go-radix v1.0.0 + github.com/cloudflare/circl v1.5.0 github.com/ethereum/go-ethereum v1.14.11 github.com/primev/mev-commit/bridge/standard v0.0.1 github.com/primev/mev-commit/contracts-abi v0.0.1 @@ -23,7 +24,6 @@ require ( github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudflare/circl v1.5.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect From 0ae3946d20bca9999549df9221f68d351eb3473b Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 12:33:29 -0500 Subject: [PATCH 11/44] chore: fixes solidty linter --- contracts/contracts/core/ProviderRegistry.sol | 15 +++++++-------- .../contracts/interfaces/IProviderRegistry.sol | 11 +++++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index fb1ed7fed..1e1143a47 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -330,12 +330,6 @@ contract ProviderRegistry is require(withdrawalRequests[provider] == 0, PendingWithdrawalRequest(provider)); } - function _stake(address provider) internal { - require(providerRegistered[provider], ProviderNotRegistered(provider)); - require(withdrawalRequests[provider] == 0, PendingWithdrawalRequest(provider)); - providerStakes[provider] += msg.value; - emit FundsDeposited(provider, msg.value); - } /** * @dev Verifies a BLS signature using the precompile @@ -373,8 +367,13 @@ contract ProviderRegistry is return result.length > 0; } - event BLSKeyAdded(address indexed provider, bytes blsPublicKey); - + function _stake(address provider) internal { + require(providerRegistered[provider], ProviderNotRegistered(provider)); + require(withdrawalRequests[provider] == 0, PendingWithdrawalRequest(provider)); + providerStakes[provider] += msg.value; + emit FundsDeposited(provider, msg.value); + } + function _registerAndStake(address provider) internal { require(!providerRegistered[provider], ProviderAlreadyRegistered(provider)); require(msg.value >= minStake, InsufficientStake(msg.value, minStake)); diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index 5b3df083e..fc6cc2d9e 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -36,6 +36,9 @@ interface IProviderRegistry { /// @dev Event emitted when the fee percent is updated event FeePercentUpdated(uint256 indexed newFeePercent); + /// @dev Event emitted when a BLS key is added + event BLSKeyAdded(address indexed provider, bytes blsPublicKey); + /// @dev Event emitted when there are insufficient funds to slash event InsufficientFundsToSlash( address indexed provider, @@ -67,7 +70,7 @@ interface IProviderRegistry { error PendingWithdrawalRequest(address sender); error BidderAmountIsZero(address sender); error BidderWithdrawalTransferFailed(address sender, uint256 amount); - + function registerAndStake() external payable; function stake() external payable; @@ -78,12 +81,12 @@ interface IProviderRegistry { address payable bidder, uint256 residualBidPercentAfterDecay ) external; - + function addVerifiedBLSKey(bytes calldata blsPublicKey, bytes calldata signature) external; + + function overrideAddBLSKey(address provider, bytes calldata blsPublicKey) external; function isProviderValid(address committerAddress) external view; function getEoaFromBLSKey(bytes calldata blsKey) external view returns (address); - - function overrideAddBLSKey(address provider, bytes calldata blsPublicKey) external; } From 132332e1794ea701e060605a293983bdcad3d79e Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 14:53:57 -0500 Subject: [PATCH 12/44] chore: updates e2e testing --- p2p/pkg/rpc/provider/service.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 9e8f5287b..3f1867d2a 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -241,7 +241,7 @@ func (s *Service) Stake( tx, txErr = s.registryContract.RegisterAndStake(opts) receipt, err := s.watcher.WaitForReceipt(ctx, tx) if err != nil { - return nil, status.Errorf(codes.Internal, "waiting for receipt: %v", err) + return nil, status.Errorf(codes.Internal, "waiting for receipt for registration: %v", err) } if receipt.Status != types.ReceiptStatusSuccessful { return nil, status.Errorf(codes.Internal, "receipt status: %v", receipt.Status) @@ -249,6 +249,16 @@ func (s *Service) Stake( for i, _ := range stake.BlsPublicKeys { tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, []byte(stake.BlsPublicKeys[i]), []byte(stake.BlsSignatures[i])) + if txErr != nil { + return nil, status.Errorf(codes.Internal, "adding verified bls key: %v", txErr) + } + receipt, err = s.watcher.WaitForReceipt(ctx, tx) + if err != nil { + return nil, status.Errorf(codes.Internal, "waiting for receipt for adding verified bls key: %v", err) + } + if receipt.Status != types.ReceiptStatusSuccessful { + return nil, status.Errorf(codes.Internal, "receipt status: %v", receipt.Status) + } } } else { tx, txErr = s.registryContract.Stake(opts) From 8028dea30faa73d5605c3e651e9e40241621dfad Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 15:13:44 -0500 Subject: [PATCH 13/44] feat: updates how staking is implemented --- p2p/pkg/rpc/provider/service.go | 64 ++++++++++++++-------------- p2p/pkg/rpc/provider/service_test.go | 7 +++ 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 3f1867d2a..3db1adefe 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -54,6 +54,7 @@ type ProviderRegistryContract interface { ParseFundsDeposited(types.Log) (*providerregistry.ProviderregistryFundsDeposited, error) ParseUnstake(types.Log) (*providerregistry.ProviderregistryUnstake, error) ParseWithdraw(types.Log) (*providerregistry.ProviderregistryWithdraw, error) + ParseBLSKeyAdded(types.Log) (*providerregistry.ProviderregistryBLSKeyAdded, error) Withdraw(opts *bind.TransactOpts) (*types.Transaction, error) Unstake(opts *bind.TransactOpts) (*types.Transaction, error) } @@ -237,29 +238,9 @@ func (s *Service) Stake( if err != nil { return nil, status.Errorf(codes.Internal, "checking registration: %v", err) } + if !registered { tx, txErr = s.registryContract.RegisterAndStake(opts) - receipt, err := s.watcher.WaitForReceipt(ctx, tx) - if err != nil { - return nil, status.Errorf(codes.Internal, "waiting for receipt for registration: %v", err) - } - if receipt.Status != types.ReceiptStatusSuccessful { - return nil, status.Errorf(codes.Internal, "receipt status: %v", receipt.Status) - } - - for i, _ := range stake.BlsPublicKeys { - tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, []byte(stake.BlsPublicKeys[i]), []byte(stake.BlsSignatures[i])) - if txErr != nil { - return nil, status.Errorf(codes.Internal, "adding verified bls key: %v", txErr) - } - receipt, err = s.watcher.WaitForReceipt(ctx, tx) - if err != nil { - return nil, status.Errorf(codes.Internal, "waiting for receipt for adding verified bls key: %v", err) - } - if receipt.Status != types.ReceiptStatusSuccessful { - return nil, status.Errorf(codes.Internal, "receipt status: %v", receipt.Status) - } - } } else { tx, txErr = s.registryContract.Stake(opts) } @@ -269,29 +250,50 @@ func (s *Service) Stake( receipt, err := s.watcher.WaitForReceipt(ctx, tx) if err != nil { - return nil, status.Errorf(codes.Internal, "waiting for receipt: %v", err) + return nil, status.Errorf(codes.Internal, "waiting for receipt for registration: %v", err) } if receipt.Status != types.ReceiptStatusSuccessful { return nil, status.Errorf(codes.Internal, "receipt status: %v", receipt.Status) } + var stakeResponse *providerapiv1.StakeResponse for _, log := range receipt.Logs { if registration, err := s.registryContract.ParseProviderRegistered(*log); err == nil { s.logger.Info("stake registered", "amount", registration.StakedAmount) - return &providerapiv1.StakeResponse{ - Amount: registration.StakedAmount.String(), - BlsPublicKeys: stake.BlsPublicKeys, - }, nil - } - if deposit, err := s.registryContract.ParseFundsDeposited(*log); err == nil { + stakeResponse = &providerapiv1.StakeResponse{ + Amount: registration.StakedAmount.String(), + } + } else if deposit, err := s.registryContract.ParseFundsDeposited(*log); err == nil { s.logger.Info("stake deposited", "amount", deposit.Amount) - return &providerapiv1.StakeResponse{Amount: deposit.Amount.String()}, nil + stakeResponse = &providerapiv1.StakeResponse{Amount: deposit.Amount.String()} + } + } + + for i, _ := range stake.BlsPublicKeys { + tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, []byte(stake.BlsPublicKeys[i]), []byte(stake.BlsSignatures[i])) + if txErr != nil { + return nil, status.Errorf(codes.Internal, "adding verified bls key: %v", txErr) + } + receipt, err = s.watcher.WaitForReceipt(ctx, tx) + if err != nil { + return nil, status.Errorf(codes.Internal, "waiting for receipt for adding verified bls key: %v", err) + } + if receipt.Status != types.ReceiptStatusSuccessful { + return nil, status.Errorf(codes.Internal, "receipt status: %v", receipt.Status) + } + + s.logger.Info("verified bls key added", "key", stake.BlsPublicKeys[i]) + + for _, log := range receipt.Logs { + if blsKeyEvent, err := s.registryContract.ParseBLSKeyAdded(*log); err == nil { + s.logger.Info("verified bls key added", "key", blsKeyEvent.BlsPublicKey) + stakeResponse.BlsPublicKeys = append(stakeResponse.BlsPublicKeys, string(blsKeyEvent.BlsPublicKey)) + } } } - s.logger.Error("no registration event found") - return nil, status.Error(codes.Internal, "no registration event found") + return stakeResponse, nil } func (s *Service) GetStake( diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index a469bd58b..cd83203c6 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -93,6 +93,13 @@ func (t *testRegistryContract) ParseUnstake(log types.Log) (*providerregistry.Pr }, nil } +func (t *testRegistryContract) ParseBLSKeyAdded(log types.Log) (*providerregistry.ProviderregistryBLSKeyAdded, error) { + return &providerregistry.ProviderregistryBLSKeyAdded{ + Provider: common.Address{}, + BlsPublicKey: t.blsKey, + }, nil +} + func (t *testRegistryContract) Unstake(opts *bind.TransactOpts) (*types.Transaction, error) { return types.NewTransaction(1, common.Address{}, nil, 0, nil, nil), nil } From df498a769fb486c8962fe12920a29e92d7397baa Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 17:03:12 -0500 Subject: [PATCH 14/44] chore: ensures decoding of hex from rpc --- p2p/pkg/rpc/provider/service.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 3db1adefe..61f869325 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -271,7 +271,15 @@ func (s *Service) Stake( } for i, _ := range stake.BlsPublicKeys { - tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, []byte(stake.BlsPublicKeys[i]), []byte(stake.BlsSignatures[i])) + pubKey, err := hex.DecodeString(stake.BlsPublicKeys[i]) + if err != nil { + return nil, status.Errorf(codes.Internal, "decoding bls public key: %v", err) + } + signature, err := hex.DecodeString(stake.BlsSignatures[i]) + if err != nil { + return nil, status.Errorf(codes.Internal, "decoding bls signature: %v", err) + } + tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, pubKey, signature) if txErr != nil { return nil, status.Errorf(codes.Internal, "adding verified bls key: %v", txErr) } From 9708230e9f214b25d558c2e34bd9b83047101d81 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 18:11:17 -0500 Subject: [PATCH 15/44] chore: use real encoding in stake --- p2p/pkg/rpc/provider/service.go | 10 +------ p2p/pkg/rpc/provider/service_test.go | 44 ++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 61f869325..3db1adefe 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -271,15 +271,7 @@ func (s *Service) Stake( } for i, _ := range stake.BlsPublicKeys { - pubKey, err := hex.DecodeString(stake.BlsPublicKeys[i]) - if err != nil { - return nil, status.Errorf(codes.Internal, "decoding bls public key: %v", err) - } - signature, err := hex.DecodeString(stake.BlsSignatures[i]) - if err != nil { - return nil, status.Errorf(codes.Internal, "decoding bls signature: %v", err) - } - tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, pubKey, signature) + tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, []byte(stake.BlsPublicKeys[i]), []byte(stake.BlsSignatures[i])) if txErr != nil { return nil, status.Errorf(codes.Internal, "adding verified bls key: %v", txErr) } diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index cd83203c6..1e01fd161 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -2,6 +2,8 @@ package providerapi_test import ( "context" + "crypto/rand" + "encoding/hex" "errors" "math/big" "net" @@ -11,9 +13,11 @@ import ( "time" "github.com/bufbuild/protovalidate-go" + "github.com/cloudflare/circl/sign/bls" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" providerregistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" preconfpb "github.com/primev/mev-commit/p2p/gen/go/preconfirmation/v1" providerapiv1 "github.com/primev/mev-commit/p2p/gen/go/providerapi/v1" @@ -482,16 +486,52 @@ func TestBidHandling(t *testing.T) { } } +// func TestBLSKeys(t *testing.T) { + +// iv := make([]byte, 32) +// _, err := rand.Read(iv) +// assert.NoError(t, err) +// blsPrivKey, err := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) +// assert.NoError(t, err) + +// pubKey := blsPrivKey.PublicKey() + +// // Keccak the value 0x53c61cfb8128ad59244e8c1d26109252ace23d14 +// value := common.Hex2Bytes("53c61cfb8128ad59244e8c1d26109252ace23d14") +// hash := crypto.Keccak256Hash(value) +// t.Logf("Keccak hash: %s", hash.Hex()) + +// signature := bls.Sign(blsPrivKey, hash.Bytes()) +// pubKeyBytes, _ := pubKey.MarshalBinary() +// if !bls.Verify[bls.G1](pubKeyBytes, hash.Bytes(), signature) { +// t.Errorf("Signature verification failed") +// } +// // return nil, nil +// // } +// // return input[:48], nil +// } + func TestWithdrawStakedAmount(t *testing.T) { t.Parallel() client, _ := startServer(t) t.Run("withdraw stake", func(t *testing.T) { + iv := make([]byte, 32) + _, _ = rand.Read(iv) + blsPrivKey, _ := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) + pubKey := blsPrivKey.PublicKey() + pubKeyBytes, _ := pubKey.MarshalBinary() + value := common.Hex2Bytes("0x53c61cfb8128ad59244e8c1d26109252ace23d14") + hash := crypto.Keccak256Hash(value) + signature := bls.Sign(blsPrivKey, hash.Bytes()) + + t.Logf("Public Key: %s", hex.EncodeToString(pubKeyBytes)) + _, err := client.Stake(context.Background(), &providerapiv1.StakeRequest{ Amount: "1000000000000000000", - BlsPublicKeys: []string{"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"}, - BlsSignatures: []string{"bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2"}, + BlsPublicKeys: []string{hex.EncodeToString(pubKeyBytes)}, + BlsSignatures: []string{hex.EncodeToString(signature)}, }) if err != nil { t.Fatalf("error depositing stake: %v", err) From c82726703e43634d15526c16ff01411bf1efb51d Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 18:18:40 -0500 Subject: [PATCH 16/44] chore: fix go mod --- p2p/go.mod | 1 + p2p/go.sum | 1 + p2p/pkg/rpc/provider/service_test.go | 65 ++++++++++++++++++---------- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/p2p/go.mod b/p2p/go.mod index 4c0c9b35b..3dbc51efb 100644 --- a/p2p/go.mod +++ b/p2p/go.mod @@ -7,6 +7,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/armon/go-radix v1.0.0 github.com/bufbuild/protovalidate-go v0.6.0 + github.com/cloudflare/circl v1.5.0 github.com/cockroachdb/pebble v1.1.2 github.com/ethereum/go-ethereum v1.14.11 github.com/go-logr/logr v1.4.2 diff --git a/p2p/go.sum b/p2p/go.sum index 75b523568..2ab7df191 100644 --- a/p2p/go.sum +++ b/p2p/go.sum @@ -52,6 +52,7 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index 1e01fd161..7e947817b 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -23,6 +23,7 @@ import ( providerapiv1 "github.com/primev/mev-commit/p2p/gen/go/providerapi/v1" providerapi "github.com/primev/mev-commit/p2p/pkg/rpc/provider" "github.com/primev/mev-commit/x/util" + "github.com/stretchr/testify/assert" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/test/bufconn" @@ -486,30 +487,46 @@ func TestBidHandling(t *testing.T) { } } -// func TestBLSKeys(t *testing.T) { - -// iv := make([]byte, 32) -// _, err := rand.Read(iv) -// assert.NoError(t, err) -// blsPrivKey, err := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) -// assert.NoError(t, err) - -// pubKey := blsPrivKey.PublicKey() - -// // Keccak the value 0x53c61cfb8128ad59244e8c1d26109252ace23d14 -// value := common.Hex2Bytes("53c61cfb8128ad59244e8c1d26109252ace23d14") -// hash := crypto.Keccak256Hash(value) -// t.Logf("Keccak hash: %s", hash.Hex()) - -// signature := bls.Sign(blsPrivKey, hash.Bytes()) -// pubKeyBytes, _ := pubKey.MarshalBinary() -// if !bls.Verify[bls.G1](pubKeyBytes, hash.Bytes(), signature) { -// t.Errorf("Signature verification failed") -// } -// // return nil, nil -// // } -// // return input[:48], nil -// } +func TestBLSKeys(t *testing.T) { + + iv := make([]byte, 32) + _, err := rand.Read(iv) + assert.NoError(t, err) + blsPrivKey, err := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) + assert.NoError(t, err) + + pubKey := blsPrivKey.PublicKey() + + // Keccak the value 0x53c61cfb8128ad59244e8c1d26109252ace23d14 + value := common.Hex2Bytes("53c61cfb8128ad59244e8c1d26109252ace23d14") + hash := crypto.Keccak256Hash(value) + t.Logf("Keccak hash: %s", hash.Hex()) + + signature := bls.Sign(blsPrivKey, hash.Bytes()) + pubKeyBytes, _ := pubKey.MarshalBinary() + encodedPubKey := hex.EncodeToString(pubKeyBytes) + t.Logf("Encoded Public Key: %s", encodedPubKey) + + encodedSignature := hex.EncodeToString(signature) + t.Logf("Encoded Signature: %s", encodedSignature) + + pubKey2, err := hex.DecodeString(encodedPubKey) + assert.NoError(t, err) + + var pubkey2bytes bls.PublicKey[bls.G1] + if err := pubkey2bytes.UnmarshalBinary(pubKey2); err != nil { + t.Fatalf("error unmarshalling public key: %v", err) + } + + signature2, err := hex.DecodeString(encodedSignature) + + if !bls.Verify[bls.G1](&pubkey2bytes, hash.Bytes(), signature2) { + t.Errorf("Signature verification failed") + } + // return nil, nil + // } + // return input[:48], nil +} func TestWithdrawStakedAmount(t *testing.T) { t.Parallel() From 0eeabbb3d61d367c0d16031478336dffaf9bc879 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 18:29:23 -0500 Subject: [PATCH 17/44] chore: update go mod --- p2p/go.sum | 1 + p2p/pkg/rpc/provider/service_test.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/p2p/go.sum b/p2p/go.sum index 2ab7df191..baf487325 100644 --- a/p2p/go.sum +++ b/p2p/go.sum @@ -53,6 +53,7 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= +github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index 7e947817b..2fe5508e6 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -518,7 +518,7 @@ func TestBLSKeys(t *testing.T) { t.Fatalf("error unmarshalling public key: %v", err) } - signature2, err := hex.DecodeString(encodedSignature) + signature2, _ := hex.DecodeString(encodedSignature) if !bls.Verify[bls.G1](&pubkey2bytes, hash.Bytes(), signature2) { t.Errorf("Signature verification failed") From e530c48423ecc67b6f3e5abfc82e7f13fac41bf9 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 9 Dec 2024 20:18:10 -0500 Subject: [PATCH 18/44] chore: fix stake response encoding --- p2p/pkg/rpc/provider/service.go | 12 ++++++++++-- p2p/pkg/rpc/provider/service_test.go | 10 ++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 3db1adefe..5a30648ae 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -271,7 +271,15 @@ func (s *Service) Stake( } for i, _ := range stake.BlsPublicKeys { - tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, []byte(stake.BlsPublicKeys[i]), []byte(stake.BlsSignatures[i])) + blsPublicKey, err := hex.DecodeString(strings.TrimPrefix(stake.BlsPublicKeys[i], "0x")) + if err != nil { + return nil, status.Errorf(codes.Internal, "decoding bls public key: %v", err) + } + blsSignature, err := hex.DecodeString(strings.TrimPrefix(stake.BlsSignatures[i], "0x")) + if err != nil { + return nil, status.Errorf(codes.Internal, "decoding bls signature: %v", err) + } + tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, blsPublicKey, blsSignature) if txErr != nil { return nil, status.Errorf(codes.Internal, "adding verified bls key: %v", txErr) } @@ -288,7 +296,7 @@ func (s *Service) Stake( for _, log := range receipt.Logs { if blsKeyEvent, err := s.registryContract.ParseBLSKeyAdded(*log); err == nil { s.logger.Info("verified bls key added", "key", blsKeyEvent.BlsPublicKey) - stakeResponse.BlsPublicKeys = append(stakeResponse.BlsPublicKeys, string(blsKeyEvent.BlsPublicKey)) + stakeResponse.BlsPublicKeys = append(stakeResponse.BlsPublicKeys, hex.EncodeToString(blsKeyEvent.BlsPublicKey)) } } } diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index 2fe5508e6..e71d70d46 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -30,10 +30,11 @@ import ( ) type testRegistryContract struct { - stake *big.Int - topup *big.Int - minStake *big.Int - blsKey []byte + stake *big.Int + topup *big.Int + minStake *big.Int + blsKey []byte + blsSignature []byte } func (t *testRegistryContract) ProviderRegistered(opts *bind.CallOpts, address common.Address) (bool, error) { @@ -50,6 +51,7 @@ func (t *testRegistryContract) RegisterAndStake(opts *bind.TransactOpts) (*types func (t *testRegistryContract) AddVerifiedBLSKey(opts *bind.TransactOpts, blsPublicKey []byte, blsSignature []byte) (*types.Transaction, error) { t.blsKey = blsPublicKey + t.blsSignature = blsSignature return types.NewTransaction(1, common.Address{}, nil, 0, nil, nil), nil } From 466d74f6f11f49bd6fd30b2262034f3744c8588d Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 08:45:08 -0500 Subject: [PATCH 19/44] chore: fix e2e test --- contracts/contracts/core/ProviderRegistry.sol | 2 -- p2p/pkg/rpc/provider/service_test.go | 2 +- testing/pkg/tests/staking/staking.go | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 1e1143a47..bfc2de042 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -305,8 +305,6 @@ contract ProviderRegistry is return penaltyFeeTracker.accumulatedAmount; } - - /** * @dev Register and stake function for providers. * The validity of this key must be verified manually off-chain. diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index e71d70d46..b966bda9c 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -500,7 +500,7 @@ func TestBLSKeys(t *testing.T) { pubKey := blsPrivKey.PublicKey() // Keccak the value 0x53c61cfb8128ad59244e8c1d26109252ace23d14 - value := common.Hex2Bytes("53c61cfb8128ad59244e8c1d26109252ace23d14") + value := common.Hex2Bytes("328809Bc894f92807417D2dAD6b7C998c1aFdac6") hash := crypto.Keccak256Hash(value) t.Logf("Keccak hash: %s", hash.Hex()) diff --git a/testing/pkg/tests/staking/staking.go b/testing/pkg/tests/staking/staking.go index f6acab3e1..71c575b5a 100644 --- a/testing/pkg/tests/staking/staking.go +++ b/testing/pkg/tests/staking/staking.go @@ -10,6 +10,7 @@ import ( "math/big" "net/http" "slices" + "strings" "github.com/cloudflare/circl/sign/bls" "github.com/ethereum/go-ethereum/common" @@ -104,7 +105,7 @@ func Run(ctx context.Context, cluster orchestrator.Orchestrator, cfg any) error blsPrivKey, _ := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) pubKey := blsPrivKey.PublicKey() pubKeyBytes, _ := pubKey.MarshalBinary() - value := common.Hex2Bytes(p.EthAddress()) + value := common.Hex2Bytes(strings.TrimPrefix(p.EthAddress(), "0x")) hash := crypto.Keccak256Hash(value) signature := bls.Sign(blsPrivKey, hash.Bytes()) From c7d8110e759bb725194edc4ed093210870f310e9 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 11:45:00 -0500 Subject: [PATCH 20/44] chore: correctly generate message and signature --- p2p/pkg/rpc/provider/service_test.go | 53 ++++++++++------------------ testing/pkg/tests/staking/staking.go | 34 ++++++++++++------ 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index b966bda9c..308fde0ea 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/hex" "errors" + "fmt" "math/big" "net" "os" @@ -23,7 +24,6 @@ import ( providerapiv1 "github.com/primev/mev-commit/p2p/gen/go/providerapi/v1" providerapi "github.com/primev/mev-commit/p2p/pkg/rpc/provider" "github.com/primev/mev-commit/x/util" - "github.com/stretchr/testify/assert" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/test/bufconn" @@ -490,44 +490,27 @@ func TestBidHandling(t *testing.T) { } func TestBLSKeys(t *testing.T) { + // Generate a BLS signature to verify + message := []byte("adb4257612d45f12570533308b20ac77dbfeb85a") + hashedMessage := crypto.Keccak256(message) + ikm := make([]byte, 32) + privateKey, err := bls.KeyGen[bls.G1](ikm, nil, nil) + if err != nil { + t.Fatalf("Failed to generate private key: %v", err) + } + publicKey := privateKey.PublicKey() + signature := bls.Sign(privateKey, hashedMessage) - iv := make([]byte, 32) - _, err := rand.Read(iv) - assert.NoError(t, err) - blsPrivKey, err := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) - assert.NoError(t, err) - - pubKey := blsPrivKey.PublicKey() - - // Keccak the value 0x53c61cfb8128ad59244e8c1d26109252ace23d14 - value := common.Hex2Bytes("328809Bc894f92807417D2dAD6b7C998c1aFdac6") - hash := crypto.Keccak256Hash(value) - t.Logf("Keccak hash: %s", hash.Hex()) - - signature := bls.Sign(blsPrivKey, hash.Bytes()) - pubKeyBytes, _ := pubKey.MarshalBinary() - encodedPubKey := hex.EncodeToString(pubKeyBytes) - t.Logf("Encoded Public Key: %s", encodedPubKey) - - encodedSignature := hex.EncodeToString(signature) - t.Logf("Encoded Signature: %s", encodedSignature) - - pubKey2, err := hex.DecodeString(encodedPubKey) - assert.NoError(t, err) - - var pubkey2bytes bls.PublicKey[bls.G1] - if err := pubkey2bytes.UnmarshalBinary(pubKey2); err != nil { - t.Fatalf("error unmarshalling public key: %v", err) + // Verify the signature + if !bls.Verify(publicKey, hashedMessage, signature) { + t.Fatalf("Failed to verify generated BLS signature") } - signature2, _ := hex.DecodeString(encodedSignature) + pubkeyb, _ := publicKey.MarshalBinary() + fmt.Printf("Public Key: %s\n", common.Bytes2Hex(pubkeyb)) + fmt.Printf("Message: %s\n", common.Bytes2Hex(hashedMessage)) + fmt.Printf("Signature: %s\n", common.Bytes2Hex(signature)) - if !bls.Verify[bls.G1](&pubkey2bytes, hash.Bytes(), signature2) { - t.Errorf("Signature verification failed") - } - // return nil, nil - // } - // return input[:48], nil } func TestWithdrawStakedAmount(t *testing.T) { diff --git a/testing/pkg/tests/staking/staking.go b/testing/pkg/tests/staking/staking.go index 71c575b5a..10c1135bb 100644 --- a/testing/pkg/tests/staking/staking.go +++ b/testing/pkg/tests/staking/staking.go @@ -3,7 +3,6 @@ package staking import ( "bytes" "context" - "crypto/rand" "encoding/hex" "encoding/json" "fmt" @@ -13,7 +12,6 @@ import ( "strings" "github.com/cloudflare/circl/sign/bls" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" providerregistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" providerapiv1 "github.com/primev/mev-commit/p2p/gen/go/providerapi/v1" @@ -99,20 +97,34 @@ func Run(ctx context.Context, cluster orchestrator.Orchestrator, cfg any) error } stakeAmount := big.NewInt(0).Mul(amount, big.NewInt(10)) + // Generate a BLS signature to verify + message := []byte(strings.ToLower(strings.TrimPrefix(p.EthAddress(), "0x"))) + hashedMessage := crypto.Keccak256(message) + ikm := make([]byte, 32) + privateKey, err := bls.KeyGen[bls.G1](ikm, nil, nil) + if err != nil { + l.Error("failed to generate private key", "error", err) + return fmt.Errorf("failed to generate private key: %w", err) + } + publicKey := privateKey.PublicKey() + signature := bls.Sign(privateKey, hashedMessage) + + // Verify the signature + if !bls.Verify(publicKey, hashedMessage, signature) { + l.Error("failed to verify generated BLS signature") + return fmt.Errorf("failed to verify generated BLS signature") + } - iv := make([]byte, 32) - _, _ = rand.Read(iv) - blsPrivKey, _ := bls.KeyGen[bls.G1](iv, []byte{}, []byte{}) - pubKey := blsPrivKey.PublicKey() - pubKeyBytes, _ := pubKey.MarshalBinary() - value := common.Hex2Bytes(strings.TrimPrefix(p.EthAddress(), "0x")) - hash := crypto.Keccak256Hash(value) - signature := bls.Sign(blsPrivKey, hash.Bytes()) + pubkeyb, err := publicKey.MarshalBinary() + if err != nil { + l.Error("failed to marshal public key", "error", err) + return fmt.Errorf("failed to marshal public key: %w", err) + } // Register a provider resp, err := providerAPI.Stake(ctx, &providerapiv1.StakeRequest{ Amount: stakeAmount.String(), - BlsPublicKeys: []string{hex.EncodeToString(pubKeyBytes)}, + BlsPublicKeys: []string{hex.EncodeToString(pubkeyb)}, BlsSignatures: []string{hex.EncodeToString(signature)}, }) From daad545d49767e36ec773e8b35e8acd32501971a Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 11:52:54 -0500 Subject: [PATCH 21/44] chore: fixes lint --- testing/pkg/tests/staking/staking.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/pkg/tests/staking/staking.go b/testing/pkg/tests/staking/staking.go index 10c1135bb..4a88551c4 100644 --- a/testing/pkg/tests/staking/staking.go +++ b/testing/pkg/tests/staking/staking.go @@ -138,7 +138,7 @@ func Run(ctx context.Context, cluster orchestrator.Orchestrator, cfg any) error return fmt.Errorf("invalid stake amount returned: %s", resp.Amount) } - reqBytes, err := json.Marshal([]string{hex.EncodeToString(pubKeyBytes)}) + reqBytes, err := json.Marshal([]string{hex.EncodeToString(pubkeyb)}) if err != nil { l.Error("failed to create bls key upload req", "error", err) return fmt.Errorf("failed to marshal bls keys: %w", err) From 586c66d4134ac013f7547e2663f81d32f8011531 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 12:19:11 -0500 Subject: [PATCH 22/44] chore: correctly format address --- testing/pkg/tests/staking/staking.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/pkg/tests/staking/staking.go b/testing/pkg/tests/staking/staking.go index 4a88551c4..dc6cad199 100644 --- a/testing/pkg/tests/staking/staking.go +++ b/testing/pkg/tests/staking/staking.go @@ -9,9 +9,9 @@ import ( "math/big" "net/http" "slices" - "strings" "github.com/cloudflare/circl/sign/bls" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" providerregistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" providerapiv1 "github.com/primev/mev-commit/p2p/gen/go/providerapi/v1" @@ -98,7 +98,7 @@ func Run(ctx context.Context, cluster orchestrator.Orchestrator, cfg any) error stakeAmount := big.NewInt(0).Mul(amount, big.NewInt(10)) // Generate a BLS signature to verify - message := []byte(strings.ToLower(strings.TrimPrefix(p.EthAddress(), "0x"))) + message := common.HexToAddress(p.EthAddress()).Bytes() hashedMessage := crypto.Keccak256(message) ikm := make([]byte, 32) privateKey, err := bls.KeyGen[bls.G1](ikm, nil, nil) From be870d4320a9890537b0b9cc73b59992b49b3f6c Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 13:32:20 -0500 Subject: [PATCH 23/44] chore: update genesis and runner --- .github/workflows/ci.yml | 6 +++--- .github/workflows/infrastructure.yml | 2 +- infrastructure/nomad/playbooks/deploy.yml | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff9260a1f..f04c65d55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ concurrency: jobs: go-modules: name: Test and Build Go Modules - runs-on: ubuntu-24.04 + runs-on: primev-ci-runner timeout-minutes: 60 steps: @@ -111,7 +111,7 @@ jobs: foundry: name: Foundry Checks and Reports - runs-on: ubuntu-24.04 + runs-on: primev-ci-runner timeout-minutes: 30 defaults: run: @@ -141,7 +141,7 @@ jobs: contracts: name: Test and Build Contracts Scripts - runs-on: ubuntu-24.04 + runs-on: primev-ci-runner timeout-minutes: 30 defaults: run: diff --git a/.github/workflows/infrastructure.yml b/.github/workflows/infrastructure.yml index 8ed49ac08..55dd71882 100644 --- a/.github/workflows/infrastructure.yml +++ b/.github/workflows/infrastructure.yml @@ -50,7 +50,7 @@ concurrency: jobs: cluster: name: Setup and Test Nomad Cluster - runs-on: ubuntu-24.04 + runs-on: primev-ci-runner timeout-minutes: 180 steps: diff --git a/infrastructure/nomad/playbooks/deploy.yml b/infrastructure/nomad/playbooks/deploy.yml index 3240c727f..9e0999af4 100644 --- a/infrastructure/nomad/playbooks/deploy.yml +++ b/infrastructure/nomad/playbooks/deploy.yml @@ -513,6 +513,8 @@ "muirGlacierBlock": 0, "berlinBlock": 0, "londonBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, "arrowGlacierBlock": 0, "grayGlacierBlock": 0, "clique": { From 80485fcd906490b517af7ff0cf77603765c539a3 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 14:33:07 -0500 Subject: [PATCH 24/44] chore: fix location of pre-compile --- infrastructure/nomad/playbooks/deploy.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/infrastructure/nomad/playbooks/deploy.yml b/infrastructure/nomad/playbooks/deploy.yml index 9e0999af4..3240c727f 100644 --- a/infrastructure/nomad/playbooks/deploy.yml +++ b/infrastructure/nomad/playbooks/deploy.yml @@ -513,8 +513,6 @@ "muirGlacierBlock": 0, "berlinBlock": 0, "londonBlock": 0, - "shanghaiTime": 0, - "cancunTime": 0, "arrowGlacierBlock": 0, "grayGlacierBlock": 0, "clique": { From 4243cc74a1c346316e98b96b2d1a219292dc890e Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 14:34:16 -0500 Subject: [PATCH 25/44] chore: bump geth --- external/geth | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/geth b/external/geth index 7cb1fc132..3ad9c82ac 160000 --- a/external/geth +++ b/external/geth @@ -1 +1 @@ -Subproject commit 7cb1fc132d506e294e07ae146576ada50db2e8a4 +Subproject commit 3ad9c82ac152564b6883ed3250144c82516755ff From 79a8a806840c0521bb44b461fa9fb9c1492ac789 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 15:24:15 -0500 Subject: [PATCH 26/44] chore: only set cancun time --- external/geth | 2 +- infrastructure/nomad/playbooks/deploy.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/external/geth b/external/geth index 3ad9c82ac..7cb1fc132 160000 --- a/external/geth +++ b/external/geth @@ -1 +1 @@ -Subproject commit 3ad9c82ac152564b6883ed3250144c82516755ff +Subproject commit 7cb1fc132d506e294e07ae146576ada50db2e8a4 diff --git a/infrastructure/nomad/playbooks/deploy.yml b/infrastructure/nomad/playbooks/deploy.yml index 3240c727f..0e755c6d1 100644 --- a/infrastructure/nomad/playbooks/deploy.yml +++ b/infrastructure/nomad/playbooks/deploy.yml @@ -515,6 +515,7 @@ "londonBlock": 0, "arrowGlacierBlock": 0, "grayGlacierBlock": 0, + "cancunTime": 0, "clique": { "period": 200, "epoch": 30000 From 740722f3ea3dd73c94ef26aca946b8480455548e Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 15:26:41 -0500 Subject: [PATCH 27/44] chore: correctly configure genesis file --- infrastructure/nomad/playbooks/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/infrastructure/nomad/playbooks/deploy.yml b/infrastructure/nomad/playbooks/deploy.yml index 0e755c6d1..240808960 100644 --- a/infrastructure/nomad/playbooks/deploy.yml +++ b/infrastructure/nomad/playbooks/deploy.yml @@ -515,6 +515,7 @@ "londonBlock": 0, "arrowGlacierBlock": 0, "grayGlacierBlock": 0, + "shanghaiTime": 0, "cancunTime": 0, "clique": { "period": 200, From d7c6e3c1e279a699addd689f3e326a6037212f37 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 15:47:07 -0500 Subject: [PATCH 28/44] chore: restrict to only bootnode build --- .../nomad/playbooks/variables/profiles.yml | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/infrastructure/nomad/playbooks/variables/profiles.yml b/infrastructure/nomad/playbooks/variables/profiles.yml index bdaf451ff..6baf255c9 100644 --- a/infrastructure/nomad/playbooks/variables/profiles.yml +++ b/infrastructure/nomad/playbooks/variables/profiles.yml @@ -695,29 +695,29 @@ profiles: devnet: jobs: - - *artifacts_job - - *datadog_agent_logs_collector_job - - *otel_collector_job + # - *artifacts_job + # - *datadog_agent_logs_collector_job + # - *otel_collector_job - *mev_commit_geth_bootnode1_job - - *mev_commit_geth_signer_node1_job - - *mev_commit_geth_member_node_job - - *mock_l1_job - - *l1_transactor_job - - *relay_emulator_job - - *contracts_deployer_job - - *mev_commit_bridge_job - - *bridge_emulator_job - - *mev_commit_dashboard_job - - *mev_commit_bootnode1_job - - *mev_commit_provider_node1_job - - *mev_commit_provider_node1_funder_job - - *mev_commit_oracle_job - - *mev_commit_bidder_node1_job - - *mev_commit_bidder_node1_funder_job - - *mev_commit_provider_emulator_node1_job - - *mev_commit_bidder_emulator_node1_job - - *mev_commit_faucet_job - - *datadog_agent_metrics_collector_job + # - *mev_commit_geth_signer_node1_job + # - *mev_commit_geth_member_node_job + # - *mock_l1_job + # - *l1_transactor_job + # - *relay_emulator_job + # - *contracts_deployer_job + # - *mev_commit_bridge_job + # - *bridge_emulator_job + # - *mev_commit_dashboard_job + # - *mev_commit_bootnode1_job + # - *mev_commit_provider_node1_job + # - *mev_commit_provider_node1_funder_job + # - *mev_commit_oracle_job + # - *mev_commit_bidder_node1_job + # - *mev_commit_bidder_node1_funder_job + # - *mev_commit_provider_emulator_node1_job + # - *mev_commit_bidder_emulator_node1_job + # - *mev_commit_faucet_job + # - *datadog_agent_metrics_collector_job testnet: jobs: From f12e4bf9146dbdea799481346ff91d9c56f63d3c Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 10 Dec 2024 21:52:35 -0500 Subject: [PATCH 29/44] chore: add back signer --- infrastructure/nomad/playbooks/variables/profiles.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/nomad/playbooks/variables/profiles.yml b/infrastructure/nomad/playbooks/variables/profiles.yml index 6baf255c9..8bcc7ec04 100644 --- a/infrastructure/nomad/playbooks/variables/profiles.yml +++ b/infrastructure/nomad/playbooks/variables/profiles.yml @@ -699,7 +699,7 @@ profiles: # - *datadog_agent_logs_collector_job # - *otel_collector_job - *mev_commit_geth_bootnode1_job - # - *mev_commit_geth_signer_node1_job + - *mev_commit_geth_signer_node1_job # - *mev_commit_geth_member_node_job # - *mock_l1_job # - *l1_transactor_job From 125e54bf3c204143c0ecb8b9d0f0b3c7c8af0281 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 11 Dec 2024 11:09:39 -0500 Subject: [PATCH 30/44] chore: adds back all jobs --- .../nomad/playbooks/variables/profiles.yml | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/infrastructure/nomad/playbooks/variables/profiles.yml b/infrastructure/nomad/playbooks/variables/profiles.yml index 8bcc7ec04..bdaf451ff 100644 --- a/infrastructure/nomad/playbooks/variables/profiles.yml +++ b/infrastructure/nomad/playbooks/variables/profiles.yml @@ -695,29 +695,29 @@ profiles: devnet: jobs: - # - *artifacts_job - # - *datadog_agent_logs_collector_job - # - *otel_collector_job + - *artifacts_job + - *datadog_agent_logs_collector_job + - *otel_collector_job - *mev_commit_geth_bootnode1_job - *mev_commit_geth_signer_node1_job - # - *mev_commit_geth_member_node_job - # - *mock_l1_job - # - *l1_transactor_job - # - *relay_emulator_job - # - *contracts_deployer_job - # - *mev_commit_bridge_job - # - *bridge_emulator_job - # - *mev_commit_dashboard_job - # - *mev_commit_bootnode1_job - # - *mev_commit_provider_node1_job - # - *mev_commit_provider_node1_funder_job - # - *mev_commit_oracle_job - # - *mev_commit_bidder_node1_job - # - *mev_commit_bidder_node1_funder_job - # - *mev_commit_provider_emulator_node1_job - # - *mev_commit_bidder_emulator_node1_job - # - *mev_commit_faucet_job - # - *datadog_agent_metrics_collector_job + - *mev_commit_geth_member_node_job + - *mock_l1_job + - *l1_transactor_job + - *relay_emulator_job + - *contracts_deployer_job + - *mev_commit_bridge_job + - *bridge_emulator_job + - *mev_commit_dashboard_job + - *mev_commit_bootnode1_job + - *mev_commit_provider_node1_job + - *mev_commit_provider_node1_funder_job + - *mev_commit_oracle_job + - *mev_commit_bidder_node1_job + - *mev_commit_bidder_node1_funder_job + - *mev_commit_provider_emulator_node1_job + - *mev_commit_bidder_emulator_node1_job + - *mev_commit_faucet_job + - *datadog_agent_metrics_collector_job testnet: jobs: From 70f79db363c27d99752fd78dfbbcfa89ee43df7d Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 11 Dec 2024 13:33:52 -0500 Subject: [PATCH 31/44] feat: bumps geth and revert genesis change --- external/geth | 2 +- infrastructure/nomad/playbooks/deploy.yml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/external/geth b/external/geth index 7cb1fc132..9992ef494 160000 --- a/external/geth +++ b/external/geth @@ -1 +1 @@ -Subproject commit 7cb1fc132d506e294e07ae146576ada50db2e8a4 +Subproject commit 9992ef494e2dd9b6a4e0f2512939e84628b0c6b1 diff --git a/infrastructure/nomad/playbooks/deploy.yml b/infrastructure/nomad/playbooks/deploy.yml index 240808960..3240c727f 100644 --- a/infrastructure/nomad/playbooks/deploy.yml +++ b/infrastructure/nomad/playbooks/deploy.yml @@ -515,8 +515,6 @@ "londonBlock": 0, "arrowGlacierBlock": 0, "grayGlacierBlock": 0, - "shanghaiTime": 0, - "cancunTime": 0, "clique": { "period": 200, "epoch": 30000 From 907cf11a02fd9900fc7ba01e52f22bee3a7a925b Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 11 Dec 2024 14:14:21 -0500 Subject: [PATCH 32/44] chore: don't put any keys in the integeration test cluster --- p2p/integrationtest/provider/client.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/p2p/integrationtest/provider/client.go b/p2p/integrationtest/provider/client.go index 630812858..a01b3a24a 100644 --- a/p2p/integrationtest/provider/client.go +++ b/p2p/integrationtest/provider/client.go @@ -91,7 +91,7 @@ func (b *ProviderClient) Close() error { return b.conn.Close() } -func (b *ProviderClient) CheckAndStake(keys []string) error { +func (b *ProviderClient) CheckAndStake(_ []string) error { stakeAmt, err := b.client.GetStake(context.Background(), &providerapiv1.EmptyMessage{}) if err != nil { b.logger.Error("failed to get stake amount", "err", err) @@ -112,8 +112,7 @@ func (b *ProviderClient) CheckAndStake(keys []string) error { } _, err = b.client.Stake(context.Background(), &providerapiv1.StakeRequest{ - Amount: "10000000000000000000", - BlsPublicKeys: keys, + Amount: "10000000000000000000", }) if err != nil { b.logger.Error("failed to register stake", "err", err) From 9c1586b562faef7c08904d69ced59fc90e9fb8c4 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 11 Dec 2024 14:52:03 -0500 Subject: [PATCH 33/44] feat: adds api call to providers --- p2p/integrationtest/provider/client.go | 43 +++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/p2p/integrationtest/provider/client.go b/p2p/integrationtest/provider/client.go index a01b3a24a..696abb01b 100644 --- a/p2p/integrationtest/provider/client.go +++ b/p2p/integrationtest/provider/client.go @@ -3,11 +3,17 @@ package main import ( "context" "crypto/tls" + "encoding/hex" "errors" + "fmt" "log/slog" "math/big" "time" + "github.com/cloudflare/circl/sign/bls" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + debugapi "github.com/primev/mev-commit/p2p/gen/go/debugapi/v1" providerapiv1 "github.com/primev/mev-commit/p2p/gen/go/providerapi/v1" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" @@ -18,6 +24,7 @@ import ( type ProviderClient struct { conn *grpc.ClientConn client providerapiv1.ProviderClient + debugClient debugapi.DebugServiceClient logger *slog.Logger senderC chan *providerapiv1.BidResponse senderClosed chan struct{} @@ -74,6 +81,7 @@ func NewProviderClient( b := &ProviderClient{ conn: conn, + debugClient: debugapi.NewDebugServiceClient(conn), client: providerapiv1.NewProviderClient(conn), logger: logger, senderC: make(chan *providerapiv1.BidResponse), @@ -98,6 +106,14 @@ func (b *ProviderClient) CheckAndStake(_ []string) error { return err } + topology, err := b.debugClient.GetTopology(context.Background(), &debugapi.EmptyMessage{}) + if err != nil { + b.logger.Error("failed to get topology", "err", err) + return err + } + + ethAddress := topology.GetTopology().Fields["ethAddress"].GetStringValue() + b.logger.Info("stake amount", "stake", stakeAmt.Amount) stakedAmt, set := big.NewInt(0).SetString(stakeAmt.Amount, 10) @@ -111,8 +127,33 @@ func (b *ProviderClient) CheckAndStake(_ []string) error { return nil } + hashedMessage := crypto.Keccak256(common.HexToAddress(ethAddress).Bytes()) + ikm := make([]byte, 32) + privateKey, err := bls.KeyGen[bls.G1](ikm, nil, nil) + if err != nil { + b.logger.Error("failed to generate private key", "error", err) + return fmt.Errorf("failed to generate private key: %w", err) + } + publicKey := privateKey.PublicKey() + signature := bls.Sign(privateKey, hashedMessage) + + // Verify the signature + if !bls.Verify(publicKey, hashedMessage, signature) { + b.logger.Error("failed to verify generated BLS signature") + return fmt.Errorf("failed to verify generated BLS signature") + } + + pubkeyb, err := publicKey.MarshalBinary() + if err != nil { + b.logger.Error("failed to marshal public key", "error", err) + return fmt.Errorf("failed to marshal public key: %w", err) + } + + // Register a provider _, err = b.client.Stake(context.Background(), &providerapiv1.StakeRequest{ - Amount: "10000000000000000000", + Amount: "10000000000000000000", + BlsPublicKeys: []string{hex.EncodeToString(pubkeyb)}, + BlsSignatures: []string{hex.EncodeToString(signature)}, }) if err != nil { b.logger.Error("failed to register stake", "err", err) From b97b6a83be8320fc2c0677ccd7e227d6cd27a33e Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 11 Dec 2024 15:26:37 -0500 Subject: [PATCH 34/44] chore: log ethaddress --- p2p/integrationtest/provider/client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/p2p/integrationtest/provider/client.go b/p2p/integrationtest/provider/client.go index 696abb01b..01bab1b70 100644 --- a/p2p/integrationtest/provider/client.go +++ b/p2p/integrationtest/provider/client.go @@ -116,6 +116,7 @@ func (b *ProviderClient) CheckAndStake(_ []string) error { b.logger.Info("stake amount", "stake", stakeAmt.Amount) + b.logger.Info("eth address", "address", ethAddress) stakedAmt, set := big.NewInt(0).SetString(stakeAmt.Amount, 10) if !set { b.logger.Error("failed to parse stake amount") From cce110f4277e79fd8c0015b0409961c0af10b612 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 11 Dec 2024 15:30:34 -0500 Subject: [PATCH 35/44] chore: add more logs --- p2p/integrationtest/provider/client.go | 3 +++ p2p/pkg/rpc/provider/service.go | 2 ++ 2 files changed, 5 insertions(+) diff --git a/p2p/integrationtest/provider/client.go b/p2p/integrationtest/provider/client.go index 01bab1b70..d7233e858 100644 --- a/p2p/integrationtest/provider/client.go +++ b/p2p/integrationtest/provider/client.go @@ -149,6 +149,9 @@ func (b *ProviderClient) CheckAndStake(_ []string) error { b.logger.Error("failed to marshal public key", "error", err) return fmt.Errorf("failed to marshal public key: %w", err) } + b.logger.Info("generated BLS key pair", + "public_key", hex.EncodeToString(pubkeyb), + "signature", hex.EncodeToString(signature)) // Register a provider _, err = b.client.Stake(context.Background(), &providerapiv1.StakeRequest{ diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 5a30648ae..36035e681 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -279,6 +279,8 @@ func (s *Service) Stake( if err != nil { return nil, status.Errorf(codes.Internal, "decoding bls signature: %v", err) } + + s.logger.Info("adding verified bls key", "blsPublicKey", hex.EncodeToString(blsPublicKey), "blsSignature", hex.EncodeToString(blsSignature)) tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, blsPublicKey, blsSignature) if txErr != nil { return nil, status.Errorf(codes.Internal, "adding verified bls key: %v", txErr) From b9414b03fdcc6647b2d775e25e7ac6dbbb4c386f Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 11 Dec 2024 17:20:32 -0500 Subject: [PATCH 36/44] chore: set eth address --- p2p/integrationtest/provider/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/p2p/integrationtest/provider/client.go b/p2p/integrationtest/provider/client.go index d7233e858..80b21c400 100644 --- a/p2p/integrationtest/provider/client.go +++ b/p2p/integrationtest/provider/client.go @@ -112,7 +112,7 @@ func (b *ProviderClient) CheckAndStake(_ []string) error { return err } - ethAddress := topology.GetTopology().Fields["ethAddress"].GetStringValue() + ethAddress := topology.GetTopology().Fields["self"].GetStructValue().Fields["Ethereum Address"].GetStringValue() b.logger.Info("stake amount", "stake", stakeAmt.Amount) From 06a9cdd600228aafd297cdaaa136533e20e49901 Mon Sep 17 00:00:00 2001 From: aloknerurkar Date: Thu, 12 Dec 2024 21:47:35 +0530 Subject: [PATCH 37/44] fix: txn opts for BLS registration and errors (#531) * chore: add errors to verification * chore: add errors to verification * chore: add errors to verification --------- Co-authored-by: Alok --- contracts/contracts/core/ProviderRegistry.sol | 8 ++++---- contracts/contracts/interfaces/IProviderRegistry.sol | 3 +++ p2p/pkg/rpc/provider/service.go | 5 +++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index bfc2de042..01c062e67 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -245,16 +245,16 @@ contract ProviderRegistry is ) external { address provider = msg.sender; - require(providerRegistered[provider], "Provider not registered"); - require(blsPublicKey.length == 48, "Public key must be 48 bytes"); - require(signature.length == 96, "Signature must be 96 bytes"); + require(providerRegistered[provider], ProviderNotRegistered(provider)); + require(blsPublicKey.length == 48, PublicKeyLengthInvalid(48, blsPublicKey.length)); + require(signature.length == 96, SignatureLengthInvalid(96, signature.length)); bytes32 message = keccak256(abi.encodePacked(provider)); // Verify the BLS signature bool isValid = verifySignature(blsPublicKey, message, signature); - require(isValid, "Invalid BLS signature"); + require(isValid, BLSSignatureInvalid()); // Add the BLS public key to the provider's account eoaToBlsPubkeys[provider].push(blsPublicKey); diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index fc6cc2d9e..e2804081a 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -70,6 +70,9 @@ interface IProviderRegistry { error PendingWithdrawalRequest(address sender); error BidderAmountIsZero(address sender); error BidderWithdrawalTransferFailed(address sender, uint256 amount); + error PublicKeyLengthInvalid(uint256 exp, uint256 got); + error SignatureLengthInvalid(uint256 exp, uint256 got); + error BLSSignatureInvalid(); function registerAndStake() external payable; diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 36035e681..860f27a2a 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -280,6 +280,11 @@ func (s *Service) Stake( return nil, status.Errorf(codes.Internal, "decoding bls signature: %v", err) } + opts, err = s.optsGetter(ctx) + if err != nil { + return nil, status.Errorf(codes.Internal, "getting transact opts for adding BLS key: %v", err) + } + s.logger.Info("adding verified bls key", "blsPublicKey", hex.EncodeToString(blsPublicKey), "blsSignature", hex.EncodeToString(blsSignature)) tx, txErr = s.registryContract.AddVerifiedBLSKey(opts, blsPublicKey, blsSignature) if txErr != nil { From 1fa0d6501728e661c202011f8f4c6995d07ae6a4 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Thu, 12 Dec 2024 12:36:59 -0500 Subject: [PATCH 38/44] chore: bump abigen --- contracts-abi/abi/ProviderRegistry.abi | 37 +++++++++++++++++++ .../ProviderRegistry/ProviderRegistry.go | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/contracts-abi/abi/ProviderRegistry.abi b/contracts-abi/abi/ProviderRegistry.abi index bbc87bc40..3e5fdb8f3 100644 --- a/contracts-abi/abi/ProviderRegistry.abi +++ b/contracts-abi/abi/ProviderRegistry.abi @@ -1107,6 +1107,11 @@ "name": "AtLeastOneBLSKeyRequired", "inputs": [] }, + { + "type": "error", + "name": "BLSSignatureInvalid", + "inputs": [] + }, { "type": "error", "name": "BidderAmountIsZero", @@ -1362,11 +1367,43 @@ } ] }, + { + "type": "error", + "name": "PublicKeyLengthInvalid", + "inputs": [ + { + "name": "exp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "got", + "type": "uint256", + "internalType": "uint256" + } + ] + }, { "type": "error", "name": "ReentrancyGuardReentrantCall", "inputs": [] }, + { + "type": "error", + "name": "SignatureLengthInvalid", + "inputs": [ + { + "name": "exp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "got", + "type": "uint256", + "internalType": "uint256" + } + ] + }, { "type": "error", "name": "StakeTransferFailed", diff --git a/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go b/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go index caa63664a..b1acfcabe 100644 --- a/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go +++ b/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go @@ -31,7 +31,7 @@ var ( // ProviderregistryMetaData contains all meta data concerning the Providerregistry contract. var ProviderregistryMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"ONE_HUNDRED_PERCENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PRECISION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addVerifiedBLSKey\",\"inputs\":[{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bidderSlashedAmount\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blockBuilderBLSKeyToAddress\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delegateRegisterAndStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"delegateStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"eoaToBlsPubkeys\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAccumulatedPenaltyFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBLSKeys\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getEoaFromBLSKey\",\"inputs\":[{\"name\":\"blsKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getProviderStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isProviderValid\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"manuallyWithdrawPenaltyFee\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"minStake\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"overrideAddBLSKey\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"penaltyFeeTracker\",\"inputs\":[],\"outputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"accumulatedAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"lastPayoutBlock\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preconfManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerRegistered\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerStakes\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerAndStake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFeePayoutPeriodBlocks\",\"inputs\":[{\"name\":\"_feePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMinStake\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewPenaltyFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfManager\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelay\",\"inputs\":[{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slash\",\"inputs\":[{\"name\":\"amt\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"residualBidPercentAfterDecay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unstake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifySignature\",\"inputs\":[{\"name\":\"pubKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"message\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSlashedAmount\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawalDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalRequests\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"BLSKeyAdded\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BidderWithdrawSlashedAmount\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePayoutPeriodBlocksUpdated\",\"inputs\":[{\"name\":\"newFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePercentUpdated\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeeTransfer\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsDeposited\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsSlashed\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InsufficientFundsToSlash\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"providerStake\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"residualAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"penaltyFee\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinStakeUpdated\",\"inputs\":[{\"name\":\"newMinStake\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PenaltyFeeRecipientUpdated\",\"inputs\":[{\"name\":\"newPenaltyFeeRecipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PreconfManagerUpdated\",\"inputs\":[{\"name\":\"newPreconfManager\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProviderRegistered\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"stakedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransferToBidderFailed\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unstake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdraw\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayUpdated\",\"inputs\":[{\"name\":\"newWithdrawalDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AtLeastOneBLSKeyRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BidderAmountIsZero\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"BidderWithdrawalTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"DelayNotPassed\",\"inputs\":[{\"name\":\"withdrawalRequestTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"currentBlockTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FeeRecipientIsZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientStake\",\"inputs\":[{\"name\":\"stake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidBLSPublicKeyLength\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedLength\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidFallback\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReceive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoStakeToWithdraw\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NoUnstakeRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotPreconfContract\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"preconfManager\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PayoutPeriodMustBePositive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PendingWithdrawalRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PreconfManagerNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ProviderAlreadyRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ProviderCommitmentsPending\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"numPending\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProviderNotRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StakeTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TransferToRecipientFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"UnstakeRequestExists\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"ONE_HUNDRED_PERCENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PRECISION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addVerifiedBLSKey\",\"inputs\":[{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bidderSlashedAmount\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blockBuilderBLSKeyToAddress\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delegateRegisterAndStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"delegateStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"eoaToBlsPubkeys\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAccumulatedPenaltyFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBLSKeys\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getEoaFromBLSKey\",\"inputs\":[{\"name\":\"blsKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getProviderStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isProviderValid\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"manuallyWithdrawPenaltyFee\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"minStake\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"overrideAddBLSKey\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"penaltyFeeTracker\",\"inputs\":[],\"outputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"accumulatedAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"lastPayoutBlock\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preconfManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerRegistered\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerStakes\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerAndStake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFeePayoutPeriodBlocks\",\"inputs\":[{\"name\":\"_feePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMinStake\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewPenaltyFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfManager\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelay\",\"inputs\":[{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slash\",\"inputs\":[{\"name\":\"amt\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"residualBidPercentAfterDecay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unstake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifySignature\",\"inputs\":[{\"name\":\"pubKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"message\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSlashedAmount\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawalDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalRequests\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"BLSKeyAdded\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BidderWithdrawSlashedAmount\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePayoutPeriodBlocksUpdated\",\"inputs\":[{\"name\":\"newFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeePercentUpdated\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeeTransfer\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsDeposited\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsSlashed\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InsufficientFundsToSlash\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"providerStake\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"residualAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"penaltyFee\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinStakeUpdated\",\"inputs\":[{\"name\":\"newMinStake\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PenaltyFeeRecipientUpdated\",\"inputs\":[{\"name\":\"newPenaltyFeeRecipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PreconfManagerUpdated\",\"inputs\":[{\"name\":\"newPreconfManager\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProviderRegistered\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"stakedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransferToBidderFailed\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unstake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdraw\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayUpdated\",\"inputs\":[{\"name\":\"newWithdrawalDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AtLeastOneBLSKeyRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BLSSignatureInvalid\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BidderAmountIsZero\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"BidderWithdrawalTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"DelayNotPassed\",\"inputs\":[{\"name\":\"withdrawalRequestTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"currentBlockTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FeeRecipientIsZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientStake\",\"inputs\":[{\"name\":\"stake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidBLSPublicKeyLength\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedLength\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidFallback\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReceive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoStakeToWithdraw\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NoUnstakeRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotPreconfContract\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"preconfManager\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PayoutPeriodMustBePositive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PendingWithdrawalRequest\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PreconfManagerNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ProviderAlreadyRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ProviderCommitmentsPending\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"numPending\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProviderNotRegistered\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"PublicKeyLengthInvalid\",\"inputs\":[{\"name\":\"exp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"got\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureLengthInvalid\",\"inputs\":[{\"name\":\"exp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"got\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"StakeTransferFailed\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TransferToRecipientFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"UnstakeRequestExists\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]}]", } // ProviderregistryABI is the input ABI used to generate the binding from. From 704f617ccd07746ef99ed56b4fdd33929de00051 Mon Sep 17 00:00:00 2001 From: mrekucci Date: Thu, 12 Dec 2024 16:42:01 -0300 Subject: [PATCH 39/44] fix: ci runner --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f04c65d55..ff9260a1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ concurrency: jobs: go-modules: name: Test and Build Go Modules - runs-on: primev-ci-runner + runs-on: ubuntu-24.04 timeout-minutes: 60 steps: @@ -111,7 +111,7 @@ jobs: foundry: name: Foundry Checks and Reports - runs-on: primev-ci-runner + runs-on: ubuntu-24.04 timeout-minutes: 30 defaults: run: @@ -141,7 +141,7 @@ jobs: contracts: name: Test and Build Contracts Scripts - runs-on: primev-ci-runner + runs-on: ubuntu-24.04 timeout-minutes: 30 defaults: run: From d139bad10db2eea8a7631dde0ab5898c7215a9b2 Mon Sep 17 00:00:00 2001 From: mrekucci Date: Thu, 12 Dec 2024 17:26:36 -0300 Subject: [PATCH 40/44] fix: test --- contracts/entrypoint.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contracts/entrypoint.sh b/contracts/entrypoint.sh index 6ccfd07c6..41d538a1b 100755 --- a/contracts/entrypoint.sh +++ b/contracts/entrypoint.sh @@ -14,6 +14,12 @@ KEYSTORE_FILENAME=${KEYSTORE_FILENAME:-*} KEYSTORE_PASSWORD=${KEYSTORE_PASSWORD:-"pwd"} CONTRACT_REPO_ROOT_PATH=${CONTRACT_REPO_ROOT_PATH:-$PWD} +set -x + +free -h +ulimit -s unlimited +ulimit -a + if [ -n "${ETHERSCAN_API_KEY}" ]; then VERIFY_OPTION="--verify" fi From cb684168a8aa5ffa3a5e7c415912b1087bccfc44 Mon Sep 17 00:00:00 2001 From: Alok Date: Fri, 13 Dec 2024 15:40:22 +0530 Subject: [PATCH 41/44] chore: test --- .github/workflows/infrastructure.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/infrastructure.yml b/.github/workflows/infrastructure.yml index 55dd71882..8ed49ac08 100644 --- a/.github/workflows/infrastructure.yml +++ b/.github/workflows/infrastructure.yml @@ -50,7 +50,7 @@ concurrency: jobs: cluster: name: Setup and Test Nomad Cluster - runs-on: primev-ci-runner + runs-on: ubuntu-24.04 timeout-minutes: 180 steps: From 48646d7836c7e782e656b71f586f46f4f7af5dc9 Mon Sep 17 00:00:00 2001 From: mrekucci Date: Fri, 13 Dec 2024 10:21:01 -0300 Subject: [PATCH 42/44] fix: remove debug --- contracts/entrypoint.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/contracts/entrypoint.sh b/contracts/entrypoint.sh index 41d538a1b..6ccfd07c6 100755 --- a/contracts/entrypoint.sh +++ b/contracts/entrypoint.sh @@ -14,12 +14,6 @@ KEYSTORE_FILENAME=${KEYSTORE_FILENAME:-*} KEYSTORE_PASSWORD=${KEYSTORE_PASSWORD:-"pwd"} CONTRACT_REPO_ROOT_PATH=${CONTRACT_REPO_ROOT_PATH:-$PWD} -set -x - -free -h -ulimit -s unlimited -ulimit -a - if [ -n "${ETHERSCAN_API_KEY}" ]; then VERIFY_OPTION="--verify" fi From ef22fee11326b43f326a8e8bc00ecb65414d8f19 Mon Sep 17 00:00:00 2001 From: Alok Date: Fri, 13 Dec 2024 18:53:13 +0530 Subject: [PATCH 43/44] chore: fix add stake test --- testing/pkg/tests/staking/staking.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testing/pkg/tests/staking/staking.go b/testing/pkg/tests/staking/staking.go index dc6cad199..5393f072e 100644 --- a/testing/pkg/tests/staking/staking.go +++ b/testing/pkg/tests/staking/staking.go @@ -255,8 +255,7 @@ func RunAddDeposit(ctx context.Context, cluster orchestrator.Orchestrator, _ any // Register a provider resp, err := providerAPI.Stake(ctx, &providerapiv1.StakeRequest{ - Amount: amount.String(), - BlsPublicKeys: getStakeResp.BlsPublicKeys, + Amount: amount.String(), }) if err != nil { l.Error("failed to register stake", "error", err) From 53bab5fb7c8367f12fa6e8aeb99aba92ebd87b78 Mon Sep 17 00:00:00 2001 From: Alok Date: Fri, 13 Dec 2024 19:56:29 +0530 Subject: [PATCH 44/44] chore: fix add stake test --- p2p/gen/go/providerapi/v1/providerapi.pb.go | 668 ++++++++++---------- p2p/pkg/rpc/provider/service.go | 6 + p2p/pkg/rpc/provider/service_test.go | 61 +- p2p/rpc/providerapi/v1/providerapi.proto | 4 +- 4 files changed, 372 insertions(+), 367 deletions(-) diff --git a/p2p/gen/go/providerapi/v1/providerapi.pb.go b/p2p/gen/go/providerapi/v1/providerapi.pb.go index af6d4e524..5cff8e579 100644 --- a/p2p/gen/go/providerapi/v1/providerapi.pb.go +++ b/p2p/gen/go/providerapi/v1/providerapi.pb.go @@ -453,7 +453,7 @@ var file_providerapi_v1_providerapi_proto_rawDesc = []byte{ 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf4, 0x07, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd0, 0x07, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xb2, 0x01, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x01, 0x92, 0x41, 0x3b, 0x32, 0x30, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, @@ -466,356 +466,354 @@ var file_providerapi_v1_providerapi_proto_rawDesc = []byte{ 0x2a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x90, 0x02, 0x0a, 0x0f, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0xe7, 0x01, + 0x75, 0x6e, 0x74, 0x12, 0xfe, 0x01, 0x0a, 0x0f, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0xd5, 0x01, 0x92, 0x41, 0x3b, 0x32, 0x20, 0x42, 0x4c, 0x53, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x8a, 0x01, 0x16, 0x5e, 0x28, 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x39, 0x36, 0x7d, 0x24, 0xba, 0x48, - 0xa5, 0x01, 0xba, 0x01, 0xa1, 0x01, 0x0a, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, + 0x93, 0x01, 0xba, 0x01, 0x8f, 0x01, 0x0a, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x12, 0x4b, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x34, 0x38, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x68, 0x65, 0x78, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x30, 0x78, 0x20, 0x70, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x2e, 0x1a, 0x42, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, - 0x3e, 0x20, 0x30, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, - 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x28, - 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, - 0x39, 0x36, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x0d, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0xa5, 0x02, 0x0a, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, - 0xfd, 0x01, 0x92, 0x41, 0x50, 0x32, 0x34, 0x42, 0x4c, 0x53, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x4c, 0x53, 0x20, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x8a, 0x01, 0x17, 0x5e, 0x28, - 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, - 0x31, 0x39, 0x32, 0x7d, 0x24, 0xba, 0x48, 0xa6, 0x01, 0xba, 0x01, 0xa2, 0x01, 0x0a, 0x0e, 0x62, - 0x6c, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x4b, 0x62, - 0x6c, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x20, 0x6d, 0x75, - 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x39, 0x36, - 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x68, 0x65, 0x78, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, - 0x30, 0x78, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x2e, 0x1a, 0x43, 0x73, 0x69, 0x7a, 0x65, - 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, - 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x28, 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, - 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x31, 0x39, 0x32, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, - 0x0d, 0x62, 0x6c, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x3a, 0xf3, - 0x01, 0x92, 0x41, 0xef, 0x01, 0x0a, 0x53, 0x2a, 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0x28, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, - 0xd2, 0x01, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0xd2, 0x01, 0x0e, 0x62, 0x6c, 0x73, 0x5f, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x32, 0x97, 0x01, 0x7b, 0x22, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, - 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x3a, - 0x20, 0x22, 0x38, 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, - 0x38, 0x30, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, - 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, - 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, - 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, - 0x34, 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, - 0x32, 0x62, 0x22, 0x7d, 0x22, 0x9f, 0x03, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, - 0x0a, 0x0f, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0xcd, 0x02, 0x92, 0x41, 0xc9, 0x02, 0x0a, 0x4a, 0x2a, - 0x0e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, - 0x38, 0x47, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x64, 0x20, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, - 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x32, 0xfa, 0x01, 0x7b, 0x22, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, - 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, - 0x20, 0x5b, 0x22, 0x39, 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, - 0x61, 0x38, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, - 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, - 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, - 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, - 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, - 0x62, 0x22, 0x2c, 0x20, 0x22, 0x38, 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, - 0x36, 0x36, 0x61, 0x38, 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, - 0x66, 0x31, 0x32, 0x32, 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, - 0x39, 0x65, 0x38, 0x31, 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, - 0x38, 0x32, 0x65, 0x34, 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, - 0x39, 0x64, 0x34, 0x34, 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, - 0x38, 0x32, 0x62, 0x22, 0x5d, 0x7d, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x57, 0x69, 0x74, 0x68, 0x64, - 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x77, 0x92, 0x41, 0x74, 0x0a, 0x4f, 0x2a, 0x13, 0x57, 0x69, - 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0x38, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x20, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x32, 0x21, 0x7b, 0x22, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x22, 0x0e, - 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xec, - 0x11, 0x0a, 0x03, 0x42, 0x69, 0x64, 0x12, 0x8f, 0x02, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0xf1, 0x01, 0x92, 0x41, 0x78, - 0x32, 0x64, 0x48, 0x65, 0x78, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x63, - 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, - 0x68, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, - 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x8a, 0x01, 0x0f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, - 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, 0xba, 0x48, 0x73, 0xba, 0x01, 0x70, 0x0a, 0x09, - 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x36, 0x74, 0x78, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, - 0x2e, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, - 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, - 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x08, - 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0xfc, 0x01, 0x0a, 0x0a, 0x62, 0x69, 0x64, - 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xdc, 0x01, - 0x92, 0x41, 0x76, 0x32, 0x6b, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x45, - 0x54, 0x48, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, - 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, - 0x20, 0x70, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, - 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x8a, 0x01, 0x06, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0xba, 0x48, 0x60, 0xba, 0x01, 0x5d, 0x0a, - 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x62, 0x69, 0x64, - 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, - 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, - 0x1a, 0x2a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, - 0x5e, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x75, 0x69, - 0x6e, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x09, 0x62, 0x69, - 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x74, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x51, 0x92, - 0x41, 0x47, 0x32, 0x45, 0x4d, 0x61, 0x78, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, - 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x2e, 0xba, 0x48, 0x04, 0x22, 0x02, 0x20, 0x00, - 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x5c, 0x0a, - 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x42, 0x3d, 0x92, 0x41, 0x31, 0x32, 0x2f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x2e, 0xba, 0x48, 0x06, 0x7a, 0x04, 0x10, 0x01, 0x18, 0x40, - 0x52, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0xc2, 0x01, 0x0a, 0x15, - 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x8d, 0x01, 0x92, 0x41, - 0x2d, 0x32, 0x2b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, - 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x73, 0x20, 0x64, 0x65, 0x63, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, 0x48, - 0x5a, 0xba, 0x01, 0x57, 0x0a, 0x15, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x64, 0x65, 0x63, - 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x0e, 0x75, 0x69, 0x6e, - 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x13, 0x64, 0x65, 0x63, - 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0xb8, 0x01, 0x0a, 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x42, 0x87, - 0x01, 0x92, 0x41, 0x2b, 0x32, 0x29, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, - 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, - 0x20, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x65, 0x63, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, - 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2c, 0x64, 0x65, 0x63, 0x61, - 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, - 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, - 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x0e, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, - 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x11, 0x64, 0x65, 0x63, 0x61, 0x79, 0x45, - 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x8a, 0x02, 0x0a, 0x13, - 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x42, 0xd9, 0x01, 0x92, 0x41, 0x49, 0x32, - 0x47, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, - 0x6f, 0x66, 0x20, 0x74, 0x78, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, - 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x6f, - 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x62, 0x65, 0x20, 0x64, 0x69, - 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x2e, 0xba, 0x48, 0x89, 0x01, 0xba, 0x01, 0x85, 0x01, - 0x0a, 0x13, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x41, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, - 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, + 0x69, 0x78, 0x2e, 0x1a, 0x30, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, + 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x28, 0x30, 0x78, + 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x39, 0x36, + 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x0d, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x73, 0x12, 0x93, 0x02, 0x0a, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0xeb, 0x01, + 0x92, 0x41, 0x50, 0x32, 0x34, 0x42, 0x4c, 0x53, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x4c, 0x53, 0x20, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x8a, 0x01, 0x17, 0x5e, 0x28, 0x30, 0x78, + 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x31, 0x39, + 0x32, 0x7d, 0x24, 0xba, 0x48, 0x94, 0x01, 0xba, 0x01, 0x90, 0x01, 0x0a, 0x0e, 0x62, 0x6c, 0x73, + 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x4b, 0x62, 0x6c, 0x73, + 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, + 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x39, 0x36, 0x2d, 0x62, + 0x79, 0x74, 0x65, 0x20, 0x68, 0x65, 0x78, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x30, 0x78, + 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x2e, 0x1a, 0x31, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, - 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, - 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x11, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, - 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x9d, 0x02, 0x0a, 0x10, 0x72, 0x61, 0x77, - 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, - 0x03, 0x28, 0x09, 0x42, 0xf1, 0x01, 0x92, 0x41, 0x6e, 0x32, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x4c, 0x50, - 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, 0x73, 0x69, 0x67, - 0x6e, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0xba, 0x48, 0x7d, 0xba, 0x01, 0x7a, 0x0a, 0x10, 0x72, - 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x3c, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, - 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x1a, 0x28, 0x74, + 0x27, 0x5e, 0x28, 0x30, 0x78, 0x29, 0x3f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, + 0x39, 0x5d, 0x7b, 0x31, 0x39, 0x32, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x0d, 0x62, 0x6c, 0x73, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x3a, 0xf3, 0x01, 0x92, 0x41, 0xef, + 0x01, 0x0a, 0x53, 0x2a, 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x32, 0x28, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0xd2, 0x01, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0xd2, 0x01, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x32, 0x97, 0x01, 0x7b, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x73, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x38, 0x30, + 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, 0x38, 0x30, 0x30, 0x65, + 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, 0x32, 0x32, 0x39, 0x38, + 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, 0x38, 0x31, 0x32, 0x61, + 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, 0x65, 0x34, 0x38, 0x38, + 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, 0x34, 0x34, 0x34, 0x39, + 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, 0x62, 0x22, 0x7d, + 0x22, 0x9f, 0x03, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6c, + 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x73, 0x3a, 0xcd, 0x02, 0x92, 0x41, 0xc9, 0x02, 0x0a, 0x4a, 0x2a, 0x0e, 0x53, 0x74, 0x61, + 0x6b, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x38, 0x47, 0x65, 0x74, + 0x20, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x64, 0x20, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2e, 0x32, 0xfa, 0x01, 0x7b, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0x3a, 0x20, 0x22, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x73, 0x5f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x39, + 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, 0x38, 0x30, 0x65, + 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, 0x32, 0x32, 0x39, 0x38, + 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, 0x38, 0x31, 0x32, 0x61, + 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, 0x65, 0x34, 0x38, 0x38, + 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, 0x34, 0x34, 0x39, 0x37, + 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, 0x62, 0x22, 0x2c, 0x20, + 0x22, 0x38, 0x30, 0x30, 0x30, 0x30, 0x63, 0x64, 0x64, 0x65, 0x65, 0x63, 0x36, 0x36, 0x61, 0x38, + 0x30, 0x65, 0x30, 0x30, 0x62, 0x30, 0x63, 0x63, 0x62, 0x62, 0x36, 0x32, 0x66, 0x31, 0x32, 0x32, + 0x39, 0x38, 0x30, 0x37, 0x33, 0x36, 0x30, 0x33, 0x66, 0x35, 0x32, 0x30, 0x39, 0x65, 0x38, 0x31, + 0x32, 0x61, 0x62, 0x62, 0x61, 0x63, 0x37, 0x65, 0x38, 0x37, 0x30, 0x34, 0x38, 0x32, 0x65, 0x34, + 0x38, 0x38, 0x64, 0x64, 0x31, 0x62, 0x62, 0x65, 0x35, 0x33, 0x33, 0x61, 0x39, 0x64, 0x34, 0x34, + 0x39, 0x37, 0x62, 0x61, 0x38, 0x62, 0x37, 0x35, 0x36, 0x65, 0x31, 0x65, 0x38, 0x32, 0x62, 0x22, + 0x5d, 0x7d, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x3a, 0x77, 0x92, 0x41, 0x74, 0x0a, 0x4f, 0x2a, 0x13, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, + 0x61, 0x77, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x38, 0x57, + 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x20, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x32, 0x21, 0x7b, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x22, 0x0e, 0x0a, 0x0c, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xec, 0x11, 0x0a, 0x03, 0x42, + 0x69, 0x64, 0x12, 0x8f, 0x02, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0xf1, 0x01, 0x92, 0x41, 0x78, 0x32, 0x64, 0x48, 0x65, + 0x78, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, + 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x8a, 0x01, 0x0f, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, + 0x7b, 0x36, 0x34, 0x7d, 0xba, 0x48, 0x73, 0xba, 0x01, 0x70, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x36, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, - 0x39, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x29, 0x52, 0x0f, 0x72, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0xd2, 0x04, 0x92, 0x41, 0xce, 0x04, 0x0a, - 0x70, 0x2a, 0x0b, 0x42, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x30, - 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x73, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, - 0xd2, 0x01, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0xd2, 0x01, 0x09, 0x62, 0x69, - 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0xd2, 0x01, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, - 0x74, 0x32, 0xd9, 0x03, 0x7b, 0x22, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x3a, - 0x20, 0x5b, 0x22, 0x66, 0x65, 0x34, 0x63, 0x62, 0x34, 0x37, 0x64, 0x62, 0x33, 0x36, 0x33, 0x30, - 0x35, 0x35, 0x31, 0x62, 0x65, 0x65, 0x64, 0x66, 0x62, 0x64, 0x30, 0x32, 0x61, 0x37, 0x31, 0x65, - 0x63, 0x63, 0x36, 0x39, 0x66, 0x64, 0x35, 0x39, 0x37, 0x35, 0x38, 0x65, 0x32, 0x62, 0x61, 0x36, - 0x39, 0x39, 0x36, 0x30, 0x36, 0x65, 0x32, 0x64, 0x35, 0x63, 0x37, 0x34, 0x32, 0x38, 0x34, 0x66, - 0x66, 0x61, 0x37, 0x22, 0x2c, 0x20, 0x22, 0x37, 0x31, 0x63, 0x31, 0x33, 0x34, 0x38, 0x66, 0x32, - 0x64, 0x37, 0x66, 0x66, 0x37, 0x65, 0x38, 0x31, 0x34, 0x66, 0x39, 0x63, 0x33, 0x36, 0x31, 0x37, - 0x39, 0x38, 0x33, 0x37, 0x30, 0x33, 0x34, 0x33, 0x35, 0x65, 0x61, 0x37, 0x34, 0x34, 0x36, 0x64, - 0x65, 0x34, 0x32, 0x30, 0x61, 0x65, 0x61, 0x63, 0x34, 0x38, 0x38, 0x62, 0x66, 0x31, 0x64, 0x65, - 0x33, 0x35, 0x37, 0x33, 0x37, 0x65, 0x38, 0x22, 0x5d, 0x2c, 0x20, 0x22, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, - 0x36, 0x2c, 0x20, 0x22, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, - 0x22, 0x39, 0x64, 0x4a, 0x69, 0x6e, 0x77, 0x4c, 0x2b, 0x46, 0x5a, 0x36, 0x42, 0x31, 0x78, 0x73, - 0x49, 0x51, 0x51, 0x6f, 0x38, 0x74, 0x38, 0x42, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x62, 0x4a, 0x77, - 0x59, 0x38, 0x36, 0x6c, 0x2f, 0x59, 0x75, 0x37, 0x79, 0x41, 0x48, 0x31, 0x35, 0x39, 0x51, 0x72, - 0x50, 0x48, 0x55, 0x30, 0x71, 0x6a, 0x32, 0x50, 0x2b, 0x59, 0x46, 0x6a, 0x2b, 0x6c, 0x6c, 0x62, - 0x75, 0x49, 0x31, 0x5a, 0x79, 0x67, 0x64, 0x78, 0x47, 0x73, 0x58, 0x38, 0x2b, 0x50, 0x33, 0x62, - 0x79, 0x4d, 0x45, 0x41, 0x35, 0x69, 0x67, 0x3d, 0x3d, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, - 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x22, 0x3a, 0x31, 0x37, 0x32, 0x35, 0x33, 0x36, 0x35, 0x33, 0x30, 0x31, 0x30, 0x30, 0x30, 0x2c, - 0x20, 0x22, 0x64, 0x65, 0x63, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x31, 0x37, 0x32, 0x35, 0x33, 0x36, 0x35, 0x33, 0x30, 0x32, 0x30, - 0x30, 0x30, 0x2c, 0x20, 0x22, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x78, - 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x66, 0x65, 0x34, 0x63, 0x62, 0x34, - 0x37, 0x64, 0x62, 0x33, 0x36, 0x33, 0x30, 0x35, 0x35, 0x31, 0x62, 0x65, 0x65, 0x64, 0x66, 0x62, - 0x64, 0x30, 0x32, 0x61, 0x37, 0x31, 0x65, 0x63, 0x63, 0x36, 0x39, 0x66, 0x64, 0x35, 0x39, 0x37, - 0x35, 0x38, 0x65, 0x32, 0x62, 0x61, 0x36, 0x39, 0x39, 0x36, 0x30, 0x36, 0x65, 0x32, 0x64, 0x35, - 0x63, 0x37, 0x34, 0x32, 0x38, 0x34, 0x66, 0x66, 0x61, 0x37, 0x22, 0x5d, 0x7d, 0x22, 0x81, 0x06, - 0x0a, 0x0b, 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, - 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x42, 0x34, 0x92, 0x41, 0x31, 0x32, 0x2f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x23, 0x92, 0x41, 0x14, 0x32, 0x12, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x2e, 0xba, - 0x48, 0x09, 0x82, 0x01, 0x06, 0x10, 0x01, 0x1a, 0x02, 0x01, 0x02, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0xb4, 0x01, 0x0a, 0x12, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x42, 0x84, 0x01, 0x92, 0x41, 0x80, 0x01, 0x32, 0x7e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, - 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, - 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x20, 0x66, - 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, - 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, - 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x3a, 0xb8, 0x02, 0x92, 0x41, 0xb4, 0x02, 0x0a, 0x82, 0x01, - 0x2a, 0x0c, 0x42, 0x69, 0x64, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x44, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, - 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, - 0x76, 0x65, 0x64, 0x2e, 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, - 0xd2, 0x01, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0xd2, 0x01, 0x16, 0x64, 0x65, 0x63, 0x61, - 0x79, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x32, 0xac, 0x01, 0x7b, 0x22, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, - 0x22, 0x3a, 0x20, 0x22, 0x39, 0x64, 0x4a, 0x69, 0x6e, 0x77, 0x4c, 0x2b, 0x46, 0x5a, 0x36, 0x42, - 0x31, 0x78, 0x73, 0x49, 0x51, 0x51, 0x6f, 0x38, 0x74, 0x38, 0x42, 0x30, 0x5a, 0x58, 0x4a, 0x75, - 0x62, 0x4a, 0x77, 0x59, 0x38, 0x36, 0x6c, 0x2f, 0x59, 0x75, 0x37, 0x79, 0x41, 0x48, 0x31, 0x35, - 0x39, 0x51, 0x72, 0x50, 0x48, 0x55, 0x30, 0x71, 0x6a, 0x32, 0x50, 0x2b, 0x59, 0x46, 0x6a, 0x2b, - 0x6c, 0x6c, 0x62, 0x75, 0x49, 0x31, 0x5a, 0x79, 0x67, 0x64, 0x78, 0x47, 0x73, 0x58, 0x38, 0x2b, - 0x50, 0x33, 0x62, 0x79, 0x4d, 0x45, 0x41, 0x35, 0x69, 0x67, 0x3d, 0x3d, 0x22, 0x2c, 0x20, 0x22, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3a, 0x20, 0x22, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, - 0x61, 0x79, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, - 0x7d, 0x32, 0x91, 0x06, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, - 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x42, 0x69, 0x64, 0x73, 0x12, 0x1c, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x13, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, - 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x62, - 0x69, 0x64, 0x73, 0x30, 0x01, 0x12, 0x7d, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x42, 0x69, 0x64, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, - 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x73, - 0x65, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x69, - 0x64, 0x73, 0x28, 0x01, 0x12, 0x69, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, - 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x2f, 0x7b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x12, - 0x67, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, 0x24, 0x27, 0x29, 0x29, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x12, 0xfc, 0x01, 0x0a, 0x0a, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xdc, 0x01, 0x92, 0x41, 0x76, 0x32, + 0x6b, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x45, 0x54, 0x48, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x20, 0x69, + 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x61, 0x79, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x8a, 0x01, 0x06, 0x5b, + 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0xba, 0x48, 0x60, 0xba, 0x01, 0x5d, 0x0a, 0x0a, 0x62, 0x69, 0x64, + 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x2a, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x30, 0x2d, + 0x39, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x74, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x51, 0x92, 0x41, 0x47, 0x32, 0x45, + 0x4d, 0x61, 0x78, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, + 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x69, 0x6e, 0x2e, 0xba, 0x48, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, 0x0b, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x5c, 0x0a, 0x0a, 0x62, 0x69, 0x64, + 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x3d, 0x92, + 0x41, 0x31, 0x32, 0x2f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, + 0x65, 0x72, 0x2e, 0xba, 0x48, 0x06, 0x7a, 0x04, 0x10, 0x01, 0x18, 0x40, 0x52, 0x09, 0x62, 0x69, + 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0xc2, 0x01, 0x0a, 0x15, 0x64, 0x65, 0x63, 0x61, + 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x8d, 0x01, 0x92, 0x41, 0x2d, 0x32, 0x2b, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, + 0x20, 0x64, 0x65, 0x63, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, 0x48, 0x5a, 0xba, 0x01, 0x57, + 0x0a, 0x15, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x0e, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0xb8, 0x01, 0x0a, + 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x42, 0x87, 0x01, 0x92, 0x41, 0x2b, + 0x32, 0x29, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, 0x74, 0x20, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x65, 0x6e, 0x64, + 0x73, 0x20, 0x64, 0x65, 0x63, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x2e, 0xba, 0x48, 0x56, 0xba, 0x01, + 0x53, 0x0a, 0x13, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2c, 0x64, 0x65, 0x63, 0x61, 0x79, 0x5f, 0x65, 0x6e, + 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x6d, 0x75, 0x73, 0x74, + 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x65, 0x72, 0x2e, 0x1a, 0x0e, 0x75, 0x69, 0x6e, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x20, 0x3e, 0x20, 0x30, 0x52, 0x11, 0x64, 0x65, 0x63, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x8a, 0x02, 0x0a, 0x13, 0x72, 0x65, 0x76, 0x65, + 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x42, 0xd9, 0x01, 0x92, 0x41, 0x49, 0x32, 0x47, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x78, 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x76, + 0x65, 0x72, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x62, 0x65, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, + 0x64, 0x65, 0x64, 0x2e, 0xba, 0x48, 0x89, 0x01, 0xba, 0x01, 0x85, 0x01, 0x0a, 0x13, 0x72, 0x65, + 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, + 0x73, 0x12, 0x41, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, + 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x73, + 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, 0x72, + 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, + 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x36, 0x34, 0x7d, 0x24, 0x27, 0x29, + 0x29, 0x52, 0x11, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x78, 0x48, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x12, 0x9d, 0x02, 0x0a, 0x10, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x42, + 0xf1, 0x01, 0x92, 0x41, 0x6e, 0x32, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x4c, 0x50, 0x20, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, + 0x64, 0x64, 0x65, 0x72, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0xba, 0x48, 0x7d, 0xba, 0x01, 0x7a, 0x0a, 0x10, 0x72, 0x61, 0x77, 0x5f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x72, 0x61, 0x77, + 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, + 0x66, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x1a, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, + 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, + 0x27, 0x29, 0x29, 0x52, 0x0f, 0x72, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0xd2, 0x04, 0x92, 0x41, 0xce, 0x04, 0x0a, 0x70, 0x2a, 0x0b, 0x42, + 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x30, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x62, 0x69, 0x64, 0x64, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0xd2, 0x01, 0x08, 0x74, + 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0xd2, 0x01, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x32, 0xd9, 0x03, + 0x7b, 0x22, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x66, + 0x65, 0x34, 0x63, 0x62, 0x34, 0x37, 0x64, 0x62, 0x33, 0x36, 0x33, 0x30, 0x35, 0x35, 0x31, 0x62, + 0x65, 0x65, 0x64, 0x66, 0x62, 0x64, 0x30, 0x32, 0x61, 0x37, 0x31, 0x65, 0x63, 0x63, 0x36, 0x39, + 0x66, 0x64, 0x35, 0x39, 0x37, 0x35, 0x38, 0x65, 0x32, 0x62, 0x61, 0x36, 0x39, 0x39, 0x36, 0x30, + 0x36, 0x65, 0x32, 0x64, 0x35, 0x63, 0x37, 0x34, 0x32, 0x38, 0x34, 0x66, 0x66, 0x61, 0x37, 0x22, + 0x2c, 0x20, 0x22, 0x37, 0x31, 0x63, 0x31, 0x33, 0x34, 0x38, 0x66, 0x32, 0x64, 0x37, 0x66, 0x66, + 0x37, 0x65, 0x38, 0x31, 0x34, 0x66, 0x39, 0x63, 0x33, 0x36, 0x31, 0x37, 0x39, 0x38, 0x33, 0x37, + 0x30, 0x33, 0x34, 0x33, 0x35, 0x65, 0x61, 0x37, 0x34, 0x34, 0x36, 0x64, 0x65, 0x34, 0x32, 0x30, + 0x61, 0x65, 0x61, 0x63, 0x34, 0x38, 0x38, 0x62, 0x66, 0x31, 0x64, 0x65, 0x33, 0x35, 0x37, 0x33, + 0x37, 0x65, 0x38, 0x22, 0x5d, 0x2c, 0x20, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, + 0x20, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x2c, 0x20, 0x22, + 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x39, 0x64, 0x4a, + 0x69, 0x6e, 0x77, 0x4c, 0x2b, 0x46, 0x5a, 0x36, 0x42, 0x31, 0x78, 0x73, 0x49, 0x51, 0x51, 0x6f, + 0x38, 0x74, 0x38, 0x42, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x62, 0x4a, 0x77, 0x59, 0x38, 0x36, 0x6c, + 0x2f, 0x59, 0x75, 0x37, 0x79, 0x41, 0x48, 0x31, 0x35, 0x39, 0x51, 0x72, 0x50, 0x48, 0x55, 0x30, + 0x71, 0x6a, 0x32, 0x50, 0x2b, 0x59, 0x46, 0x6a, 0x2b, 0x6c, 0x6c, 0x62, 0x75, 0x49, 0x31, 0x5a, + 0x79, 0x67, 0x64, 0x78, 0x47, 0x73, 0x58, 0x38, 0x2b, 0x50, 0x33, 0x62, 0x79, 0x4d, 0x45, 0x41, + 0x35, 0x69, 0x67, 0x3d, 0x3d, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, 0x61, 0x79, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x31, 0x37, + 0x32, 0x35, 0x33, 0x36, 0x35, 0x33, 0x30, 0x31, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x22, 0x64, 0x65, + 0x63, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, + 0x3a, 0x31, 0x37, 0x32, 0x35, 0x33, 0x36, 0x35, 0x33, 0x30, 0x32, 0x30, 0x30, 0x30, 0x2c, 0x20, + 0x22, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x66, 0x65, 0x34, 0x63, 0x62, 0x34, 0x37, 0x64, 0x62, 0x33, + 0x36, 0x33, 0x30, 0x35, 0x35, 0x31, 0x62, 0x65, 0x65, 0x64, 0x66, 0x62, 0x64, 0x30, 0x32, 0x61, + 0x37, 0x31, 0x65, 0x63, 0x63, 0x36, 0x39, 0x66, 0x64, 0x35, 0x39, 0x37, 0x35, 0x38, 0x65, 0x32, + 0x62, 0x61, 0x36, 0x39, 0x39, 0x36, 0x30, 0x36, 0x65, 0x32, 0x64, 0x35, 0x63, 0x37, 0x34, 0x32, + 0x38, 0x34, 0x66, 0x66, 0x61, 0x37, 0x22, 0x5d, 0x7d, 0x22, 0x81, 0x06, 0x0a, 0x0b, 0x42, 0x69, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0a, 0x62, 0x69, 0x64, + 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x34, 0x92, + 0x41, 0x31, 0x32, 0x2f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x64, + 0x65, 0x72, 0x2e, 0x52, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x5f, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x42, 0x23, 0x92, 0x41, 0x14, 0x32, 0x12, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x2e, 0xba, 0x48, 0x09, 0x82, 0x01, + 0x06, 0x10, 0x01, 0x1a, 0x02, 0x01, 0x02, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0xb4, 0x01, 0x0a, 0x12, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x84, 0x01, 0x92, + 0x41, 0x80, 0x01, 0x32, 0x7e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x61, + 0x74, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, + 0x6d, 0x70, 0x75, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, + 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x10, 0x02, 0x3a, 0xb8, 0x02, 0x92, 0x41, 0xb4, 0x02, 0x0a, 0x82, 0x01, 0x2a, 0x0c, 0x42, 0x69, + 0x64, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x44, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x62, 0x69, 0x64, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x2e, + 0xd2, 0x01, 0x09, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0xd2, 0x01, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0xd2, 0x01, 0x16, 0x64, 0x65, 0x63, 0x61, 0x79, 0x44, 0x69, 0x73, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x32, 0xac, + 0x01, 0x7b, 0x22, 0x62, 0x69, 0x64, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, + 0x39, 0x64, 0x4a, 0x69, 0x6e, 0x77, 0x4c, 0x2b, 0x46, 0x5a, 0x36, 0x42, 0x31, 0x78, 0x73, 0x49, + 0x51, 0x51, 0x6f, 0x38, 0x74, 0x38, 0x42, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x62, 0x4a, 0x77, 0x59, + 0x38, 0x36, 0x6c, 0x2f, 0x59, 0x75, 0x37, 0x79, 0x41, 0x48, 0x31, 0x35, 0x39, 0x51, 0x72, 0x50, + 0x48, 0x55, 0x30, 0x71, 0x6a, 0x32, 0x50, 0x2b, 0x59, 0x46, 0x6a, 0x2b, 0x6c, 0x6c, 0x62, 0x75, + 0x49, 0x31, 0x5a, 0x79, 0x67, 0x64, 0x78, 0x47, 0x73, 0x58, 0x38, 0x2b, 0x50, 0x33, 0x62, 0x79, + 0x4d, 0x45, 0x41, 0x35, 0x69, 0x67, 0x3d, 0x3d, 0x22, 0x2c, 0x20, 0x22, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x3a, 0x20, 0x22, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, + 0x45, 0x50, 0x54, 0x45, 0x44, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x63, 0x61, 0x79, 0x44, 0x69, + 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, + 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x7d, 0x32, 0x91, 0x06, + 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x65, 0x0a, 0x0b, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x42, 0x69, 0x64, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x22, 0x21, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x69, 0x64, 0x73, 0x30, + 0x01, 0x12, 0x7d, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x42, 0x69, 0x64, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, + 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x5f, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x64, 0x73, 0x28, 0x01, + 0x12, 0x69, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, - 0x12, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x67, - 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x6e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, - 0x69, 0x6e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x1b, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x61, + 0x6b, 0x65, 0x2f, 0x7b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x12, 0x67, 0x0a, 0x08, 0x47, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, - 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x6d, - 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x76, 0x0a, 0x0d, 0x57, 0x69, 0x74, 0x68, - 0x64, 0x72, 0x61, 0x77, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, - 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, - 0x12, 0x63, 0x0a, 0x07, 0x55, 0x6e, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, - 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x75, 0x6e, - 0x73, 0x74, 0x61, 0x6b, 0x65, 0x42, 0xbc, 0x02, 0x92, 0x41, 0x74, 0x12, 0x72, 0x0a, 0x0c, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x2a, 0x55, 0x0a, 0x1b, 0x42, - 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x4c, - 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x31, 0x2e, 0x31, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, - 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, - 0x72, 0x69, 0x6d, 0x65, 0x76, 0x2f, 0x6d, 0x65, 0x76, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, - 0x53, 0x45, 0x32, 0x0b, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x0a, - 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x42, 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x76, 0x2f, 0x6d, 0x65, 0x76, 0x2d, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, - 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x76, 0x31, 0xa2, 0x02, 0x03, - 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, - 0x69, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, - 0x70, 0x69, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x61, 0x70, 0x69, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x76, + 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x73, + 0x74, 0x61, 0x6b, 0x65, 0x12, 0x6e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x53, 0x74, + 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x73, + 0x74, 0x61, 0x6b, 0x65, 0x12, 0x76, 0x0a, 0x0d, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, + 0x53, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, + 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x77, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x63, 0x0a, 0x07, + 0x55, 0x6e, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x76, 0x31, + 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x6b, + 0x65, 0x42, 0xbc, 0x02, 0x92, 0x41, 0x74, 0x12, 0x72, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x2a, 0x55, 0x0a, 0x1b, 0x42, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x20, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x20, 0x31, 0x2e, 0x31, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x65, + 0x76, 0x2f, 0x6d, 0x65, 0x76, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2f, 0x62, 0x6c, 0x6f, + 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x0b, + 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x0a, 0x12, 0x63, 0x6f, 0x6d, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x42, + 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x70, 0x72, 0x69, 0x6d, 0x65, 0x76, 0x2f, 0x6d, 0x65, 0x76, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, + 0x02, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x31, + 0xca, 0x02, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x5c, + 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x0f, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x61, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index 860f27a2a..e86bbc58c 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -240,6 +240,12 @@ func (s *Service) Stake( } if !registered { + if len(stake.BlsPublicKeys) == 0 { + return nil, status.Error(codes.InvalidArgument, "missing BLS keys") + } + if len(stake.BlsSignatures) == 0 { + return nil, status.Error(codes.InvalidArgument, "missing BLS signatures") + } tx, txErr = s.registryContract.RegisterAndStake(opts) } else { tx, txErr = s.registryContract.Stake(opts) diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index 308fde0ea..a4c127449 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -208,18 +208,16 @@ func TestStakeHandling(t *testing.T) { validSignature := "bbbbbbbbb1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" t.Run("register stake", func(t *testing.T) { type testCase struct { - amount string - blsPublicKey string - blsSignature string - err string + amount string + blsPublicKeys []string + blsSignatures []string + err string } for _, tc := range []testCase{ { - amount: "", - blsPublicKey: "", - blsSignature: "", - err: "amount must be a valid integer", + amount: "", + err: "amount must be a valid integer", }, { amount: "0000000000000000000", @@ -230,36 +228,39 @@ func TestStakeHandling(t *testing.T) { err: "amount must be a valid integer", }, { - amount: "1000000000000000000", - blsPublicKey: "0x", - err: "bls_public_key must be a valid 48-byte hex string, with optional 0x prefix.", + amount: "1000000000000000000", + blsPublicKeys: []string{"0x"}, + err: "bls_public_key must be a valid 48-byte hex string, with optional 0x prefix.", }, { - amount: "1000000000000000000", - blsPublicKey: "0x12345", - err: "bls_public_key must be a valid 48-byte hex string, with optional 0x prefix.", + amount: "1000000000000000000", + blsPublicKeys: []string{"0x12345"}, + err: "bls_public_key must be a valid 48-byte hex string, with optional 0x prefix.", }, { - amount: "1000000000000000000", - blsPublicKey: validBLSKey, - blsSignature: "", - err: "bls_signatures must be a valid 96-byte hex string, with optional 0x prefix.", + amount: "1000000000000000000", + blsPublicKeys: []string{validBLSKey}, + err: "missing BLS signatures", }, { - amount: "1000000000000000000", - blsPublicKey: validBLSKey, - blsSignature: validSignature, - err: "", + amount: "1000000000000000000", + blsPublicKeys: []string{validBLSKey}, + blsSignatures: []string{validSignature}, + err: "", }, { - amount: "1000000000000000000", - blsPublicKey: validBLSKey, - blsSignature: validSignature, - err: "", + amount: "1000000000000000000", + err: "", }, } { - stake, err := client.Stake(context.Background(), - &providerapiv1.StakeRequest{Amount: tc.amount, BlsPublicKeys: []string{tc.blsPublicKey}, BlsSignatures: []string{tc.blsSignature}}) + stake, err := client.Stake( + context.Background(), + &providerapiv1.StakeRequest{ + Amount: tc.amount, + BlsPublicKeys: tc.blsPublicKeys, + BlsSignatures: tc.blsSignatures, + }, + ) if tc.err != "" { if err == nil || !strings.Contains(err.Error(), tc.err) { t.Fatalf("expected error staking: %s got %v", tc.err, err) @@ -271,8 +272,8 @@ func TestStakeHandling(t *testing.T) { if stake.Amount != tc.amount { t.Fatalf("expected amount to be %v, got %v", tc.amount, stake.Amount) } - if stake.BlsPublicKeys[0] != tc.blsPublicKey { - t.Fatalf("expected bls_public_key to be %v, got %v", tc.blsPublicKey, stake.BlsPublicKeys[0]) + if len(tc.blsPublicKeys) > 0 && stake.BlsPublicKeys[0] != tc.blsPublicKeys[0] { + t.Fatalf("expected bls_public_key to be %v, got %v", tc.blsPublicKeys[0], stake.BlsPublicKeys[0]) } } } diff --git a/p2p/rpc/providerapi/v1/providerapi.proto b/p2p/rpc/providerapi/v1/providerapi.proto index 0b1559ad9..3f168b986 100644 --- a/p2p/rpc/providerapi/v1/providerapi.proto +++ b/p2p/rpc/providerapi/v1/providerapi.proto @@ -92,7 +92,7 @@ message StakeRequest { }, (buf.validate.field).cel = { id: "bls_public_key", message: "bls_public_key must be a valid 48-byte hex string, with optional 0x prefix.", - expression: "size(this) > 0 && this.all(r, r.matches('^(0x)?[a-fA-F0-9]{96}$'))" + expression: "this.all(r, r.matches('^(0x)?[a-fA-F0-9]{96}$'))" }]; repeated string bls_signatures = 3 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { description: "BLS signatures corresponding to the BLS public keys." @@ -100,7 +100,7 @@ message StakeRequest { }, (buf.validate.field).cel = { id: "bls_signatures", message: "bls_signatures must be a valid 96-byte hex string, with optional 0x prefix.", - expression: "size(this) > 0 && this.all(r, r.matches('^(0x)?[a-fA-F0-9]{192}$'))" + expression: "this.all(r, r.matches('^(0x)?[a-fA-F0-9]{192}$'))" }]; };