diff --git a/contracts-abi/abi/ProviderRegistry.abi b/contracts-abi/abi/ProviderRegistry.abi index c08b651bc..6c573ef06 100644 --- a/contracts-abi/abi/ProviderRegistry.abi +++ b/contracts-abi/abi/ProviderRegistry.abi @@ -12,6 +12,51 @@ "type": "receive", "stateMutability": "payable" }, + { + "type": "function", + "name": "EOAToBLSPubkey", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "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", @@ -109,6 +154,25 @@ ], "stateMutability": "view" }, + { + "type": "function", + "name": "getBLSKey", + "inputs": [ + { + "name": "provider", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, { "type": "function", "name": "initialize", @@ -230,7 +294,13 @@ { "type": "function", "name": "registerAndStake", - "inputs": [], + "inputs": [ + { + "name": "blsPublicKey", + "type": "bytes", + "internalType": "bytes" + } + ], "outputs": [], "stateMutability": "payable" }, @@ -457,6 +527,12 @@ "type": "uint256", "indexed": false, "internalType": "uint256" + }, + { + "name": "blsPublicKey", + "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 27ea18f9b..22c3b5510 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\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bidderAmount\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"depositFunds\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feeRecipient\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feeRecipientAmount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_feeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"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\":\"preConfirmationsContract\",\"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\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfirmationsContract\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"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\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"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\":\"withdrawBidderAmount\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawFeeRecipientAmount\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawStakedAmount\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"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\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"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\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"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\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"EOAToBLSPubkey\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"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\":\"bidderAmount\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"depositFunds\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feeRecipient\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feeRecipientAmount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBLSKey\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_feeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"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\":\"preConfirmationsContract\",\"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\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfirmationsContract\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"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\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"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\":\"withdrawBidderAmount\",\"inputs\":[{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawFeeRecipientAmount\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawStakedAmount\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"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\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"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\":\"blsPublicKey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"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\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", } // ProviderregistryABI is the input ABI used to generate the binding from. @@ -180,6 +180,99 @@ func (_Providerregistry *ProviderregistryTransactorRaw) Transact(opts *bind.Tran return _Providerregistry.Contract.contract.Transact(opts, method, params...) } +// EOAToBLSPubkey is a free data retrieval call binding the contract method 0xc7cae7fc. +// +// Solidity: function EOAToBLSPubkey(address ) view returns(bytes) +func (_Providerregistry *ProviderregistryCaller) EOAToBLSPubkey(opts *bind.CallOpts, arg0 common.Address) ([]byte, error) { + var out []interface{} + err := _Providerregistry.contract.Call(opts, &out, "EOAToBLSPubkey", arg0) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// EOAToBLSPubkey is a free data retrieval call binding the contract method 0xc7cae7fc. +// +// Solidity: function EOAToBLSPubkey(address ) view returns(bytes) +func (_Providerregistry *ProviderregistrySession) EOAToBLSPubkey(arg0 common.Address) ([]byte, error) { + return _Providerregistry.Contract.EOAToBLSPubkey(&_Providerregistry.CallOpts, arg0) +} + +// EOAToBLSPubkey is a free data retrieval call binding the contract method 0xc7cae7fc. +// +// Solidity: function EOAToBLSPubkey(address ) view returns(bytes) +func (_Providerregistry *ProviderregistryCallerSession) EOAToBLSPubkey(arg0 common.Address) ([]byte, error) { + return _Providerregistry.Contract.EOAToBLSPubkey(&_Providerregistry.CallOpts, arg0) +} + +// PERCENT is a free data retrieval call binding the contract method 0xb85a8b20. +// +// Solidity: function PERCENT() view returns(uint256) +func (_Providerregistry *ProviderregistryCaller) PERCENT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Providerregistry.contract.Call(opts, &out, "PERCENT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// PERCENT is a free data retrieval call binding the contract method 0xb85a8b20. +// +// Solidity: function PERCENT() view returns(uint256) +func (_Providerregistry *ProviderregistrySession) PERCENT() (*big.Int, error) { + return _Providerregistry.Contract.PERCENT(&_Providerregistry.CallOpts) +} + +// PERCENT is a free data retrieval call binding the contract method 0xb85a8b20. +// +// Solidity: function PERCENT() view returns(uint256) +func (_Providerregistry *ProviderregistryCallerSession) PERCENT() (*big.Int, error) { + return _Providerregistry.Contract.PERCENT(&_Providerregistry.CallOpts) +} + +// PRECISION is a free data retrieval call binding the contract method 0xaaf5eb68. +// +// Solidity: function PRECISION() view returns(uint256) +func (_Providerregistry *ProviderregistryCaller) PRECISION(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Providerregistry.contract.Call(opts, &out, "PRECISION") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// PRECISION is a free data retrieval call binding the contract method 0xaaf5eb68. +// +// Solidity: function PRECISION() view returns(uint256) +func (_Providerregistry *ProviderregistrySession) PRECISION() (*big.Int, error) { + return _Providerregistry.Contract.PRECISION(&_Providerregistry.CallOpts) +} + +// PRECISION is a free data retrieval call binding the contract method 0xaaf5eb68. +// +// Solidity: function PRECISION() view returns(uint256) +func (_Providerregistry *ProviderregistryCallerSession) PRECISION() (*big.Int, error) { + return _Providerregistry.Contract.PRECISION(&_Providerregistry.CallOpts) +} + // UPGRADEINTERFACEVERSION is a free data retrieval call binding the contract method 0xad3cb1cc. // // Solidity: function UPGRADE_INTERFACE_VERSION() view returns(string) @@ -366,6 +459,37 @@ func (_Providerregistry *ProviderregistryCallerSession) FeeRecipientAmount() (*b return _Providerregistry.Contract.FeeRecipientAmount(&_Providerregistry.CallOpts) } +// GetBLSKey is a free data retrieval call binding the contract method 0xb50c522e. +// +// Solidity: function getBLSKey(address provider) view returns(bytes) +func (_Providerregistry *ProviderregistryCaller) GetBLSKey(opts *bind.CallOpts, provider common.Address) ([]byte, error) { + var out []interface{} + err := _Providerregistry.contract.Call(opts, &out, "getBLSKey", provider) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// GetBLSKey is a free data retrieval call binding the contract method 0xb50c522e. +// +// Solidity: function getBLSKey(address provider) view returns(bytes) +func (_Providerregistry *ProviderregistrySession) GetBLSKey(provider common.Address) ([]byte, error) { + return _Providerregistry.Contract.GetBLSKey(&_Providerregistry.CallOpts, provider) +} + +// GetBLSKey is a free data retrieval call binding the contract method 0xb50c522e. +// +// Solidity: function getBLSKey(address provider) view returns(bytes) +func (_Providerregistry *ProviderregistryCallerSession) GetBLSKey(provider common.Address) ([]byte, error) { + return _Providerregistry.Contract.GetBLSKey(&_Providerregistry.CallOpts, provider) +} + // MinStake is a free data retrieval call binding the contract method 0x375b3c0a. // // Solidity: function minStake() view returns(uint256) @@ -594,25 +718,25 @@ func (_Providerregistry *ProviderregistryTransactorSession) Initialize(_minStake return _Providerregistry.Contract.Initialize(&_Providerregistry.TransactOpts, _minStake, _feeRecipient, _feePercent, _owner) } -// RegisterAndStake is a paid mutator transaction binding the contract method 0x84d180ee. +// RegisterAndStake is a paid mutator transaction binding the contract method 0x8e3d03f6. // -// Solidity: function registerAndStake() payable returns() -func (_Providerregistry *ProviderregistryTransactor) RegisterAndStake(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Providerregistry.contract.Transact(opts, "registerAndStake") +// Solidity: function registerAndStake(bytes blsPublicKey) payable returns() +func (_Providerregistry *ProviderregistryTransactor) RegisterAndStake(opts *bind.TransactOpts, blsPublicKey []byte) (*types.Transaction, error) { + return _Providerregistry.contract.Transact(opts, "registerAndStake", blsPublicKey) } -// RegisterAndStake is a paid mutator transaction binding the contract method 0x84d180ee. +// RegisterAndStake is a paid mutator transaction binding the contract method 0x8e3d03f6. // -// Solidity: function registerAndStake() payable returns() -func (_Providerregistry *ProviderregistrySession) RegisterAndStake() (*types.Transaction, error) { - return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts) +// Solidity: function registerAndStake(bytes blsPublicKey) payable returns() +func (_Providerregistry *ProviderregistrySession) RegisterAndStake(blsPublicKey []byte) (*types.Transaction, error) { + return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts, blsPublicKey) } -// RegisterAndStake is a paid mutator transaction binding the contract method 0x84d180ee. +// RegisterAndStake is a paid mutator transaction binding the contract method 0x8e3d03f6. // -// Solidity: function registerAndStake() payable returns() -func (_Providerregistry *ProviderregistryTransactorSession) RegisterAndStake() (*types.Transaction, error) { - return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts) +// Solidity: function registerAndStake(bytes blsPublicKey) payable returns() +func (_Providerregistry *ProviderregistryTransactorSession) RegisterAndStake(blsPublicKey []byte) (*types.Transaction, error) { + return _Providerregistry.Contract.RegisterAndStake(&_Providerregistry.TransactOpts, blsPublicKey) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. @@ -1515,12 +1639,13 @@ func (it *ProviderregistryProviderRegisteredIterator) Close() error { type ProviderregistryProviderRegistered struct { Provider common.Address StakedAmount *big.Int + BlsPublicKey []byte Raw types.Log // Blockchain specific contextual infos } -// FilterProviderRegistered is a free log retrieval operation binding the contract event 0x90c9734131c1e4fb36cde2d71e6feb93fb258f71be8a85411c173d25e1516e80. +// FilterProviderRegistered is a free log retrieval operation binding the contract event 0x79fda11c69e0429d87cf53e6967d16c56a3d80a7e6e67dd03ccf7f20d6285fc0. // -// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount) +// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes blsPublicKey) func (_Providerregistry *ProviderregistryFilterer) FilterProviderRegistered(opts *bind.FilterOpts, provider []common.Address) (*ProviderregistryProviderRegisteredIterator, error) { var providerRule []interface{} @@ -1535,9 +1660,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 0x90c9734131c1e4fb36cde2d71e6feb93fb258f71be8a85411c173d25e1516e80. +// WatchProviderRegistered is a free log subscription operation binding the contract event 0x79fda11c69e0429d87cf53e6967d16c56a3d80a7e6e67dd03ccf7f20d6285fc0. // -// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount) +// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes blsPublicKey) func (_Providerregistry *ProviderregistryFilterer) WatchProviderRegistered(opts *bind.WatchOpts, sink chan<- *ProviderregistryProviderRegistered, provider []common.Address) (event.Subscription, error) { var providerRule []interface{} @@ -1577,9 +1702,9 @@ func (_Providerregistry *ProviderregistryFilterer) WatchProviderRegistered(opts }), nil } -// ParseProviderRegistered is a log parse operation binding the contract event 0x90c9734131c1e4fb36cde2d71e6feb93fb258f71be8a85411c173d25e1516e80. +// ParseProviderRegistered is a log parse operation binding the contract event 0x79fda11c69e0429d87cf53e6967d16c56a3d80a7e6e67dd03ccf7f20d6285fc0. // -// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount) +// Solidity: event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes blsPublicKey) 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/ProviderRegistry.sol b/contracts/contracts/ProviderRegistry.sol index 06526ac34..f3575784f 100644 --- a/contracts/contracts/ProviderRegistry.sol +++ b/contracts/contracts/ProviderRegistry.sol @@ -18,8 +18,8 @@ contract ProviderRegistry is ReentrancyGuardUpgradeable { /// @dev For improved precision - uint256 constant PRECISION = 10 ** 25; - uint256 constant PERCENT = 100 * PRECISION; + uint256 public constant PRECISION = 10 ** 25; + uint256 public constant PERCENT = 100 * PRECISION; /// @dev Minimum stake required for registration uint256 public minStake; @@ -39,6 +39,9 @@ contract ProviderRegistry is /// @dev Mapping from provider address to whether they are registered or not mapping(address => bool) public providerRegistered; + /// @dev Mapping from a provider's EOA address to their BLS public key + mapping(address => bytes) public EOAToBLSPubkey; + /// @dev Mapping from provider addresses to their staked amount mapping(address => uint256) public providerStakes; @@ -46,7 +49,7 @@ contract ProviderRegistry is mapping(address => uint256) public bidderAmount; /// @dev Event for provider registration - event ProviderRegistered(address indexed provider, uint256 stakedAmount); + event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes blsPublicKey); /// @dev Event for depositing funds event FundsDeposited(address indexed provider, uint256 amount); @@ -123,14 +126,17 @@ contract ProviderRegistry is /** * @dev Register and stake function for providers. + * @param blsPublicKey The BLS public key of the provider. + * The validity of this key must be verified manually off-chain. */ - function registerAndStake() public payable { + function registerAndStake(bytes calldata blsPublicKey) public payable { require(!providerRegistered[msg.sender], "Provider already registered"); require(msg.value >= minStake, "Insufficient stake"); + require(blsPublicKey.length == 48, "Invalid BLS public key length"); + EOAToBLSPubkey[msg.sender] = blsPublicKey; providerStakes[msg.sender] = msg.value; providerRegistered[msg.sender] = true; - - emit ProviderRegistered(msg.sender, msg.value); + emit ProviderRegistered(msg.sender, msg.value, blsPublicKey); } /** @@ -255,4 +261,9 @@ contract ProviderRegistry is (bool success, ) = provider.call{value: stake}(""); require(success, "Couldn't transfer stake to provider"); } + + /// @dev Returns the BLS public key corresponding to a provider's staked EOA address. + function getBLSKey(address provider) external view returns (bytes memory) { + return EOAToBLSPubkey[provider]; + } } diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index ff9b6a8d8..e5cbc929b 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.20; interface IProviderRegistry { - function registerAndStake() external payable; + function registerAndStake(bytes calldata blsPublicKey) external payable; function checkStake(address provider) external view returns (uint256); diff --git a/contracts/test/OracleTest.sol b/contracts/test/OracleTest.sol index 77cee6204..6d481e6cf 100644 --- a/contracts/test/OracleTest.sol +++ b/contracts/test/OracleTest.sol @@ -13,22 +13,23 @@ import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; import {WindowFromBlockNumber} from "../contracts/utils/WindowFromBlockNumber.sol"; contract OracleTest is Test { - address internal owner; + address public owner; using ECDSA for bytes32; - Oracle internal oracle; - PreConfCommitmentStore internal preConfCommitmentStore; - uint16 internal feePercent; - uint256 internal minStake; - address internal feeRecipient; - ProviderRegistry internal providerRegistry; - uint256 testNumber; - uint64 testNumber2; - BidderRegistry internal bidderRegistry; - BlockTracker internal blockTracker; + Oracle public oracle; + PreConfCommitmentStore public preConfCommitmentStore; + uint16 public feePercent; + uint256 public minStake; + address public feeRecipient; + ProviderRegistry public providerRegistry; + uint256 public testNumber; + uint64 public testNumber2; + BidderRegistry public bidderRegistry; + BlockTracker public blockTracker; TestCommitment internal _testCommitmentAliceBob; - uint64 internal dispatchTimestampTesting; - bytes internal sharedSecretKey; - uint256 internal blocksPerWindow; + uint64 public dispatchTimestampTesting; + bytes public sharedSecretKey; + uint256 public blocksPerWindow; + bytes public constant validBLSPubkey = hex"80000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82b"; struct TestCommitment { uint64 bid; @@ -178,7 +179,7 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(); + providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkey); vm.stopPrank(); bytes32 index = constructAndStoreCommitment( @@ -223,7 +224,7 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(); + providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkey); vm.stopPrank(); bytes32 index = constructAndStoreCommitment( @@ -274,7 +275,7 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(); + providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkey); vm.stopPrank(); bytes32 index1 = constructAndStoreCommitment( @@ -347,7 +348,7 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(); + providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkey); vm.stopPrank(); bytes32 index1 = constructAndStoreCommitment( @@ -457,13 +458,13 @@ contract OracleTest is Test { vm.deal(provider, 200000 ether); vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(); + providerRegistry.registerAndStake{value: 250 ether}(validBLSPubkey); vm.stopPrank(); bytes32[] memory commitments = new bytes32[](4); bytes[] memory bidSignatures = new bytes[](4); bytes[] memory commitmentSignatures = new bytes[](4); - for (uint i = 0; i < commitments.length; i++) { + for (uint256 i = 0; i < commitments.length; i++) { ( commitments[i], bidSignatures[i], @@ -486,7 +487,7 @@ contract OracleTest is Test { blockTracker.recordL1Block(blockNumber, "test"); vm.stopPrank(); - for (uint i = 0; i < commitments.length; i++) { + for (uint256 i = 0; i < commitments.length; i++) { vm.startPrank(provider); preConfCommitmentStore.openCommitment( commitments[i], @@ -503,7 +504,7 @@ contract OracleTest is Test { } vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); - for (uint i = 0; i < commitments.length; i++) { + for (uint256 i = 0; i < commitments.length; i++) { vm.expectEmit(true, false, false, true); emit CommitmentProcessed(commitments[i], false); oracle.processBuilderCommitmentForBlockNumber( @@ -566,7 +567,7 @@ contract OracleTest is Test { string memory txnHash, uint64 bid, uint64 blockNumber - ) internal view returns (bytes32) { + ) public view returns (bytes32) { return preConfCommitmentStore.getBidHash( txnHash, @@ -580,7 +581,7 @@ contract OracleTest is Test { function getBidSignature( uint256 bidderPk, bytes32 bidHash - ) internal pure returns (bytes memory) { + ) public pure returns (bytes memory) { (uint8 v, bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); return abi.encodePacked(r, s, v); } @@ -591,7 +592,7 @@ contract OracleTest is Test { uint64 blockNumber, bytes32 bidHash, bytes memory bidSignature - ) internal view returns (bytes32) { + ) public view returns (bytes32) { return preConfCommitmentStore.getPreConfHash( txnHash, @@ -608,7 +609,7 @@ contract OracleTest is Test { function getCommitmentSignature( uint256 signerPk, bytes32 commitmentHash - ) internal pure returns (bytes memory) { + ) public pure returns (bytes memory) { (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, commitmentHash); return abi.encodePacked(r, s, v); } @@ -618,7 +619,7 @@ contract OracleTest is Test { bytes32 commitmentHash, bytes memory commitmentSignature, uint64 dispatchTimestamp - ) internal returns (bytes32) { + ) public returns (bytes32) { vm.startPrank(provider); bytes32 encryptedCommitmentIndex = preConfCommitmentStore .storeEncryptedCommitment( @@ -630,7 +631,7 @@ contract OracleTest is Test { return encryptedCommitmentIndex; } - function recordBlockData(address provider, uint64 blockNumber) internal { + function recordBlockData(address provider, uint64 blockNumber) public { vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); blockTracker.addBuilderAddress("test", provider); blockTracker.recordL1Block(blockNumber, "test"); @@ -645,7 +646,7 @@ contract OracleTest is Test { string memory txnHash, bytes memory bidSignature, bytes memory commitmentSignature - ) internal returns (bytes32) { + ) public returns (bytes32) { vm.startPrank(provider); bytes32 commitmentIndex = preConfCommitmentStore.openCommitment( encryptedCommitmentIndex, @@ -717,7 +718,7 @@ contract OracleTest is Test { function _bytesToHexString( bytes memory _bytes - ) public pure returns (string memory) { + ) internal pure returns (string memory) { bytes memory HEXCHARS = "0123456789abcdef"; bytes memory _string = new bytes(_bytes.length * 2); for (uint256 i = 0; i < _bytes.length; i++) { diff --git a/contracts/test/PreConfirmationConfTest.sol b/contracts/test/PreConfirmationConfTest.sol index 44a4e2aed..e9390dc58 100644 --- a/contracts/test/PreConfirmationConfTest.sol +++ b/contracts/test/PreConfirmationConfTest.sol @@ -28,15 +28,16 @@ contract TestPreConfCommitmentStore is Test { } TestCommitment internal _testCommitmentAliceBob; - PreConfCommitmentStore internal preConfCommitmentStore; - uint16 internal feePercent; - uint256 internal minStake; - address internal provider; - address internal feeRecipient; - ProviderRegistry internal providerRegistry; - BlockTracker internal blockTracker; - uint256 internal blocksPerWindow; - BidderRegistry internal bidderRegistry; + PreConfCommitmentStore public preConfCommitmentStore; + uint16 public feePercent; + uint256 public minStake; + address public provider; + address public feeRecipient; + ProviderRegistry public providerRegistry; + BlockTracker public blockTracker; + uint256 public blocksPerWindow; + BidderRegistry public bidderRegistry; + bytes public constant validBLSPubkey = hex"80000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82b"; function setUp() public { _testCommitmentAliceBob = TestCommitment( @@ -410,7 +411,7 @@ contract TestPreConfCommitmentStore is Test { bytes memory commitmentSignature, uint64 dispatchTimestamp, bytes memory sharedSecretKey - ) internal returns (bytes32) { + ) public returns (bytes32) { bytes32 bidHash = preConfCommitmentStore.getBidHash( txnHash, bid, @@ -451,7 +452,7 @@ contract TestPreConfCommitmentStore is Test { bytes memory bidSignature, bytes memory commitmentSignature, bytes memory sharedSecretKey - ) internal returns (bytes32) { + ) public returns (bytes32) { vm.prank(msgSender); bytes32 commitmentIndex = preConfCommitmentStore.openCommitment( encryptedCommitmentIndex, @@ -624,7 +625,7 @@ contract TestPreConfCommitmentStore is Test { address(preConfCommitmentStore) ); vm.prank(commiter); - providerRegistry.registerAndStake{value: 4 ether}(); + providerRegistry.registerAndStake{value: 4 ether}(validBLSPubkey); uint256 blockNumber = 2; blockTracker.addBuilderAddress("test", commiter); blockTracker.recordL1Block(blockNumber, "test"); @@ -705,7 +706,7 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.sharedSecretKey ); vm.prank(commiter); - providerRegistry.registerAndStake{value: 4 ether}(); + providerRegistry.registerAndStake{value: 4 ether}(validBLSPubkey); blockTracker.addBuilderAddress("test", commiter); blockTracker.recordL1Block( _testCommitmentAliceBob.blockNumber, @@ -789,7 +790,7 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.sharedSecretKey ); vm.prank(commiter); - providerRegistry.registerAndStake{value: 4 ether}(); + providerRegistry.registerAndStake{value: 4 ether}(validBLSPubkey); blockTracker.addBuilderAddress("test", commiter); blockTracker.recordL1Block( _testCommitmentAliceBob.blockNumber, @@ -824,7 +825,7 @@ contract TestPreConfCommitmentStore is Test { function _bytesToHexString( bytes memory _bytes - ) public pure returns (string memory) { + ) internal pure returns (string memory) { bytes memory HEXCHARS = "0123456789abcdef"; bytes memory _string = new bytes(_bytes.length * 2); for (uint256 i = 0; i < _bytes.length; i++) { diff --git a/contracts/test/ProviderRegistryTest.sol b/contracts/test/ProviderRegistryTest.sol index ba0cdbcca..7e02cdaf0 100644 --- a/contracts/test/ProviderRegistryTest.sol +++ b/contracts/test/ProviderRegistryTest.sol @@ -10,17 +10,18 @@ import {BlockTracker} from "../contracts/BlockTracker.sol"; import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; contract ProviderRegistryTest is Test { - uint256 testNumber; - ProviderRegistry internal providerRegistry; - uint16 internal feePercent; - uint256 internal minStake; - address internal provider; - address internal feeRecipient; - BidderRegistry bidderRegistry; - PreConfCommitmentStore preConfCommitmentStore; - BlockTracker blockTracker; - uint256 blocksPerWindow; - event ProviderRegistered(address indexed provider, uint256 stakedAmount); + uint256 public testNumber; + ProviderRegistry public providerRegistry; + uint16 public feePercent; + uint256 public minStake; + address public provider; + address public feeRecipient; + BidderRegistry public bidderRegistry; + PreConfCommitmentStore public preConfCommitmentStore; + BlockTracker public blockTracker; + uint256 public blocksPerWindow; + bytes public constant validBLSPubkey = hex"80000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82b"; + event ProviderRegistered(address indexed provider, uint256 stakedAmount, bytes blsPublicKey); function setUp() public { testNumber = 42; @@ -88,7 +89,15 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); vm.expectRevert(bytes("")); - providerRegistry.registerAndStake{value: 1 wei}(); + providerRegistry.registerAndStake{value: 1 wei}(validBLSPubkey); + } + + function testFail_ProviderStakeAndRegisterInvalidBLSKey() public { + vm.deal(provider, 3 ether); + vm.prank(provider); + vm.expectRevert("Invalid BLS public key length"); + bytes memory blsPublicKey = abi.encodePacked(uint256(134)); + providerRegistry.registerAndStake{value: 1 wei}(blsPublicKey); } function test_ProviderStakeAndRegister() public { @@ -96,9 +105,9 @@ contract ProviderRegistryTest is Test { vm.prank(provider); vm.expectEmit(true, false, false, true); - emit ProviderRegistered(provider, 1e18 wei); + emit ProviderRegistered(provider, 1e18 wei, validBLSPubkey); - providerRegistry.registerAndStake{value: 1e18 wei}(); + providerRegistry.registerAndStake{value: 1e18 wei}(validBLSPubkey); bool isProviderRegistered = providerRegistry.providerRegistered( provider @@ -112,9 +121,9 @@ contract ProviderRegistryTest is Test { function testFail_ProviderStakeAndRegisterAlreadyRegistered() public { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2e18 wei}(); + providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkey); vm.expectRevert(bytes("")); - providerRegistry.registerAndStake{value: 1 wei}(); + providerRegistry.registerAndStake{value: 1 wei}(validBLSPubkey); } function testFail_receive() public { @@ -180,7 +189,7 @@ contract ProviderRegistryTest is Test { providerRegistry.setPreconfirmationsContract(address(this)); vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(); + providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkey); address bidder = vm.addr(4); providerRegistry.slash(1 ether, provider, payable(bidder),100); @@ -197,7 +206,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(); + providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkey); address bidder = vm.addr(4); providerRegistry.slash(1 ether, provider, payable(bidder),100); @@ -209,7 +218,7 @@ contract ProviderRegistryTest is Test { function testFail_shouldRetrieveFundsNotPreConf() public { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(); + providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkey); address bidder = vm.addr(4); vm.expectRevert(bytes("")); providerRegistry.slash(1 ether, provider, payable(bidder),100); @@ -221,7 +230,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(); + providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkey); address bidder = vm.addr(4); vm.expectRevert(bytes("")); vm.prank(address(this)); @@ -234,7 +243,7 @@ contract ProviderRegistryTest is Test { vm.deal(provider, 3 ether); vm.prank(provider); - providerRegistry.registerAndStake{value: 2 ether}(); + providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkey); providerRegistry.setPreconfirmationsContract(address(this)); providerRegistry.slash(1e18 wei, provider, payable(provider),50); assertEq( @@ -254,7 +263,7 @@ contract ProviderRegistryTest is Test { address bidder = vm.addr(7); vm.deal(bidder, 3 ether); vm.prank(bidder); - providerRegistry.registerAndStake{value: 2 ether}(); + providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkey); providerRegistry.setPreconfirmationsContract(address(this)); providerRegistry.slash(1e18 wei, bidder, payable(bidder),100); @@ -272,7 +281,7 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(); + providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkey); providerRegistry.setPreconfirmationsContract( address(preConfCommitmentStore) ); @@ -296,7 +305,7 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(); + providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkey); vm.expectRevert(bytes("")); providerRegistry.withdrawStakedAmount(payable(vm.addr(12))); } @@ -305,7 +314,7 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(5); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(); + providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkey); assertEq( providerRegistry.providerStakes(newProvider), 2e18 wei, @@ -322,7 +331,7 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(); + providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkey); providerRegistry.setPreconfirmationsContract( address(preConfCommitmentStore) ); @@ -346,7 +355,7 @@ contract ProviderRegistryTest is Test { address newProvider = vm.addr(8); vm.deal(newProvider, 3 ether); vm.prank(newProvider); - providerRegistry.registerAndStake{value: 2e18 wei}(); + providerRegistry.registerAndStake{value: 2e18 wei}(validBLSPubkey); vm.expectRevert("Provider Commitments still pending"); providerRegistry.withdrawStakedAmount(payable(newProvider)); } diff --git a/p2p/gen/go/providerapi/v1/providerapi.pb.go b/p2p/gen/go/providerapi/v1/providerapi.pb.go index e982d6a7e..80129892c 100644 --- a/p2p/gen/go/providerapi/v1/providerapi.pb.go +++ b/p2p/gen/go/providerapi/v1/providerapi.pb.go @@ -77,7 +77,8 @@ type StakeRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Amount string `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` + Amount string `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` + BlsPublicKey string `protobuf:"bytes,2,opt,name=bls_public_key,json=blsPublicKey,proto3" json:"bls_public_key,omitempty"` } func (x *StakeRequest) Reset() { @@ -119,12 +120,20 @@ func (x *StakeRequest) GetAmount() string { return "" } +func (x *StakeRequest) GetBlsPublicKey() string { + if x != nil { + return x.BlsPublicKey + } + return "" +} + type StakeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Amount string `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` + Amount string `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` + BlsPublicKey string `protobuf:"bytes,2,opt,name=bls_public_key,json=blsPublicKey,proto3" json:"bls_public_key,omitempty"` } func (x *StakeResponse) Reset() { @@ -166,6 +175,13 @@ func (x *StakeResponse) GetAmount() string { return "" } +func (x *StakeResponse) GetBlsPublicKey() string { + if x != nil { + return x.BlsPublicKey + } + return "" +} + type EmptyMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -366,243 +382,275 @@ 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, 0xc1, 0x02, - 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xbb, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xad, 0x05, + 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, - 0xa2, 0x01, 0x92, 0x41, 0x44, 0x32, 0x39, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, + 0x99, 0x01, 0x92, 0x41, 0x3b, 0x32, 0x30, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x45, 0x54, 0x48, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x69, 0x6e, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, - 0x8a, 0x01, 0x06, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0xba, 0x48, 0x58, 0xba, 0x01, 0x55, 0x0a, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 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, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x73, 0x92, 0x41, - 0x70, 0x0a, 0x4a, 0x2a, 0x0d, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x32, 0x31, 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, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0xd2, 0x01, 0x05, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x32, 0x22, 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, 0x20, - 0x7d, 0x22, 0xa5, 0x01, 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, 0x3a, 0x7c, 0x92, 0x41, 0x79, - 0x0a, 0x53, 0x2a, 0x0e, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x32, 0x41, 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, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x32, 0x22, 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, 0x20, 0x7d, 0x22, 0x0e, 0x0a, 0x0c, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb1, 0x0c, 0x0a, 0x03, 0x42, 0x69, - 0x64, 0x12, 0xa3, 0x02, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x85, 0x02, 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, 0x86, 0x01, 0xba, 0x01, 0x82, 0x01, 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, 0x3d, - 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, 0x20, 0x26, 0x26, 0x20, 0x73, - 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 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, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x8a, 0x01, 0x06, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, + 0xba, 0x48, 0x58, 0xba, 0x01, 0x55, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 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, + 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x52, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0xf1, 0x01, 0x0a, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xca, 0x01, 0x92, + 0x41, 0x3a, 0x32, 0x1f, 0x42, 0x4c, 0x53, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, + 0x65, 0x79, 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, 0x89, 0x01, + 0xba, 0x01, 0x85, 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, 0x26, 0x74, 0x68, 0x69, 0x73, 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, 0x52, 0x0c, 0x62, 0x6c, 0x73, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 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, 0xb8, 0x02, + 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, 0x24, 0x0a, 0x0e, 0x62, 0x6c, 0x73, 0x5f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x62, 0x6c, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x3a, 0xe8, 0x01, + 0x92, 0x41, 0xe4, 0x01, 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, 0x95, 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, 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, 0x7d, 0x22, 0x0e, 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb1, 0x0c, 0x0a, 0x03, 0x42, 0x69, 0x64, + 0x12, 0xa3, 0x02, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x42, 0x85, 0x02, 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, 0x86, 0x01, 0xba, 0x01, 0x82, 0x01, 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, 0x3d, 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, 0x20, 0x26, 0x26, 0x20, 0x73, 0x69, + 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 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, 0x3a, 0xb0, 0x03, 0x92, 0x41, 0xac, 0x03, + 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, 0xb7, 0x02, 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, 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, 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, 0x3a, 0xb0, 0x03, 0x92, 0x41, 0xac, - 0x03, 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, 0xb7, 0x02, 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, + 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, 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, + 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, 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, 0xc5, 0x04, 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, 0x7a, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 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, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x5f, 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, + 0x6d, 0x70, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x7d, + 0x32, 0xc5, 0x04, 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, 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, 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, + 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, 0x7a, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 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, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x5f, 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, 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/go/providerapi/v1/providerapi.pb.gw.go b/p2p/gen/go/providerapi/v1/providerapi.pb.gw.go index e4b679b7b..fe81e1a66 100644 --- a/p2p/gen/go/providerapi/v1/providerapi.pb.gw.go +++ b/p2p/gen/go/providerapi/v1/providerapi.pb.gw.go @@ -92,6 +92,10 @@ func request_Provider_SendProcessedBids_0(ctx context.Context, marshaler runtime } +var ( + filter_Provider_RegisterStake_0 = &utilities.DoubleArray{Encoding: map[string]int{"amount": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_Provider_RegisterStake_0(ctx context.Context, marshaler runtime.Marshaler, client ProviderClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq StakeRequest var metadata runtime.ServerMetadata @@ -113,6 +117,13 @@ func request_Provider_RegisterStake_0(ctx context.Context, marshaler runtime.Mar return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "amount", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Provider_RegisterStake_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.RegisterStake(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -139,6 +150,13 @@ func local_request_Provider_RegisterStake_0(ctx context.Context, marshaler runti return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "amount", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Provider_RegisterStake_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.RegisterStake(ctx, &protoReq) return msg, metadata, err diff --git a/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml b/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml index 479d5c6f6..adfdab05b 100644 --- a/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml +++ b/p2p/gen/openapi/providerapi/v1/providerapi.swagger.yaml @@ -76,10 +76,16 @@ paths: $ref: '#/definitions/googlerpcStatus' parameters: - name: amount - description: Amount of ETH to stake in the provider provider_registry. + description: Amount of ETH to stake in the provider registry. in: path required: true type: string + - name: blsPublicKey + description: BLS public key of the provider. + in: query + required: true + type: string + pattern: ^(0x)?[a-fA-F0-9]{96}$ /v1/provider/send_processed_bids: post: summary: SendProcessedBids @@ -201,8 +207,11 @@ definitions: type: object example: amount: "1000000000000000000" + bls_public_key: 80000cddeec66a80e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d4497ba8b756e1e82b properties: amount: type: string - description: Get staked amount for provider in the provider provider_registry. + blsPublicKey: + type: string + description: Get staked amount for provider in the provider registry. title: Stake response diff --git a/p2p/integrationtest/provider/client.go b/p2p/integrationtest/provider/client.go index 2069b0154..c694c3a48 100644 --- a/p2p/integrationtest/provider/client.go +++ b/p2p/integrationtest/provider/client.go @@ -2,7 +2,9 @@ package main import ( "context" + "crypto/rand" "crypto/tls" + "encoding/hex" "errors" "log/slog" "math/big" @@ -109,8 +111,16 @@ func (b *ProviderClient) CheckAndStake() error { return nil } + blsPubkeyBytes := make([]byte, 48) + _, err = rand.Read(blsPubkeyBytes) + if err != nil { + b.logger.Error("failed to generate mock BLS public key", "err", err) + return err + } + _, err = b.client.RegisterStake(context.Background(), &providerapiv1.StakeRequest{ - Amount: "10000000000000000000", + Amount: "10000000000000000000", + BlsPublicKey: hex.EncodeToString(blsPubkeyBytes), }) if err != nil { b.logger.Error("failed to register stake", "err", err) diff --git a/p2p/pkg/rpc/provider/service.go b/p2p/pkg/rpc/provider/service.go index e4c344a83..333d0a23d 100644 --- a/p2p/pkg/rpc/provider/service.go +++ b/p2p/pkg/rpc/provider/service.go @@ -41,7 +41,7 @@ type Service struct { } type ProviderRegistryContract interface { - RegisterAndStake(*bind.TransactOpts) (*types.Transaction, error) + RegisterAndStake(opts *bind.TransactOpts, blsPublicKey []byte) (*types.Transaction, error) CheckStake(*bind.CallOpts, common.Address) (*big.Int, error) MinStake(*bind.CallOpts) (*big.Int, error) ParseFundsDeposited(types.Log) (*providerregistry.ProviderregistryFundsDeposited, error) @@ -205,7 +205,13 @@ func (s *Service) RegisterStake( } opts.Value = amount - tx, err := s.registryContract.RegisterAndStake(opts) + stake.BlsPublicKey = strings.TrimPrefix(stake.BlsPublicKey, "0x") + blsPubkeyBytes, err := hex.DecodeString(stake.BlsPublicKey) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "decoding bls public key: %v", err) + } + + tx, err := s.registryContract.RegisterAndStake(opts, blsPubkeyBytes) if err != nil { return nil, status.Errorf(codes.Internal, "registering stake: %v", err) } @@ -222,7 +228,10 @@ func (s *Service) RegisterStake( for _, log := range receipt.Logs { if registration, err := s.registryContract.ParseFundsDeposited(*log); err == nil { s.logger.Info("stake registered", "amount", registration.Amount) - return &providerapiv1.StakeResponse{Amount: registration.Amount.String()}, nil + return &providerapiv1.StakeResponse{ + Amount: registration.Amount.String(), + BlsPublicKey: stake.BlsPublicKey, + }, nil } } diff --git a/p2p/pkg/rpc/provider/service_test.go b/p2p/pkg/rpc/provider/service_test.go index bbe004115..9e8e7aae4 100644 --- a/p2p/pkg/rpc/provider/service_test.go +++ b/p2p/pkg/rpc/provider/service_test.go @@ -29,7 +29,7 @@ type testRegistryContract struct { minStake *big.Int } -func (t *testRegistryContract) RegisterAndStake(opts *bind.TransactOpts) (*types.Transaction, error) { +func (t *testRegistryContract) RegisterAndStake(opts *bind.TransactOpts, blsPublicKey []byte) (*types.Transaction, error) { t.stake = opts.Value return types.NewTransaction(1, common.Address{}, nil, 0, nil, nil), nil } @@ -131,14 +131,16 @@ func TestStakeHandling(t *testing.T) { t.Run("register stake", func(t *testing.T) { type testCase struct { - amount string - err string + amount string + blsPublicKey string + err string } for _, tc := range []testCase{ { - amount: "", - err: "amount must be a valid integer", + amount: "", + blsPublicKey: "", + err: "amount must be a valid integer", }, { amount: "0000000000000000000", @@ -149,11 +151,28 @@ func TestStakeHandling(t *testing.T) { err: "amount must be a valid integer", }, { - amount: "1000000000000000000", - err: "", + amount: "1000000000000000000", + blsPublicKey: "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", + blsPublicKey: "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456", + err: "", + }, + { + amount: "1000000000000000000", + blsPublicKey: "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456", + err: "", }, } { - stake, err := client.RegisterStake(context.Background(), &providerapiv1.StakeRequest{Amount: tc.amount}) + stake, err := client.RegisterStake(context.Background(), + &providerapiv1.StakeRequest{Amount: tc.amount, BlsPublicKey: tc.blsPublicKey}) if tc.err != "" { if err == nil || !strings.Contains(err.Error(), tc.err) { t.Fatalf("expected error staking: %s got %v", tc.err, err) @@ -165,6 +184,10 @@ func TestStakeHandling(t *testing.T) { if stake.Amount != tc.amount { t.Fatalf("expected amount to be %v, got %v", tc.amount, stake.Amount) } + tc.blsPublicKey = strings.TrimPrefix(tc.blsPublicKey, "0x") + if stake.BlsPublicKey != tc.blsPublicKey { + t.Fatalf("expected bls_public_key to be %v, got %v", tc.blsPublicKey, stake.BlsPublicKey) + } } } }) diff --git a/p2p/rpc/providerapi/v1/providerapi.proto b/p2p/rpc/providerapi/v1/providerapi.proto index a49965d08..4030af74a 100644 --- a/p2p/rpc/providerapi/v1/providerapi.proto +++ b/p2p/rpc/providerapi/v1/providerapi.proto @@ -59,30 +59,39 @@ message StakeRequest { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { json_schema: { title: "Stake request" - description: "Stake provider in the provider provider_registry." - required: ["stake"] + description: "Stake provider in the provider registry." + required: ["amount", "bls_public_key"] } - example: "{\"amount\": \"1000000000000000000\" }" + example: "{\"amount\": \"1000000000000000000\", \"bls_public_key\": \"80000cddeec66a800e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d44497ba8b756e1e82b\"}" }; string amount = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - description: "Amount of ETH to stake in the provider provider_registry." + description: "Amount of ETH to stake in the provider registry." pattern: "[0-9]+" }, (buf.validate.field).cel = { id: "amount", message: "amount must be a valid integer.", expression: "this.matches('^[0-9]+$') && uint(this) > 0" }]; + string bls_public_key = 2 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "BLS public key of the provider." + pattern: "^(0x)?[a-fA-F0-9]{96}$" + }, (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: "this.matches('^(0x)?[a-fA-F0-9]{96}$')" + }]; }; message StakeResponse { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { json_schema: { title: "Stake response" - description: "Get staked amount for provider in the provider provider_registry." + description: "Get staked amount for provider in the provider registry." } - example: "{\"amount\": \"1000000000000000000\" }" + example: "{\"amount\": \"1000000000000000000\", \"bls_public_key\": \"80000cddeec66a80e00b0ccbb62f12298073603f5209e812abbac7e870482e488dd1bbe533a9d4497ba8b756e1e82b\"}" }; string amount = 1; + string bls_public_key = 2; }; message EmptyMessage {}; @@ -136,6 +145,7 @@ message Bid { expression: "uint(this) > 0" }]; }; + message BidResponse { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { json_schema: {