From 8d9038cf1378b3f386328397d72d14c93225112e Mon Sep 17 00:00:00 2001 From: Ji Hwan Date: Mon, 3 Jun 2024 16:27:13 +0900 Subject: [PATCH 1/5] feat: blob mode for loadtest Signed-off-by: Ji Hwan --- cmd/loadtest/blob.go | 103 ++++++++++++++++++++++++++++ cmd/loadtest/loadtest.go | 68 ++++++++++++++++++ cmd/loadtest/loadtestmode_string.go | 5 +- cmd/loadtest/uniswapv3.go | 6 +- go.mod | 4 +- go.sum | 4 ++ 6 files changed, 183 insertions(+), 7 deletions(-) create mode 100644 cmd/loadtest/blob.go diff --git a/cmd/loadtest/blob.go b/cmd/loadtest/blob.go new file mode 100644 index 00000000..dffb600a --- /dev/null +++ b/cmd/loadtest/blob.go @@ -0,0 +1,103 @@ +package loadtest + +import ( + cryptorand "crypto/rand" + "crypto/sha256" + _ "embed" + "fmt" + "math/rand" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum/go-ethereum/core/types" +) + +type BlobCommitment struct { + Blob kzg4844.Blob + Commitment kzg4844.Commitment + Proof kzg4844.Proof + VersionedHash common.Hash +} + +func encodeBlobData(data []byte) kzg4844.Blob { + blob := kzg4844.Blob{} + fieldIndex := -1 + for i := 0; i < len(data); i += 31 { + fieldIndex++ + if fieldIndex == params.BlobTxFieldElementsPerBlob { + break + } + max := i + 31 + if max > len(data) { + max = len(data) + } + copy(blob[fieldIndex*32+1:], data[i:max]) + } + return blob +} + +func EncodeBlob(data []byte) (*BlobCommitment, error) { + dataLen := len(data) + if dataLen > params.BlobTxFieldElementsPerBlob*(params.BlobTxBytesPerFieldElement-1) { + return nil, fmt.Errorf("Blob data longer than allowed (length: %v, limit: %v)", dataLen, params.BlobTxFieldElementsPerBlob*(params.BlobTxBytesPerFieldElement-1)) + } + blobCommitment := BlobCommitment{ + Blob: encodeBlobData(data), + } + var err error + + // generate blob commitment + blobCommitment.Commitment, err = kzg4844.BlobToCommitment(blobCommitment.Blob) + if err != nil { + return nil, fmt.Errorf("Failed generating blob commitment: %w", err) + } + + // generate blob proof + blobCommitment.Proof, err = kzg4844.ComputeBlobProof(blobCommitment.Blob, blobCommitment.Commitment) + if err != nil { + return nil, fmt.Errorf("Failed generating blob proof: %w", err) + } + + // build versioned hash + blobCommitment.VersionedHash = sha256.Sum256(blobCommitment.Commitment[:]) + blobCommitment.VersionedHash[0] = 0x01 + return &blobCommitment, nil +} + +func parseBlobRefs(tx *types.BlobTx) error { + var err error + var blobBytes []byte + var blobRefBytes []byte + blobLen := rand.Intn((params.BlobTxFieldElementsPerBlob * (params.BlobTxBytesPerFieldElement - 1)) - len(blobBytes)) + blobRefBytes, _ = randomBlobData(blobLen) + + if blobRefBytes == nil { + return fmt.Errorf("Unknown blob ref") + } + blobBytes = append(blobBytes, blobRefBytes...) + + blobCommitment, err := EncodeBlob(blobBytes) + if err != nil { + return fmt.Errorf("Invalid blob: %w", err) + } + + tx.BlobHashes = append(tx.BlobHashes, blobCommitment.VersionedHash) + tx.Sidecar.Blobs = append(tx.Sidecar.Blobs, blobCommitment.Blob) + tx.Sidecar.Commitments = append(tx.Sidecar.Commitments, blobCommitment.Commitment) + tx.Sidecar.Proofs = append(tx.Sidecar.Proofs, blobCommitment.Proof) + return nil +} + +func randomBlobData(size int) ([]byte, error) { + data := make([]byte, size) + n, err := cryptorand.Read(data) + if err != nil { + return nil, err + } + if n != size { + return nil, fmt.Errorf("Could not create random blob data with size %d: %v", size, err) + } + return data, nil +} diff --git a/cmd/loadtest/loadtest.go b/cmd/loadtest/loadtest.go index 7e4a9914..9dd9624b 100644 --- a/cmd/loadtest/loadtest.go +++ b/cmd/loadtest/loadtest.go @@ -10,13 +10,17 @@ import ( "io" "math/big" "math/rand" + "os" "os/signal" "strings" "sync" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/signer/core/apitypes" + "github.com/holiman/uint256" "github.com/maticnetwork/polygon-cli/bindings/tester" "github.com/maticnetwork/polygon-cli/bindings/tokens" @@ -29,6 +33,7 @@ import ( ethereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types" ethcrypto "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" @@ -64,6 +69,7 @@ const ( loadTestModeContractCall loadTestModeInscription loadTestModeUniswapV3 + loadTestModeBlob codeQualitySeed = "code code code code code code code code code code code quality" codeQualityPrivateKey = "42b6e34dc21598a807dc19d7784c71b2a7a01f6480dc6f58258f78e539f1a1fa" @@ -103,6 +109,8 @@ func characterToLoadTestMode(mode string) (loadTestMode, error) { return loadTestModeContractCall, nil case "inscription": return loadTestModeInscription, nil + case "blob": + return loadTestModeBlob, nil default: return 0, fmt.Errorf("unrecognized load test mode: %s", mode) } @@ -637,6 +645,8 @@ func mainLoop(ctx context.Context, c *ethclient.Client, rpc *ethrpc.Client) erro startReq, endReq, tErr = loadTestContractCall(ctx, c, myNonceValue) case loadTestModeInscription: startReq, endReq, tErr = loadTestInscription(ctx, c, myNonceValue) + case loadTestModeBlob: + startReq, endReq, tErr = loadTestBlob(ctx, c, myNonceValue) default: log.Error().Str("mode", mode.String()).Msg("We've arrived at a load test mode that we don't recognize") } @@ -1477,6 +1487,64 @@ func loadTestInscription(ctx context.Context, c *ethclient.Client, nonce uint64) return } +func loadTestBlob(ctx context.Context, c *ethclient.Client, nonce uint64) (t1 time.Time, t2 time.Time, err error) { + ltp := inputLoadTestParams + + to := ltp.ToETHAddress + if *ltp.ToRandom { + to = getRandomAddress() + } + + amount := ltp.SendAmount + chainID := new(big.Int).SetUint64(*ltp.ChainID) + privateKey := ltp.ECDSAPrivateKey + + gasLimit := uint64(21000) + gasPrice, gasTipCap := getSuggestedGasPrices(ctx, c) + blobFeeCap := uint64(1000000000) // 1eth + + blobTx := ethtypes.BlobTx{ + ChainID: uint256.NewInt(chainID.Uint64()), + Nonce: nonce, + GasTipCap: uint256.NewInt(gasTipCap.Uint64()), + GasFeeCap: uint256.NewInt(gasPrice.Uint64()), + BlobFeeCap: uint256.NewInt(blobFeeCap), + Gas: gasLimit, + To: *to, + Value: uint256.NewInt(amount.Uint64()), + Data: nil, + AccessList: nil, + BlobHashes: make([]common.Hash, 0), + Sidecar: &types.BlobTxSidecar{ + Blobs: make([]kzg4844.Blob, 0), + Commitments: make([]kzg4844.Commitment, 0), + Proofs: make([]kzg4844.Proof, 0), + }, + } + err = parseBlobRefs(&blobTx) + if err != nil { + log.Error().Err(err).Msg("Unable to parse blob") + return + } + tx := types.NewTx(&blobTx) + + stx, err := types.SignTx(tx, types.LatestSignerForChainID(chainID), privateKey) + if err != nil { + log.Error().Err(err).Msg("Unable to sign transaction") + return + } + + t1 = time.Now() + defer func() { t2 = time.Now() }() + if *ltp.CallOnly { + log.Error().Err(err).Msg("CallOnly not supported to blob transactions") + return + } else { + err = c.SendTransaction(ctx, stx) + } + return +} + func recordSample(goRoutineID, requestID int64, err error, start, end time.Time, nonce uint64) { s := loadTestSample{} s.GoRoutineID = goRoutineID diff --git a/cmd/loadtest/loadtestmode_string.go b/cmd/loadtest/loadtestmode_string.go index 0a3a9c79..80ec951b 100644 --- a/cmd/loadtest/loadtestmode_string.go +++ b/cmd/loadtest/loadtestmode_string.go @@ -24,11 +24,12 @@ func _() { _ = x[loadTestModeContractCall-13] _ = x[loadTestModeInscription-14] _ = x[loadTestModeUniswapV3-15] + _ = x[loadTestModeBlob-16] } -const _loadTestMode_name = "loadTestModeTransactionloadTestModeDeployloadTestModeCallloadTestModeFunctionloadTestModeIncloadTestModeStoreloadTestModeERC20loadTestModeERC721loadTestModePrecompiledContractsloadTestModePrecompiledContractloadTestModeRandomloadTestModeRecallloadTestModeRPCloadTestModeContractCallloadTestModeInscriptionloadTestModeUniswapV3" +const _loadTestMode_name = "loadTestModeTransactionloadTestModeDeployloadTestModeCallloadTestModeFunctionloadTestModeIncloadTestModeStoreloadTestModeERC20loadTestModeERC721loadTestModePrecompiledContractsloadTestModePrecompiledContractloadTestModeRandomloadTestModeRecallloadTestModeRPCloadTestModeContractCallloadTestModeInscriptionloadTestModeUniswapV3loadTestModeBlob" -var _loadTestMode_index = [...]uint16{0, 23, 41, 57, 77, 92, 109, 126, 144, 176, 207, 225, 243, 258, 282, 305, 326} +var _loadTestMode_index = [...]uint16{0, 23, 41, 57, 77, 92, 109, 126, 144, 176, 207, 225, 243, 258, 282, 305, 326, 342} func (i loadTestMode) String() string { if i < 0 || i >= loadTestMode(len(_loadTestMode_index)-1) { diff --git a/cmd/loadtest/uniswapv3.go b/cmd/loadtest/uniswapv3.go index 6fb594f0..ec8d819d 100644 --- a/cmd/loadtest/uniswapv3.go +++ b/cmd/loadtest/uniswapv3.go @@ -21,7 +21,7 @@ import ( var ( //go:embed uniswapv3Usage.md uniswapv3Usage string - uniswapv3LoadTestParams params + uniswapv3LoadTestParams uniswap3params ) var uniswapV3LoadTestCmd = &cobra.Command{ @@ -62,7 +62,7 @@ func checkUniswapV3LoadtestFlags() error { return nil } -type params struct { +type uniswap3params struct { UniswapFactoryV3, UniswapMulticall, UniswapProxyAdmin, UniswapTickLens, UniswapNFTLibDescriptor, UniswapNonfungibleTokenPositionDescriptor, UniswapUpgradeableProxy, UniswapNonfungiblePositionManager, UniswapMigrator, UniswapStaker, UniswapQuoterV2, UniswapSwapRouter, WETH9, UniswapPoolToken0, UniswapPoolToken1 *string PoolFees *float64 SwapAmountInput *uint64 @@ -70,7 +70,7 @@ type params struct { func init() { // Specify subcommand flags. - params := new(params) + params := new(uniswap3params) // Pre-deployed addresses. params.UniswapFactoryV3 = uniswapV3LoadTestCmd.Flags().String("uniswap-factory-v3-address", "", "The address of a pre-deployed UniswapFactoryV3 contract") diff --git a/go.mod b/go.mod index 75b90df1..80a4b170 100644 --- a/go.mod +++ b/go.mod @@ -130,13 +130,13 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.14.0 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect - golang.org/x/tools v0.16.0 // indirect + golang.org/x/tools v0.21.0 // indirect google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8 // indirect diff --git a/go.sum b/go.sum index f2d8a2f2..0ec8ea28 100644 --- a/go.sum +++ b/go.sum @@ -446,6 +446,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -524,6 +526,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 55277752ebbd9c73943a2491520379d963f1d5d9 Mon Sep 17 00:00:00 2001 From: Ji Hwan Date: Mon, 3 Jun 2024 19:10:24 +0900 Subject: [PATCH 2/5] chore: adding comments and changing variable names Signed-off-by: Ji Hwan --- cmd/loadtest/blob.go | 15 +++++++++------ cmd/loadtest/loadtest.go | 4 +++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/cmd/loadtest/blob.go b/cmd/loadtest/blob.go index dffb600a..7d5cf126 100644 --- a/cmd/loadtest/blob.go +++ b/cmd/loadtest/blob.go @@ -38,7 +38,8 @@ func encodeBlobData(data []byte) kzg4844.Blob { return blob } -func EncodeBlob(data []byte) (*BlobCommitment, error) { +// encodeBlob will generate the values for BlobCommitment variables +func encodeBlob(data []byte) (*BlobCommitment, error) { dataLen := len(data) if dataLen > params.BlobTxFieldElementsPerBlob*(params.BlobTxBytesPerFieldElement-1) { return nil, fmt.Errorf("Blob data longer than allowed (length: %v, limit: %v)", dataLen, params.BlobTxFieldElementsPerBlob*(params.BlobTxBytesPerFieldElement-1)) @@ -48,25 +49,26 @@ func EncodeBlob(data []byte) (*BlobCommitment, error) { } var err error - // generate blob commitment + // Generate blob commitment blobCommitment.Commitment, err = kzg4844.BlobToCommitment(blobCommitment.Blob) if err != nil { return nil, fmt.Errorf("Failed generating blob commitment: %w", err) } - // generate blob proof + // Generate blob proof blobCommitment.Proof, err = kzg4844.ComputeBlobProof(blobCommitment.Blob, blobCommitment.Commitment) if err != nil { return nil, fmt.Errorf("Failed generating blob proof: %w", err) } - // build versioned hash + // Build versioned hash blobCommitment.VersionedHash = sha256.Sum256(blobCommitment.Commitment[:]) blobCommitment.VersionedHash[0] = 0x01 return &blobCommitment, nil } -func parseBlobRefs(tx *types.BlobTx) error { +// parseBlobCommitment will append the generated BlobCommitment values to blob transaction specific variables +func parseBlobCommitment(tx *types.BlobTx) error { var err error var blobBytes []byte var blobRefBytes []byte @@ -78,7 +80,7 @@ func parseBlobRefs(tx *types.BlobTx) error { } blobBytes = append(blobBytes, blobRefBytes...) - blobCommitment, err := EncodeBlob(blobBytes) + blobCommitment, err := encodeBlob(blobBytes) if err != nil { return fmt.Errorf("Invalid blob: %w", err) } @@ -90,6 +92,7 @@ func parseBlobRefs(tx *types.BlobTx) error { return nil } +// randomBlobData will generate random blob data func randomBlobData(size int) ([]byte, error) { data := make([]byte, size) n, err := cryptorand.Read(data) diff --git a/cmd/loadtest/loadtest.go b/cmd/loadtest/loadtest.go index 9dd9624b..83947014 100644 --- a/cmd/loadtest/loadtest.go +++ b/cmd/loadtest/loadtest.go @@ -1503,6 +1503,7 @@ func loadTestBlob(ctx context.Context, c *ethclient.Client, nonce uint64) (t1 ti gasPrice, gasTipCap := getSuggestedGasPrices(ctx, c) blobFeeCap := uint64(1000000000) // 1eth + // Initialize blobTx with blob transaction type blobTx := ethtypes.BlobTx{ ChainID: uint256.NewInt(chainID.Uint64()), Nonce: nonce, @@ -1521,7 +1522,8 @@ func loadTestBlob(ctx context.Context, c *ethclient.Client, nonce uint64) (t1 ti Proofs: make([]kzg4844.Proof, 0), }, } - err = parseBlobRefs(&blobTx) + // paseBlobVariables will take in the blobTx struct and append values to blob transaction specific keys + err = parseBlobCommitment(&blobTx) if err != nil { log.Error().Err(err).Msg("Unable to parse blob") return From 21447d5b3aae792e86bda83629c50dae1bca21ad Mon Sep 17 00:00:00 2001 From: Ji Hwan Date: Mon, 3 Jun 2024 21:31:53 +0900 Subject: [PATCH 3/5] chore: rename functions and add more doc comments for functions Signed-off-by: Ji Hwan --- cmd/loadtest/blob.go | 43 ++++++++++++++++++++-------------------- cmd/loadtest/loadtest.go | 9 +++++++-- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/cmd/loadtest/blob.go b/cmd/loadtest/blob.go index 7d5cf126..b63f45c7 100644 --- a/cmd/loadtest/blob.go +++ b/cmd/loadtest/blob.go @@ -21,7 +21,21 @@ type BlobCommitment struct { VersionedHash common.Hash } -func encodeBlobData(data []byte) kzg4844.Blob { +// generateRandomBlobData will generate random data to be used for blob encoding +func generateRandomBlobData(size int) ([]byte, error) { + data := make([]byte, size) + n, err := cryptorand.Read(data) + if err != nil { + return nil, err + } + if n != size { + return nil, fmt.Errorf("Could not create random blob data with size %d: %v", size, err) + } + return data, nil +} + +// createBlob takes in randomly generated byte slice and commits it with KZG +func createBlob(data []byte) kzg4844.Blob { blob := kzg4844.Blob{} fieldIndex := -1 for i := 0; i < len(data); i += 31 { @@ -38,14 +52,14 @@ func encodeBlobData(data []byte) kzg4844.Blob { return blob } -// encodeBlob will generate the values for BlobCommitment variables -func encodeBlob(data []byte) (*BlobCommitment, error) { +// generateBlobCommitment will generate the values for BlobCommitment variables +func generateBlobCommitment(data []byte) (*BlobCommitment, error) { dataLen := len(data) if dataLen > params.BlobTxFieldElementsPerBlob*(params.BlobTxBytesPerFieldElement-1) { return nil, fmt.Errorf("Blob data longer than allowed (length: %v, limit: %v)", dataLen, params.BlobTxFieldElementsPerBlob*(params.BlobTxBytesPerFieldElement-1)) } blobCommitment := BlobCommitment{ - Blob: encodeBlobData(data), + Blob: createBlob(data), } var err error @@ -67,20 +81,20 @@ func encodeBlob(data []byte) (*BlobCommitment, error) { return &blobCommitment, nil } -// parseBlobCommitment will append the generated BlobCommitment values to blob transaction specific variables -func parseBlobCommitment(tx *types.BlobTx) error { +// appendBlobCommitment will append the generated BlobCommitment values to blob transaction specific variables +func appendBlobCommitment(tx *types.BlobTx) error { var err error var blobBytes []byte var blobRefBytes []byte blobLen := rand.Intn((params.BlobTxFieldElementsPerBlob * (params.BlobTxBytesPerFieldElement - 1)) - len(blobBytes)) - blobRefBytes, _ = randomBlobData(blobLen) + blobRefBytes, _ = generateRandomBlobData(blobLen) if blobRefBytes == nil { return fmt.Errorf("Unknown blob ref") } blobBytes = append(blobBytes, blobRefBytes...) - blobCommitment, err := encodeBlob(blobBytes) + blobCommitment, err := generateBlobCommitment(blobBytes) if err != nil { return fmt.Errorf("Invalid blob: %w", err) } @@ -91,16 +105,3 @@ func parseBlobCommitment(tx *types.BlobTx) error { tx.Sidecar.Proofs = append(tx.Sidecar.Proofs, blobCommitment.Proof) return nil } - -// randomBlobData will generate random blob data -func randomBlobData(size int) ([]byte, error) { - data := make([]byte, size) - n, err := cryptorand.Read(data) - if err != nil { - return nil, err - } - if n != size { - return nil, fmt.Errorf("Could not create random blob data with size %d: %v", size, err) - } - return data, nil -} diff --git a/cmd/loadtest/loadtest.go b/cmd/loadtest/loadtest.go index 83947014..c54639a7 100644 --- a/cmd/loadtest/loadtest.go +++ b/cmd/loadtest/loadtest.go @@ -1522,8 +1522,13 @@ func loadTestBlob(ctx context.Context, c *ethclient.Client, nonce uint64) (t1 ti Proofs: make([]kzg4844.Proof, 0), }, } - // paseBlobVariables will take in the blobTx struct and append values to blob transaction specific keys - err = parseBlobCommitment(&blobTx) + // appendBlobCommitment() will take in the blobTx struct and append values to blob transaction specific keys in the following steps: + // The function will take in blobTx with empty BlobHashses, and Blob Sidecar variables initially. + // Then generateRandomBlobData() is called to generate a byte slice with random values. + // createBlob() is called to commit the randomly generated byte slice with KZG. + // generateBlobCommitment() will do the same for the Commitment and Proof. + // Append all the blob related computed values to the blobTx struct. + err = appendBlobCommitment(&blobTx) if err != nil { log.Error().Err(err).Msg("Unable to parse blob") return From cc00b0a5981d6a869aad19404ccbe2be26d0267c Mon Sep 17 00:00:00 2001 From: Ji Hwan Date: Tue, 4 Jun 2024 09:56:36 +0900 Subject: [PATCH 4/5] feat: add input load test parameter flag for blob fee cap Signed-off-by: Ji Hwan --- cmd/loadtest/app.go | 2 ++ cmd/loadtest/loadtest.go | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/loadtest/app.go b/cmd/loadtest/app.go index 150c5731..246a9693 100644 --- a/cmd/loadtest/app.go +++ b/cmd/loadtest/app.go @@ -78,6 +78,7 @@ type ( ContractCallFunctionArgs *[]string ContractCallPayable *bool InscriptionContent *string + BlobFeeCap *uint64 // Computed CurrentGasPrice *big.Int @@ -229,6 +230,7 @@ func initFlags() { ltp.SummaryOutputMode = LoadtestCmd.PersistentFlags().String("output-mode", "text", "Format mode for summary output (json | text)") ltp.LegacyTransactionMode = LoadtestCmd.PersistentFlags().Bool("legacy", false, "Send a legacy transaction instead of an EIP1559 transaction.") ltp.SendOnly = LoadtestCmd.PersistentFlags().Bool("send-only", false, "Send transactions and load without waiting for it to be mined.") + ltp.BlobFeeCap = LoadtestCmd.Flags().Uint64("blob-fee-cap", 100000, "The blob fee cap, or the maximum blob fee per chunk, in Gwei.") // Local flags. ltp.Modes = LoadtestCmd.Flags().StringSliceP("mode", "m", []string{"t"}, `The testing mode to use. It can be multiple like: "t,c,d,f" diff --git a/cmd/loadtest/loadtest.go b/cmd/loadtest/loadtest.go index c54639a7..35a37c25 100644 --- a/cmd/loadtest/loadtest.go +++ b/cmd/loadtest/loadtest.go @@ -1501,7 +1501,8 @@ func loadTestBlob(ctx context.Context, c *ethclient.Client, nonce uint64) (t1 ti gasLimit := uint64(21000) gasPrice, gasTipCap := getSuggestedGasPrices(ctx, c) - blobFeeCap := uint64(1000000000) // 1eth + // blobFeeCap := uint64(1000000000) // 1eth + blobFeeCap := ltp.BlobFeeCap // Initialize blobTx with blob transaction type blobTx := ethtypes.BlobTx{ @@ -1509,7 +1510,7 @@ func loadTestBlob(ctx context.Context, c *ethclient.Client, nonce uint64) (t1 ti Nonce: nonce, GasTipCap: uint256.NewInt(gasTipCap.Uint64()), GasFeeCap: uint256.NewInt(gasPrice.Uint64()), - BlobFeeCap: uint256.NewInt(blobFeeCap), + BlobFeeCap: uint256.NewInt(*blobFeeCap), Gas: gasLimit, To: *to, Value: uint256.NewInt(amount.Uint64()), From ae50b2a67d5f57b6ea7865f22f0b739877b742ea Mon Sep 17 00:00:00 2001 From: Ji Hwan Date: Tue, 4 Jun 2024 10:27:07 +0900 Subject: [PATCH 5/5] docs: add blob-fee-cap flag Signed-off-by: Ji Hwan --- doc/polycli_loadtest.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/polycli_loadtest.md b/doc/polycli_loadtest.md index e1a7d5cd..77455031 100644 --- a/doc/polycli_loadtest.md +++ b/doc/polycli_loadtest.md @@ -105,6 +105,7 @@ The codebase has a contract that used for load testing. It's written in Solidity --adaptive-rate-limit Enable AIMD-style congestion control to automatically adjust request rate --adaptive-rate-limit-increment uint When using adaptive rate limiting, this flag controls the size of the additive increases. (default 50) --batch-size uint Number of batches to perform at a time for receipt fetching. Default is 999 requests at a time. (default 999) + --blob-fee-cap uint The blob fee cap, or the maximum blob fee per chunk, in Gwei. (default 100000) -b, --byte-count uint If we're in store mode, this controls how many bytes we'll try to store in our contract (default 1024) --call-only When using this mode, rather than sending a transaction, we'll just call. This mode is incompatible with adaptive rate limiting, summarization, and a few other features. --call-only-latest When using call only mode with recall, should we execute on the latest block or on the original block