From 2abb53cff575de79ce89ef51044a6888741007ef Mon Sep 17 00:00:00 2001 From: Marcel Moura <5615598+marcelstanley@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:44:25 -0300 Subject: [PATCH] feat: allow mining of multiple blocks - implement ethutil.MineBlocks - add support to cli --- cmd/cartesi-rollups-cli/root/mine/mine.go | 40 ++++++++++++++--------- docs/cli/cartesi-rollups-cli.md | 2 +- docs/cli/cartesi-rollups-cli_mine.md | 12 ++++--- pkg/ethutil/ethutil.go | 12 +++++-- pkg/ethutil/ethutil_test.go | 21 +++++++++--- 5 files changed, 58 insertions(+), 29 deletions(-) diff --git a/cmd/cartesi-rollups-cli/root/mine/mine.go b/cmd/cartesi-rollups-cli/root/mine/mine.go index 2c1969544..437c9e3c9 100644 --- a/cmd/cartesi-rollups-cli/root/mine/mine.go +++ b/cmd/cartesi-rollups-cli/root/mine/mine.go @@ -12,30 +12,40 @@ import ( ) var Cmd = &cobra.Command{ - Use: "mine", - Short: "Mine a new block", - Example: examples, - Run: run, + Use: "mine", + Short: "Mine blocks", + Run: run, + Example: `# Mine 10 blocks with a 5-second interval between them: +cartesi-rollups-cli mine --number-of-blocks 10 --block-interval 5`, } -const examples = `# Mine a new block: -cartesi-rollups-cli mine` - var ( - anvilEndpoint string + ethEndpoint string + numBlocks int + blockInterval int ) func init() { - - Cmd.Flags().StringVar(&anvilEndpoint, "anvil-endpoint", "http://localhost:8545", - "address of anvil endpoint to be used to send the mining request") + Cmd.Flags().StringVar(ðEndpoint, "eth-endpoint", "http://localhost:8545", + "ethereum node JSON-RPC endpoint") + Cmd.Flags().IntVar(&numBlocks, "number-of-blocks", 1, + "number of blocks to mine") + Cmd.Flags().IntVar(&blockInterval, "block-interval", 1, + "interval, in seconds, between the timestamps of each block") } func run(cmd *cobra.Command, args []string) { - - blockNumber, err := ethutil.MineNewBlock(context.Background(), anvilEndpoint) - + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + slog.Debug("mining blocks", + "numBlocks", numBlocks, + "blockInterval", blockInterval) + blockNumber, err := ethutil.MineBlocks(ctx, + ethEndpoint, + uint64(numBlocks), + uint64(blockInterval)) cobra.CheckErr(err) - slog.Info("Ok", "block number", blockNumber) + slog.Info("done", "last block number", blockNumber) } diff --git a/docs/cli/cartesi-rollups-cli.md b/docs/cli/cartesi-rollups-cli.md index b70bba14a..2b3763a82 100644 --- a/docs/cli/cartesi-rollups-cli.md +++ b/docs/cli/cartesi-rollups-cli.md @@ -18,7 +18,7 @@ Cartesi Rollups node. * [cartesi-rollups-cli execute](cartesi-rollups-cli_execute.md) - Executes a voucher * [cartesi-rollups-cli increase-time](cartesi-rollups-cli_increase-time.md) - Increases evm time of the current machine * [cartesi-rollups-cli inspect](cartesi-rollups-cli_inspect.md) - Calls inspect API -* [cartesi-rollups-cli mine](cartesi-rollups-cli_mine.md) - Mine a new block +* [cartesi-rollups-cli mine](cartesi-rollups-cli_mine.md) - Mine blocks * [cartesi-rollups-cli read](cartesi-rollups-cli_read.md) - Read the node state from the GraphQL API * [cartesi-rollups-cli run-deps](cartesi-rollups-cli_run-deps.md) - Run node dependencies with Docker * [cartesi-rollups-cli save-snapshot](cartesi-rollups-cli_save-snapshot.md) - Saves the testing Cartesi machine snapshot to the designated folder diff --git a/docs/cli/cartesi-rollups-cli_mine.md b/docs/cli/cartesi-rollups-cli_mine.md index 3995ca3f6..ac3d41645 100644 --- a/docs/cli/cartesi-rollups-cli_mine.md +++ b/docs/cli/cartesi-rollups-cli_mine.md @@ -1,6 +1,6 @@ ## cartesi-rollups-cli mine -Mine a new block +Mine blocks ``` cartesi-rollups-cli mine [flags] @@ -9,15 +9,17 @@ cartesi-rollups-cli mine [flags] ### Examples ``` -# Mine a new block: -cartesi-rollups-cli mine +# Mine 10 blocks with a 5-second interval between them: +cartesi-rollups-cli mine --number-of-blocks 10 --block-interval 5 ``` ### Options ``` - --anvil-endpoint string address of anvil endpoint to be used to send the mining request (default "http://localhost:8545") - -h, --help help for mine + --block-interval int interval, in seconds, between the timestamps of each block (default 1) + --eth-endpoint string ethereum node JSON-RPC endpoint (default "http://localhost:8545") + -h, --help help for mine + --number-of-blocks int number of blocks to mine (default 1) ``` ### SEE ALSO diff --git a/pkg/ethutil/ethutil.go b/pkg/ethutil/ethutil.go index 3bd1a81ee..13a009215 100644 --- a/pkg/ethutil/ethutil.go +++ b/pkg/ethutil/ethutil.go @@ -219,17 +219,23 @@ func SetNextDevnetBlockTimestamp( return client.CallContext(ctx, nil, "evm_setNextBlockTimestamp", timestamp) } -// Mines a new block -func MineNewBlock( +// Mine blocks. +// Assumes the HTTP provider is anvil as the `rpc_modules` method cannot be +// be relied upon to discover what modules are supported and decide what mine +// method to use +func MineBlocks( ctx context.Context, blockchainHttpEndpoint string, + numBlocks uint64, + blockInterval uint64, ) (uint64, error) { client, err := rpc.DialContext(ctx, blockchainHttpEndpoint) if err != nil { return 0, err } defer client.Close() - err = client.CallContext(ctx, nil, "evm_mine") + + err = client.CallContext(ctx, nil, "anvil_mine", numBlocks, blockInterval) if err != nil { return 0, err } diff --git a/pkg/ethutil/ethutil_test.go b/pkg/ethutil/ethutil_test.go index 2d40a4188..5e8509fca 100644 --- a/pkg/ethutil/ethutil_test.go +++ b/pkg/ethutil/ethutil_test.go @@ -19,8 +19,8 @@ import ( const testTimeout = 300 * time.Second -// This suite sets up a container running a devnet Ethereum node, and connects to it using -// go-ethereum's client. +// This suite sets up a container running a devnet Ethereum node +// and connects to it using go-ethereum's client. type EthUtilSuite struct { suite.Suite ctx context.Context @@ -75,11 +75,22 @@ func (s *EthUtilSuite) TestAddInput() { s.Require().Equal(payload, event.Input) } -func (s *EthUtilSuite) TestMineNewBlock() { - blockNumber, err := MineNewBlock(s.ctx, s.endpoint) +func (s *EthUtilSuite) TestMineOneBlock() { + s.mineBlocks(1) +} + +func (s *EthUtilSuite) TestMineAHundredBlocks() { + s.mineBlocks(100) +} + +func (s *EthUtilSuite) mineBlocks(numBlocks uint64) { + lastBlockNumber, err := s.client.BlockNumber(s.ctx) s.Require().Nil(err) - s.Require().Equal(uint64(22), blockNumber) + expectedBlockNumber := lastBlockNumber + numBlocks + blockNumber, err := MineBlocks(s.ctx, s.endpoint, numBlocks, 1) + s.Require().Nil(err) + s.Require().Equal(expectedBlockNumber, blockNumber) } // Log the output of the given container