Skip to content

Commit

Permalink
VRF-330: enabling batch fulfillment for VRF e2e tests (#13091)
Browse files Browse the repository at this point in the history
* VRF-330: enabling batch fulfillment for VRF e2e tests

* VRF-330: fixing lint

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: fixing tests

* VRF-330: PR comments

* VRF-330: PR comments

* VRF-330: PR comments
  • Loading branch information
iljapavlovs committed May 7, 2024
1 parent 700a827 commit b0b4354
Show file tree
Hide file tree
Showing 21 changed files with 833 additions and 101 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -529,12 +529,12 @@ jobs:
pyroscope_env: ci-smoke-vrf-evm-simulated
- name: vrfv2
id: vrfv2
nodes: 5
nodes: 6
os: ubuntu-latest
pyroscope_env: ci-smoke-vrf2-evm-simulated
- name: vrfv2plus
id: vrfv2plus
nodes: 8
nodes: 9
os: ubuntu-latest
pyroscope_env: ci-smoke-vrf2plus-evm-simulated
- name: forwarder_ocr
Expand Down
28 changes: 14 additions & 14 deletions integration-tests/actions/vrf/common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ const (
ErrEncodingProvingKey = "error encoding proving key"
ErrDeployBlockHashStore = "error deploying blockhash store"
ErrDeployBatchBlockHashStore = "error deploying batch blockhash store"
ErrDeployCoordinator = "error deploying VRF CoordinatorV2"
ErrABIEncodingFunding = "error Abi encoding subscriptionID"
ErrSendingLinkToken = "error sending Link token"
ErrCreatingBHSJob = "error creating BHS job"
ErrParseJob = "error parsing job definition"
ErrSetVRFCoordinatorConfig = "error setting config for VRF Coordinator contract"
ErrCreateVRFSubscription = "error creating VRF Subscription"
ErrAddConsumerToSub = "error adding consumer to VRF Subscription"
ErrFundSubWithLinkToken = "error funding subscription with Link tokens"
ErrRestartCLNode = "error restarting CL node"
ErrWaitTXsComplete = "error waiting for TXs to complete"
ErrRequestRandomness = "error requesting randomness"
ErrLoadingCoordinator = "error loading coordinator contract"
ErrCreatingVRFKey = "error creating VRF key"

ErrABIEncodingFunding = "error Abi encoding subscriptionID"
ErrSendingLinkToken = "error sending Link token"
ErrCreatingBHSJob = "error creating BHS job"
ErrParseJob = "error parsing job definition"
ErrSetVRFCoordinatorConfig = "error setting config for VRF Coordinator contract"
ErrCreateVRFSubscription = "error creating VRF Subscription"
ErrAddConsumerToSub = "error adding consumer to VRF Subscription"
ErrFundSubWithLinkToken = "error funding subscription with Link tokens"
ErrRestartCLNode = "error restarting CL node"
ErrWaitTXsComplete = "error waiting for TXs to complete"
ErrRequestRandomness = "error requesting randomness"
ErrLoadingCoordinator = "error loading coordinator contract"
ErrCreatingVRFKey = "error creating VRF key"

ErrWaitRandomWordsRequestedEvent = "error waiting for RandomWordsRequested event"
ErrWaitRandomWordsFulfilledEvent = "error waiting for RandomWordsFulfilled event"
Expand Down
21 changes: 12 additions & 9 deletions integration-tests/actions/vrf/common/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,17 @@ type VRFNode struct {
}

type VRFContracts struct {
CoordinatorV2 contracts.VRFCoordinatorV2
CoordinatorV2Plus contracts.VRFCoordinatorV2_5
VRFOwner contracts.VRFOwner
BHS contracts.BlockHashStore
BatchBHS contracts.BatchBlockhashStore
VRFV2Consumers []contracts.VRFv2LoadTestConsumer
VRFV2PlusConsumer []contracts.VRFv2PlusLoadTestConsumer
LinkToken contracts.LinkToken
MockETHLINKFeed contracts.VRFMockETHLINKFeed
CoordinatorV2 contracts.VRFCoordinatorV2
BatchCoordinatorV2 contracts.BatchVRFCoordinatorV2
CoordinatorV2Plus contracts.VRFCoordinatorV2_5
BatchCoordinatorV2Plus contracts.BatchVRFCoordinatorV2Plus
VRFOwner contracts.VRFOwner
BHS contracts.BlockHashStore
BatchBHS contracts.BatchBlockhashStore
VRFV2Consumers []contracts.VRFv2LoadTestConsumer
VRFV2PlusConsumer []contracts.VRFv2PlusLoadTestConsumer
LinkToken contracts.LinkToken
MockETHLINKFeed contracts.VRFMockETHLINKFeed
}

type VRFOwnerConfig struct {
Expand All @@ -62,6 +64,7 @@ type VRFOwnerConfig struct {
type VRFJobSpecConfig struct {
ForwardingAllowed bool
CoordinatorAddress string
BatchCoordinatorAddress string
FromAddresses []string
EVMChainID string
MinIncomingConfirmations int
Expand Down
43 changes: 28 additions & 15 deletions integration-tests/actions/vrf/vrfv2/contract_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func DeployVRFV2Contracts(
if useTestCoordinator {
testCoordinator, err := env.ContractDeployer.DeployVRFCoordinatorTestV2(linkTokenContract.Address(), bhs.Address(), linkEthFeedContract.Address())
if err != nil {
return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrDeployCoordinator, err)
return nil, fmt.Errorf("%s, err %w", ErrDeployCoordinatorV2, err)
}
err = evmClient.WaitForEvents()
if err != nil {
Expand All @@ -61,7 +61,7 @@ func DeployVRFV2Contracts(
} else {
coordinator, err := env.ContractDeployer.DeployVRFCoordinatorV2(linkTokenContract.Address(), bhs.Address(), linkEthFeedContract.Address())
if err != nil {
return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrDeployCoordinator, err)
return nil, fmt.Errorf("%s, err %w", ErrDeployCoordinatorV2, err)
}
err = evmClient.WaitForEvents()
if err != nil {
Expand All @@ -74,31 +74,44 @@ func DeployVRFV2Contracts(
if err != nil {
return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrLoadingCoordinator, err)
}

batchCoordinator, err := env.ContractDeployer.DeployBatchVRFCoordinatorV2(coordinator.Address())
if err != nil {
return nil, fmt.Errorf("%s, err %w", ErrDeployBatchCoordinatorV2, err)
}

err = evmClient.WaitForEvents()
if err != nil {
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err)
}

if useVRFOwner {
vrfOwner, err := env.ContractDeployer.DeployVRFOwner(coordinatorAddress)
if err != nil {
return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrDeployCoordinator, err)
return nil, fmt.Errorf("%s, err %w", ErrDeployCoordinatorV2, err)
}
err = evmClient.WaitForEvents()
if err != nil {
return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err)
}
return &vrfcommon.VRFContracts{
CoordinatorV2: coordinator,
VRFOwner: vrfOwner,
BHS: bhs,
VRFV2Consumers: nil,
LinkToken: linkTokenContract,
MockETHLINKFeed: linkEthFeedContract,
CoordinatorV2: coordinator,
BatchCoordinatorV2: batchCoordinator,
VRFOwner: vrfOwner,
BHS: bhs,
VRFV2Consumers: nil,
LinkToken: linkTokenContract,
MockETHLINKFeed: linkEthFeedContract,
}, nil
}
return &vrfcommon.VRFContracts{
CoordinatorV2: coordinator,
VRFOwner: nil,
BHS: bhs,
VRFV2Consumers: nil,
LinkToken: linkTokenContract,
MockETHLINKFeed: linkEthFeedContract,
CoordinatorV2: coordinator,
BatchCoordinatorV2: batchCoordinator,
VRFOwner: nil,
BHS: bhs,
VRFV2Consumers: nil,
LinkToken: linkTokenContract,
MockETHLINKFeed: linkEthFeedContract,
}, nil
}

Expand Down
12 changes: 7 additions & 5 deletions integration-tests/actions/vrf/vrfv2/errors.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package vrfv2

const (
ErrDeployVRFV2Wrapper = "error deploying VRFV2Wrapper"
ErrCreateVRFV2Jobs = "error creating VRF V2 Jobs"
ErrDeployVRFV2Contracts = "error deploying VRFV2 contracts"
ErrCreatingVRFv2Job = "error creating VRFv2 job"
ErrAdvancedConsumer = "error deploying VRFv2 Advanced Consumer"
ErrDeployCoordinatorV2 = "error deploying VRF CoordinatorV2"
ErrDeployBatchCoordinatorV2 = "error deploying Batch VRF CoordinatorV2"
ErrDeployVRFV2Wrapper = "error deploying VRFV2Wrapper"
ErrCreateVRFV2Jobs = "error creating VRF V2 Jobs"
ErrDeployVRFV2Contracts = "error deploying VRFV2 contracts"
ErrCreatingVRFv2Job = "error creating VRFv2 job"
ErrAdvancedConsumer = "error deploying VRFv2 Advanced Consumer"
)
7 changes: 3 additions & 4 deletions integration-tests/actions/vrf/vrfv2/setup_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,8 @@ func CreateVRFV2Job(
spec.VRFOwner = vrfJobSpecConfig.VRFOwnerConfig.OwnerAddress
spec.UseVRFOwner = true
}

if err != nil {
return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrParseJob, err)

if vrfJobSpecConfig.BatchFulfillmentEnabled {
spec.BatchCoordinatorAddress = vrfJobSpecConfig.BatchCoordinatorAddress
}
job, err := chainlinkNode.MustCreateJob(spec)
if err != nil {
Expand Down Expand Up @@ -200,6 +198,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Conf
vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{
ForwardingAllowed: *vrfv2Config.VRFJobForwardingAllowed,
CoordinatorAddress: contracts.CoordinatorV2.Address(),
BatchCoordinatorAddress: contracts.BatchCoordinatorV2.Address(),
FromAddresses: vrfNode.TXKeyAddressStrings,
EVMChainID: chainID.String(),
MinIncomingConfirmations: int(*vrfv2Config.MinimumConfirmations),
Expand Down
19 changes: 12 additions & 7 deletions integration-tests/actions/vrf/vrfv2plus/contract_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,28 @@ func DeployVRFV2_5Contracts(
if err != nil {
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrDeployBatchBlockHashStore, err)
}
coordinator, err := contractDeployer.DeployVRFCoordinatorV2_5(bhs.Address())
if err != nil {
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err)
}
err = chainClient.WaitForEvents()
if err != nil {
return nil, fmt.Errorf("%s, batchBHS err %w", vrfcommon.ErrWaitTXsComplete, err)
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err)
}
coordinator, err := contractDeployer.DeployVRFCoordinatorV2_5(bhs.Address())
batchCoordinator, err := contractDeployer.DeployBatchVRFCoordinatorV2Plus(coordinator.Address())
if err != nil {
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrDeployCoordinator, err)
return nil, fmt.Errorf("%s, err %w", ErrDeployBatchCoordinatorV2Plus, err)
}
err = chainClient.WaitForEvents()
if err != nil {
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err)
}
return &vrfcommon.VRFContracts{
CoordinatorV2Plus: coordinator,
BHS: bhs,
BatchBHS: batchBHS,
VRFV2PlusConsumer: nil,
CoordinatorV2Plus: coordinator,
BatchCoordinatorV2Plus: batchCoordinator,
BHS: bhs,
BatchBHS: batchBHS,
VRFV2PlusConsumer: nil,
}, nil
}

Expand Down
2 changes: 2 additions & 0 deletions integration-tests/actions/vrf/vrfv2plus/errors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package vrfv2plus

const (
ErrDeployCoordinatorV2Plus = "error deploying VRF CoordinatorV2Plus"
ErrDeployBatchCoordinatorV2Plus = "error deploying Batch VRF CoordinatorV2Plus"
ErrCreatingVRFv2PlusKey = "error creating VRFv2Plus key"
ErrAdvancedConsumer = "error deploying VRFv2Plus Advanced Consumer"
ErrCreatingVRFv2PlusJob = "error creating VRFv2Plus job"
Expand Down
11 changes: 9 additions & 2 deletions integration-tests/actions/vrf/vrfv2plus/setup_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func CreateVRFV2PlusJob(
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrParseJob, err)
}

job, err := chainlinkNode.MustCreateJob(&client.VRFV2PlusJobSpec{
jobSpec := client.VRFV2PlusJobSpec{
Name: fmt.Sprintf("vrf-v2-plus-%s", jobUUID),
CoordinatorAddress: vrfJobSpecConfig.CoordinatorAddress,
FromAddresses: vrfJobSpecConfig.FromAddresses,
Expand All @@ -56,7 +56,13 @@ func CreateVRFV2PlusJob(
BatchFulfillmentGasMultiplier: vrfJobSpecConfig.BatchFulfillmentGasMultiplier,
PollPeriod: vrfJobSpecConfig.PollPeriod,
RequestTimeout: vrfJobSpecConfig.RequestTimeout,
})
}

if vrfJobSpecConfig.BatchFulfillmentEnabled {
jobSpec.BatchCoordinatorAddress = vrfJobSpecConfig.BatchCoordinatorAddress
}

job, err := chainlinkNode.MustCreateJob(&jobSpec)
if err != nil {
return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrCreatingVRFv2PlusJob, err)
}
Expand Down Expand Up @@ -201,6 +207,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *v
vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{
ForwardingAllowed: *config.VRFJobForwardingAllowed,
CoordinatorAddress: contracts.CoordinatorV2Plus.Address(),
BatchCoordinatorAddress: contracts.BatchCoordinatorV2Plus.Address(),
FromAddresses: vrfNode.TXKeyAddressStrings,
EVMChainID: chainID.String(),
MinIncomingConfirmations: int(*config.MinimumConfirmations),
Expand Down
8 changes: 6 additions & 2 deletions integration-tests/client/chainlink_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,8 @@ observationSource = """
type VRFV2PlusJobSpec struct {
Name string `toml:"name"`
CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF CoordinatorV2 contract
PublicKey string `toml:"publicKey"` // Public key of the proving key
BatchCoordinatorAddress string `toml:"batchCoordinatorAddress"`
PublicKey string `toml:"publicKey"` // Public key of the proving key
ExternalJobID string `toml:"externalJobID"`
ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node
MinIncomingConfirmations int `toml:"minIncomingConfirmations"`
Expand All @@ -1185,6 +1186,7 @@ type = "vrf"
schemaVersion = 1
name = "{{.Name}}"
coordinatorAddress = "{{.CoordinatorAddress}}"
{{ if .BatchFulfillmentEnabled }}batchCoordinatorAddress = "{{.BatchCoordinatorAddress}}"{{ else }}{{ end }}
fromAddresses = [{{range .FromAddresses}}"{{.}}",{{end}}]
evmChainID = "{{.EVMChainID}}"
minIncomingConfirmations = {{.MinIncomingConfirmations}}
Expand All @@ -1207,7 +1209,8 @@ observationSource = """
type VRFV2JobSpec struct {
Name string `toml:"name"`
CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF CoordinatorV2 contract
PublicKey string `toml:"publicKey"` // Public key of the proving key
BatchCoordinatorAddress string `toml:"batchCoordinatorAddress"`
PublicKey string `toml:"publicKey"` // Public key of the proving key
ExternalJobID string `toml:"externalJobID"`
ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node
MinIncomingConfirmations int `toml:"minIncomingConfirmations"`
Expand Down Expand Up @@ -1236,6 +1239,7 @@ schemaVersion = 1
name = "{{.Name}}"
forwardingAllowed = {{.ForwardingAllowed}}
coordinatorAddress = "{{.CoordinatorAddress}}"
{{ if .BatchFulfillmentEnabled }}batchCoordinatorAddress = "{{.BatchCoordinatorAddress}}"{{ else }}{{ end }}
fromAddresses = [{{range .FromAddresses}}"{{.}}",{{end}}]
evmChainID = "{{.EVMChainID}}"
minIncomingConfirmations = {{.MinIncomingConfirmations}}
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/contracts/contract_deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ type ContractDeployer interface {
DeployVRFV2PlusWrapperLoadTestConsumer(vrfV2PlusWrapperAddr string) (VRFv2PlusWrapperLoadTestConsumer, error)
DeployVRFCoordinator(linkAddr string, bhsAddr string) (VRFCoordinator, error)
DeployVRFCoordinatorV2(linkAddr string, bhsAddr string, linkEthFeedAddr string) (VRFCoordinatorV2, error)
DeployBatchVRFCoordinatorV2(coordinatorAddress string) (BatchVRFCoordinatorV2, error)
DeployVRFCoordinatorV2_5(bhsAddr string) (VRFCoordinatorV2_5, error)
DeployBatchVRFCoordinatorV2Plus(coordinatorAddress string) (BatchVRFCoordinatorV2Plus, error)
DeployVRFCoordinatorV2PlusUpgradedVersion(bhsAddr string) (VRFCoordinatorV2PlusUpgradedVersion, error)
DeployVRFV2Wrapper(linkAddr string, linkEthFeedAddr string, coordinatorAddr string) (VRFV2Wrapper, error)
DeployVRFV2PlusWrapper(linkAddr string, linkEthFeedAddr string, coordinatorAddr string, subId *big.Int) (VRFV2PlusWrapper, error)
Expand Down
10 changes: 10 additions & 0 deletions integration-tests/contracts/contract_vrf_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type VRFCoordinatorV2 interface {
OwnerCancelSubscription(subID uint64) (*types.Transaction, error)
ParseSubscriptionCanceled(log types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionCanceled, error)
ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error)
ParseRandomWordsFulfilled(log types.Log) (*CoordinatorRandomWordsFulfilled, error)
ParseLog(log types.Log) (generated.AbigenLog, error)
CancelSubscription(subID uint64, to common.Address) (*types.Transaction, error)
FindSubscriptionID(subID uint64) (uint64, error)
Expand Down Expand Up @@ -122,6 +123,7 @@ type VRFCoordinatorV2_5 interface {
WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error)
WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted, error)
ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error)
ParseRandomWordsFulfilled(log types.Log) (*CoordinatorRandomWordsFulfilled, error)
WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error)
}

Expand Down Expand Up @@ -160,6 +162,7 @@ type VRFCoordinatorV2PlusUpgradedVersion interface {
WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error)
WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted, error)
ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error)
ParseRandomWordsFulfilled(log types.Log) (*CoordinatorRandomWordsFulfilled, error)
WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error)
}

Expand Down Expand Up @@ -365,6 +368,13 @@ type BatchBlockhashStore interface {
Address() string
}

type BatchVRFCoordinatorV2 interface {
Address() string
}
type BatchVRFCoordinatorV2Plus interface {
Address() string
}

type VRFMockETHLINKFeed interface {
Address() string
LatestRoundData() (*big.Int, error)
Expand Down
19 changes: 0 additions & 19 deletions integration-tests/contracts/ethereum_ocr2vrf_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/rs/zerolog/log"

"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
Expand Down Expand Up @@ -114,24 +113,6 @@ func (e *EthereumContractDeployer) DeployVRFBeacon(vrfCoordinatorAddress string,
}, err
}

// DeployBatchBlockhashStore deploys DeployBatchBlockhashStore contract
func (e *EthereumContractDeployer) DeployBatchBlockhashStore(blockhashStoreAddr string) (BatchBlockhashStore, error) {
address, _, instance, err := e.client.DeployContract("BatchBlockhashStore", func(
auth *bind.TransactOpts,
backend bind.ContractBackend,
) (common.Address, *types.Transaction, interface{}, error) {
return batch_blockhash_store.DeployBatchBlockhashStore(auth, backend, common.HexToAddress(blockhashStoreAddr))
})
if err != nil {
return nil, err
}
return &LegacyEthereumBatchBlockhashStore{
client: e.client,
batchBlockhashStore: instance.(*batch_blockhash_store.BatchBlockhashStore),
address: address,
}, err
}

// todo - solve import cycle
func DecodeHexTo32ByteArray(val string) ([32]byte, error) {
var byteArray [32]byte
Expand Down
Loading

0 comments on commit b0b4354

Please sign in to comment.