Skip to content
This repository has been archived by the owner on Apr 15, 2024. It is now read-only.

Commit

Permalink
feat: add gas cost benchmark tool (#524)
Browse files Browse the repository at this point in the history
* feat: add gas cost benchmark tool

* chore: gofumpt
  • Loading branch information
rach-id authored Oct 26, 2023
1 parent bb0bc42 commit 6a8496f
Showing 1 changed file with 214 additions and 0 deletions.
214 changes: 214 additions & 0 deletions benchmark/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package main

Check failure on line 1 in benchmark/main.go

View workflow job for this annotation

GitHub Actions / golangci-lint

: # github.com/celestiaorg/orchestrator-relayer/benchmark

import (
"context"
"crypto/ecdsa"
"fmt"
"math/big"
"os"
"path/filepath"
"syscall"
"time"

"github.com/celestiaorg/celestia-app/x/qgb/types"
"github.com/celestiaorg/orchestrator-relayer/evm"
"github.com/celestiaorg/orchestrator-relayer/store"
types2 "github.com/celestiaorg/orchestrator-relayer/types"
wrappers "github.com/celestiaorg/quantum-gravity-bridge/v2/wrappers/QuantumGravityBridge.sol"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
ethcmn "github.com/ethereum/go-ethereum/common"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
tmlog "github.com/tendermint/tendermint/libs/log"
)

const (
NumberOfValidators = 100
NumberOfNecessarySigners = 30
TotalValidatorPower = int64(100000)
FundedPrivateKeyInHex = "funded_evm_key"
EVMRPC = "evm_network_rpc"
)

type WrappedValidator struct {
Validator wrappers.Validator
PrivateKey ecdsa.PrivateKey
Account accounts.Account
}

func main() {
err := DeployContractAndSubmitDataCommitment()
if err != nil {
fmt.Println(err)
syscall.Exit(1)
}
}

func DeployContractAndSubmitDataCommitment() error {
logger := tmlog.NewTMLogger(os.Stdout)

path, err := os.MkdirTemp(os.TempDir(), "qgb_bench")
if err != nil {
return nil
}

ks := keystore.NewKeyStore(filepath.Join(path, store.EVMKeyStorePath), keystore.LightScryptN, keystore.LightScryptP)

valsetValidators, err := generateRandomValidators(ks, NumberOfValidators, NumberOfNecessarySigners)
if err != nil {
return nil
}
bridgeValidators := ToBridgeValidators(valsetValidators)

ethPrivKey, err := ethcrypto.HexToECDSA(FundedPrivateKeyInHex)
if err != nil {
return err
}

acc, err := ks.ImportECDSA(ethPrivKey, "1234")
if err != nil {
return err
}
err = ks.Unlock(acc, "1234")
if err != nil {
return err
}

logger.Info("loading EVM account", "address", acc.Address.Hex())

ctx := context.Background()

evmClient := evm.NewClient(
tmlog.NewTMLogger(os.Stdout),
nil,
ks,
&acc,
EVMRPC,
2500000,
)

txOpts, err := evmClient.NewTransactionOpts(ctx)
if err != nil {
return err
}

backend, err := evmClient.NewEthClient()
if err != nil {
return err
}
defer backend.Close()

vs := types.Valset{
Nonce: 1,
Members: bridgeValidators,
Height: 1,
Time: time.Now(),
}

address, tx, bridge, err := evmClient.DeployQGBContract(txOpts, backend, vs, vs.Nonce, true)

Check failure on line 108 in benchmark/main.go

View workflow job for this annotation

GitHub Actions / test

evmClient.DeployQGBContract undefined (type *evm.Client has no field or method DeployQGBContract)

Check failure on line 108 in benchmark/main.go

View workflow job for this annotation

GitHub Actions / golangci-lint

evmClient.DeployQGBContract undefined (type *evm.Client has no field or method DeployQGBContract) (typecheck)

Check failure on line 108 in benchmark/main.go

View workflow job for this annotation

GitHub Actions / test-coverage

evmClient.DeployQGBContract undefined (type *evm.Client has no field or method DeployQGBContract)

Check failure on line 108 in benchmark/main.go

View workflow job for this annotation

GitHub Actions / test-race

evmClient.DeployQGBContract undefined (type *evm.Client has no field or method DeployQGBContract)
if err != nil {
logger.Error("failed to deploy QGB contract")
return err
}

receipt, err := evmClient.WaitForTransaction(ctx, backend, tx)
if err == nil && receipt != nil && receipt.Status == 1 {
logger.Info("deployed QGB contract", "proxy_address", address.Hex(), "tx_hash", tx.Hash().String())
}

txOpts.Nonce.Add(txOpts.Nonce, big.NewInt(1))

commitment := []byte{0x12}
dataRootHash := types2.DataCommitmentTupleRootSignBytes(big.NewInt(int64(2)), commitment)
signatures := make([]wrappers.Signature, NumberOfValidators)
cumulatedPower := int64(0)
for i, val := range valsetValidators {
if cumulatedPower > 2*TotalValidatorPower/3 {
break
}
dcSig, err := evm.NewEthereumSignature(dataRootHash.Bytes(), ks, val.Account)
if err != nil {
return err
}
v, r, s, err := evm.SigToVRS(ethcmn.Bytes2Hex(dcSig))
if err != nil {
return err
}
signatures[i] = wrappers.Signature{
V: v,
R: r,
S: s,
}
cumulatedPower += val.Validator.Power.Int64()
}
wrapperValidators := ToWrapperValidators(valsetValidators)
submitTx, err := bridge.SubmitDataRootTupleRoot(txOpts, big.NewInt(2), big.NewInt(1), [32]byte{0x12}, wrapperValidators, signatures)
if err != nil {
return err
}
logger.Info("submitted data root tuple root", "tx_hash", submitTx.Hash().String())
return nil
}

func generateRandomValidators(s *keystore.KeyStore, numberOfValidators, numberOfNecessarySigners int64) ([]WrappedValidator, error) {
validators := make([]WrappedValidator, numberOfValidators)
threshold := 2 * TotalValidatorPower / 3
primaryPowers := threshold / (numberOfNecessarySigners - 1)
secondaryPowers := (TotalValidatorPower - threshold) / (numberOfValidators - numberOfNecessarySigners + 1)
for i := int64(0); i < numberOfValidators; i++ {
pKey, err := ethcrypto.GenerateKey()
if err != nil {
return nil, err
}
address := ethcrypto.PubkeyToAddress(pKey.PublicKey)
if i < numberOfNecessarySigners {
validators[i] = WrappedValidator{
Validator: wrappers.Validator{
Addr: address,
Power: big.NewInt(primaryPowers),
},
PrivateKey: *pKey,
}
} else {
validators[i] = WrappedValidator{
Validator: wrappers.Validator{
Addr: address,
Power: big.NewInt(secondaryPowers),
},
PrivateKey: *pKey,
}
}
account, err := s.ImportECDSA(pKey, "1234")
if err != nil {
return nil, err
}
err = s.Unlock(account, "1234")
if err != nil {
return nil, err
}
validators[i].Account = account
}
return validators, nil
}

func ToBridgeValidators(validators []WrappedValidator) types.BridgeValidators {
bridgedValidators := make(types.BridgeValidators, len(validators))
for i, val := range validators {
bridgedValidators[i] = types.BridgeValidator{
Power: val.Validator.Power.Uint64(),
EvmAddress: val.Validator.Addr.Hex(),
}
}
return bridgedValidators
}

func ToWrapperValidators(validators []WrappedValidator) []wrappers.Validator {
wrapperValidators := make([]wrappers.Validator, len(validators))
for i, val := range validators {
wrapperValidators[i] = wrappers.Validator{
Power: val.Validator.Power,
Addr: val.Validator.Addr,
}
}
return wrapperValidators
}

0 comments on commit 6a8496f

Please sign in to comment.