diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index bca6d1e83b88..f420a241058b 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -187,7 +187,12 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc { // outside of this function, as part of the dynamic gas, and that will make it // also become correctly reported to tracers. contract.Gas += coldCost - return gas + coldCost, nil + + var overflow bool + if gas, overflow = math.SafeAdd(gas, coldCost); overflow { + return 0, ErrGasUintOverflow + } + return gas, nil } } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 831b865a0381..3c9b186040a1 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1459,6 +1459,7 @@ func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Ha tx *types.Transaction err error ) + b.SetPoS() switch i { case 0: // transfer 1000wei @@ -1507,7 +1508,6 @@ func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Ha b.AddTx(tx) txHashes[i] = tx.Hash() } - b.SetPoS() }) return backend, txHashes } diff --git a/miner/builder.go b/miner/builder.go index fd76812c7ea4..770261fb71a6 100644 --- a/miner/builder.go +++ b/miner/builder.go @@ -22,6 +22,13 @@ import ( "github.com/holiman/uint256" ) +var ( + ErrInvalidInclusionRange = errors.New("invalid inclusion range") + ErrInvalidBlockNumber = errors.New("invalid block number") + ErrExceedsMaxBlock = errors.New("block number exceeds max block") + ErrEmptyTxs = errors.New("empty transactions") +) + type BuilderConfig struct { ChainConfig *params.ChainConfig Engine consensus.Engine @@ -77,26 +84,92 @@ func NewBuilder(config *BuilderConfig, args *BuilderArgs) (*Builder, error) { return b, nil } -type SBundle struct { - BlockNumber *big.Int `json:"blockNumber,omitempty"` // if BlockNumber is set it must match DecryptionCondition! - MaxBlock *big.Int `json:"maxBlock,omitempty"` - Txs types.Transactions `json:"txs"` - RevertingHashes []common.Hash `json:"revertingHashes,omitempty"` - RefundPercent *int `json:"percent,omitempty"` -} - -func (b *Builder) AddTransaction(txn *types.Transaction) (*suavextypes.SimulateTransactionResult, error) { +func (b *Builder) addTransaction(txn *types.Transaction, env *environment) (*suavextypes.SimulateTransactionResult, error) { // If the context is not set, the logs will not be recorded b.env.state.SetTxContext(txn.Hash(), b.env.tcount) - logs, err := b.wrk.commitTransaction(b.env, txn) + prevGas := env.header.GasUsed + logs, err := b.wrk.commitTransaction(env, txn) if err != nil { return &suavextypes.SimulateTransactionResult{ Error: err.Error(), Success: false, - }, nil + }, err + } + egp := env.header.GasUsed - prevGas + return receiptToSimResult(&types.Receipt{Logs: logs}, egp), nil +} + +func (b *Builder) AddTransaction(txn *types.Transaction) (*suavextypes.SimulateTransactionResult, error) { + res, _ := b.addTransaction(txn, b.env) + return res, nil +} + +func (b *Builder) AddTransactions(txns types.Transactions) ([]*suavextypes.SimulateTransactionResult, error) { + results := make([]*suavextypes.SimulateTransactionResult, 0) + snap := b.env.copy() + + for _, txn := range txns { + res, err := b.addTransaction(txn, snap) + results = append(results, res) + if err != nil { + return results, nil + } } - return receiptToSimResult(&types.Receipt{Logs: logs}), nil + b.env = snap + return results, nil +} + +func (b *Builder) addBundle(bundle *suavextypes.Bundle, env *environment) (*suavextypes.SimulateBundleResult, error) { + if err := checkBundleParams(b.env.header.Number, bundle); err != nil { + return &suavextypes.SimulateBundleResult{ + Error: err.Error(), + Success: false, + }, err + } + + revertingHashes := bundle.RevertingHashesMap() + egp := uint64(0) + + var results []*suavextypes.SimulateTransactionResult + for _, txn := range bundle.Txs { + result, err := b.addTransaction(txn, env) + results = append(results, result) + if err != nil { + if _, ok := revertingHashes[txn.Hash()]; ok { + // continue if the transaction is in the reverting hashes + continue + } + return &suavextypes.SimulateBundleResult{ + Error: err.Error(), + SimulateTransactionResults: results, + Success: false, + }, err + } + egp += result.Egp + } + + return &suavextypes.SimulateBundleResult{ + Egp: egp, + SimulateTransactionResults: results, + Success: true, + }, nil +} + +func (b *Builder) AddBundles(bundles []*suavextypes.Bundle) ([]*suavextypes.SimulateBundleResult, error) { + var results []*suavextypes.SimulateBundleResult + snap := b.env.copy() + + for _, bundle := range bundles { + result, err := b.addBundle(bundle, snap) + results = append(results, result) + if err != nil { + return results, nil + } + } + + b.env = snap + return results, nil } func (b *Builder) GetBalance(addr common.Address) *big.Int { @@ -143,8 +216,8 @@ func (b *Builder) Bid(builderPubKey phase0.BLSPubKey) (*suavextypes.SubmitBlockR blockBidMsg := builderV1.BidTrace{ Slot: b.args.Slot, - ParentHash: phase0.Hash32(payload.ParentHash), - BlockHash: phase0.Hash32(payload.BlockHash), + ParentHash: payload.ParentHash, + BlockHash: payload.BlockHash, BuilderPubkey: builderPubKey, ProposerPubkey: phase0.BLSPubKey(proposerPubkey), ProposerFeeRecipient: bellatrix.ExecutionAddress(b.args.FeeRecipient), @@ -173,8 +246,9 @@ func (b *Builder) Bid(builderPubKey phase0.BLSPubKey) (*suavextypes.SubmitBlockR return &bidRequest, nil } -func receiptToSimResult(receipt *types.Receipt) *suavextypes.SimulateTransactionResult { +func receiptToSimResult(receipt *types.Receipt, egp uint64) *suavextypes.SimulateTransactionResult { result := &suavextypes.SimulateTransactionResult{ + Egp: egp, Success: true, Logs: []*suavextypes.SimulatedLog{}, } @@ -227,3 +301,33 @@ func executableDataToDenebExecutionPayload(data *engine.ExecutableData) (*deneb. Withdrawals: withdrawalData, }, nil } + +func checkBundleParams(currentBlockNumber *big.Int, bundle *suavextypes.Bundle) error { + if bundle.BlockNumber != nil && bundle.MaxBlock != nil && bundle.BlockNumber.Cmp(bundle.MaxBlock) > 0 { + return ErrInvalidInclusionRange + } + + // check inclusion target if BlockNumber is set + if bundle.BlockNumber != nil { + if bundle.MaxBlock == nil && currentBlockNumber.Cmp(bundle.BlockNumber) != 0 { + return ErrInvalidBlockNumber + } + + if bundle.MaxBlock != nil { + if currentBlockNumber.Cmp(bundle.MaxBlock) > 0 { + return ErrExceedsMaxBlock + } + + if currentBlockNumber.Cmp(bundle.BlockNumber) < 0 { + return ErrInvalidBlockNumber + } + } + } + + // check if the bundle has transactions + if bundle.Txs == nil || bundle.Txs.Len() == 0 { + return ErrEmptyTxs + } + + return nil +} diff --git a/miner/builder_test.go b/miner/builder_test.go index 3cbc3561f595..a538086236c4 100644 --- a/miner/builder_test.go +++ b/miner/builder_test.go @@ -12,9 +12,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + suavextypes "github.com/ethereum/go-ethereum/suave/builder/api" "github.com/stretchr/testify/require" ) @@ -25,12 +28,13 @@ func TestBuilder_AddTxn_Simple(t *testing.T) { builder, err := NewBuilder(config, &BuilderArgs{}) require.NoError(t, err) - tx1 := backend.newRandomTx(true) + tx1 := backend.newRandomTx(false) res, err := builder.AddTransaction(tx1) require.NoError(t, err) require.True(t, res.Success) require.Len(t, builder.env.receipts, 1) + require.Equal(t, big.NewInt(1000), builder.env.state.GetBalance(testUserAddress)) // we cannot add the same transaction again. Note that by design the // function does not error but returns the SimulateTransactionResult.success = false @@ -38,6 +42,150 @@ func TestBuilder_AddTxn_Simple(t *testing.T) { require.NoError(t, err) require.False(t, res.Success) require.Len(t, builder.env.receipts, 1) + require.Equal(t, big.NewInt(1000), builder.env.state.GetBalance(testUserAddress)) +} + +func TestBuilder_AddTxns_Simple(t *testing.T) { + t.Parallel() + config, backend := newMockBuilderConfig(t) + builder, err := NewBuilder(config, &BuilderArgs{}) + require.NoError(t, err) + + tx1 := backend.newRandomTx(false) + tx2 := backend.newRandomTxWithNonce(1) + + res, err := builder.AddTransactions([]*types.Transaction{tx1, tx2}) + require.NoError(t, err) + require.Len(t, res, 2) + for _, r := range res { + require.True(t, r.Success) + } + require.Equal(t, big.NewInt(2000), builder.env.state.GetBalance(testUserAddress)) + + tx3 := backend.newRandomTxWithNonce(2) + tx4 := backend.newRandomTxWithNonce(1000) // fails with nonce too high + + res, err = builder.AddTransactions([]*types.Transaction{tx3, tx4}) + require.NoError(t, err) + require.Len(t, res, 2) + require.True(t, res[0].Success) + require.False(t, res[1].Success) + require.Len(t, builder.env.txs, 2) + require.Equal(t, big.NewInt(2000), builder.env.state.GetBalance(testUserAddress)) +} + +func TestBuilder_AddBundles_Simple(t *testing.T) { + t.Parallel() + config, backend := newMockBuilderConfig(t) + builder, err := NewBuilder(config, &BuilderArgs{}) + require.NoError(t, err) + + tx1 := backend.newRandomTx(false) + tx2 := backend.newRandomTxWithNonce(1) + + bundle1 := &suavextypes.Bundle{ + Txs: []*types.Transaction{tx1, tx2}, + } + + tx3 := backend.newRandomTxWithNonce(2) + tx4 := backend.newRandomTxWithNonce(3) + + bundle2 := &suavextypes.Bundle{ + Txs: []*types.Transaction{tx3, tx4}, + } + + res, err := builder.AddBundles([]*suavextypes.Bundle{bundle1, bundle2}) + require.NoError(t, err) + require.Len(t, res, 2) + require.True(t, res[0].Success) + require.True(t, res[1].Success) + require.Equal(t, big.NewInt(4000), builder.env.state.GetBalance(testUserAddress)) +} + +func TestBuilder_AddBundles_RevertHashes(t *testing.T) { + t.Parallel() + config, backend := newMockBuilderConfig(t) + builder, err := NewBuilder(config, &BuilderArgs{}) + require.NoError(t, err) + + tx1 := backend.newRandomTx(false) + tx2 := backend.newRandomTxWithNonce(3) // fails with nonce too high + + bundle := &suavextypes.Bundle{ + Txs: []*types.Transaction{tx1, tx2}, + } + + res, err := builder.AddBundles([]*suavextypes.Bundle{bundle}) + require.NoError(t, err) + require.Len(t, res, 1) + require.False(t, res[0].Success) + require.Len(t, res[0].SimulateTransactionResults, 2) + require.True(t, res[0].SimulateTransactionResults[0].Success) + require.False(t, res[0].SimulateTransactionResults[1].Success) + require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress)) + + bundle.RevertingHashes = []common.Hash{tx2.Hash()} + + res, err = builder.AddBundles([]*suavextypes.Bundle{bundle}) + require.NoError(t, err) + require.Len(t, res, 1) + require.True(t, res[0].Success) + require.Len(t, res[0].SimulateTransactionResults, 2) + require.True(t, res[0].SimulateTransactionResults[0].Success) + require.False(t, res[0].SimulateTransactionResults[1].Success) + require.Equal(t, big.NewInt(1000), builder.env.state.GetBalance(testUserAddress)) +} + +func TestBuilder_AddBundles_InvalidParams(t *testing.T) { + t.Parallel() + config, backend := newMockBuilderConfig(t) + // set builder target block number to 10 + backend.insertRandomBlocks(9) + + builder, err := NewBuilder(config, &BuilderArgs{}) + require.Equal(t, uint64(10), builder.env.header.Number.Uint64()) + require.NoError(t, err) + + tx1 := backend.newRandomTx(false) + tx2 := backend.newRandomTx(false) + + bundle := &suavextypes.Bundle{ + Txs: []*types.Transaction{tx1, tx2}, + BlockNumber: big.NewInt(20), + } + + res, err := builder.AddBundles([]*suavextypes.Bundle{bundle}) + require.NoError(t, err) + require.Len(t, res, 1) + require.False(t, res[0].Success) + require.Equal(t, ErrInvalidBlockNumber.Error(), res[0].Error) + require.Len(t, res[0].SimulateTransactionResults, 0) + require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress)) + + bundle = &suavextypes.Bundle{ + Txs: []*types.Transaction{tx1, tx2}, + BlockNumber: big.NewInt(5), + MaxBlock: big.NewInt(6), + } + + res, err = builder.AddBundles([]*suavextypes.Bundle{bundle}) + require.NoError(t, err) + require.Len(t, res, 1) + require.False(t, res[0].Success) + require.Equal(t, ErrExceedsMaxBlock.Error(), res[0].Error) + require.Len(t, res[0].SimulateTransactionResults, 0) + require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress)) + + bundle = &suavextypes.Bundle{ + Txs: []*types.Transaction{}, + } + + res, err = builder.AddBundles([]*suavextypes.Bundle{bundle}) + require.NoError(t, err) + require.False(t, res[0].Success) + require.Equal(t, ErrEmptyTxs.Error(), res[0].Error) + require.Len(t, res[0].SimulateTransactionResults, 0) + require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress)) } func TestBuilder_FillTransactions(t *testing.T) { @@ -118,10 +266,8 @@ func TestBuilder_Bid(t *testing.T) { _, err = builder.BuildBlock() require.NoError(t, err) - req, err := builder.Bid([48]byte{}) + _, err = builder.Bid([48]byte{}) require.NoError(t, err) - - fmt.Println("-- req --", req) } func TestBuilder_Balance(t *testing.T) { @@ -165,6 +311,49 @@ func newMockBuilderConfig(t *testing.T) (*BuilderConfig, *testWorkerBackend) { return bConfig, backend } +func (b *testWorkerBackend) newRandomTxWithNonce(nonce uint64) *types.Transaction { + gasPrice := big.NewInt(10 * params.InitialBaseFee) + tx, _ := types.SignTx(types.NewTransaction(nonce, testUserAddress, big.NewInt(1000), params.TxGas, gasPrice, nil), types.HomesteadSigner{}, testBankKey) + return tx +} + +func (b *testWorkerBackend) insertRandomBlocks(n int) []*types.Block { + extraVanity := 32 + extraSeal := crypto.SignatureLength + diffInTurn := big.NewInt(2) + signer := new(types.HomesteadSigner) + _, blocks, _ := core.GenerateChainWithGenesis(b.genesis, b.chain.Engine(), n, func(i int, block *core.BlockGen) { + block.SetDifficulty(big.NewInt(2)) // diffInTurn + + if i != 1 { + tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), common.Address{0x00}, new(big.Int), params.TxGas, block.BaseFee(), nil), signer, testBankKey) + if err != nil { + panic(err) + } + block.AddTxWithChain(b.chain, tx) + } + }) + + for i, block := range blocks { + header := block.Header() + if i > 0 { + header.ParentHash = blocks[i-1].Hash() + } + header.Extra = make([]byte, extraVanity+extraSeal) + header.Difficulty = diffInTurn + + sig, _ := crypto.Sign(clique.SealHash(header).Bytes(), testBankKey) + copy(header.Extra[len(header.Extra)-extraSeal:], sig) + blocks[i] = block.WithSeal(header) + } + + if _, err := b.chain.InsertChain(blocks); err != nil { + panic(fmt.Sprintf("failed to insert initial blocks: %v", err)) + } + + return blocks +} + func (b *testWorkerBackend) newCall(to common.Address, data []byte) *types.Transaction { gasPrice := big.NewInt(10 * params.InitialBaseFee) tx, _ := types.SignTx(types.NewTransaction(b.txPool.Nonce(testBankAddress), to, big.NewInt(0), 1000000, gasPrice, data), types.HomesteadSigner{}, testBankKey) diff --git a/params/config.go b/params/config.go index 7e8dfc8124bc..e97d21af5650 100644 --- a/params/config.go +++ b/params/config.go @@ -859,6 +859,8 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules if chainID == nil { chainID = new(big.Int) } + // disallow setting Merge out of order + isMerge = isMerge && c.IsLondon(num) return Rules{ ChainID: new(big.Int).Set(chainID), IsHomestead: c.IsHomestead(num), @@ -872,9 +874,9 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsBerlin: c.IsBerlin(num), IsLondon: c.IsLondon(num), IsMerge: isMerge, - IsShanghai: c.IsShanghai(num, timestamp), - IsCancun: c.IsCancun(num, timestamp), - IsPrague: c.IsPrague(num, timestamp), - IsVerkle: c.IsVerkle(num, timestamp), + IsShanghai: isMerge && c.IsShanghai(num, timestamp), + IsCancun: isMerge && c.IsCancun(num, timestamp), + IsPrague: isMerge && c.IsPrague(num, timestamp), + IsVerkle: isMerge && c.IsVerkle(num, timestamp), } } diff --git a/suave/builder/api/api.go b/suave/builder/api/api.go index 2579dcb030c5..57a0a1168327 100644 --- a/suave/builder/api/api.go +++ b/suave/builder/api/api.go @@ -24,6 +24,14 @@ type Bundle struct { RefundPercent *int `json:"percent,omitempty"` } +func (bundle *Bundle) RevertingHashesMap() map[common.Hash]struct{} { + m := make(map[common.Hash]struct{}) + for _, hash := range bundle.RevertingHashes { + m[hash] = struct{}{} + } + return m +} + type BuildBlockArgs struct { Slot uint64 `json:"slot"` ProposerPubkey []byte `json:"proposerPubkey"` @@ -52,6 +60,13 @@ type SimulateTransactionResult struct { Error string `json:"error"` } +type SimulateBundleResult struct { + Egp uint64 `json:"egp"` + SimulateTransactionResults []*SimulateTransactionResult `json:"simulateTransactionResults"` + Success bool `json:"success"` + Error string `json:"error"` +} + // field type overrides for gencodec type simulateTransactionResultMarshaling struct { Egp hexutil.Uint64 @@ -77,6 +92,8 @@ type SubmitBlockRequest struct { type API interface { NewSession(ctx context.Context, args *BuildBlockArgs) (string, error) AddTransaction(ctx context.Context, sessionId string, tx *types.Transaction) (*SimulateTransactionResult, error) + AddTransactions(ctx context.Context, sessionId string, txs types.Transactions) ([]*SimulateTransactionResult, error) + AddBundles(ctx context.Context, sessionId string, bundles []*Bundle) ([]*SimulateBundleResult, error) BuildBlock(ctx context.Context, sessionId string) error Bid(ctx context.Context, sessioId string, blsPubKey phase0.BLSPubKey) (*SubmitBlockRequest, error) GetBalance(ctx context.Context, sessionId string, addr common.Address) (*big.Int, error) diff --git a/suave/builder/api/api_client.go b/suave/builder/api/api_client.go index a8ef2291ed47..08cb6dc86a9d 100644 --- a/suave/builder/api/api_client.go +++ b/suave/builder/api/api_client.go @@ -44,6 +44,18 @@ func (a *APIClient) AddTransaction(ctx context.Context, sessionId string, tx *ty return receipt, err } +func (a *APIClient) AddTransactions(ctx context.Context, sessionId string, txs types.Transactions) ([]*SimulateTransactionResult, error) { + var receipt []*SimulateTransactionResult + err := a.rpc.CallContext(ctx, &receipt, "suavex_addTransactions", sessionId, txs) + return receipt, err +} + +func (a *APIClient) AddBundles(ctx context.Context, sessionId string, bundles []*Bundle) ([]*SimulateBundleResult, error) { + var receipt []*SimulateBundleResult + err := a.rpc.CallContext(ctx, &receipt, "suavex_addBundles", sessionId, bundles) + return receipt, err +} + func (a *APIClient) BuildBlock(ctx context.Context, sessionId string) error { return a.rpc.CallContext(ctx, nil, "suavex_buildBlock", sessionId) } diff --git a/suave/builder/api/api_server.go b/suave/builder/api/api_server.go index e38dc57e1f19..8cda0149ae86 100644 --- a/suave/builder/api/api_server.go +++ b/suave/builder/api/api_server.go @@ -15,6 +15,8 @@ var _ API = (*Server)(nil) type SessionManager interface { NewSession(context.Context, *BuildBlockArgs) (string, error) AddTransaction(sessionId string, tx *types.Transaction) (*SimulateTransactionResult, error) + AddTransactions(sessionId string, txs types.Transactions) ([]*SimulateTransactionResult, error) + AddBundles(sessionId string, bundles []*Bundle) ([]*SimulateBundleResult, error) BuildBlock(sessionId string) error Bid(sessionId string, blsPubKey phase0.BLSPubKey) (*SubmitBlockRequest, error) GetBalance(sessionId string, addr common.Address) (*big.Int, error) @@ -39,6 +41,14 @@ func (s *Server) AddTransaction(ctx context.Context, sessionId string, tx *types return s.sessionMngr.AddTransaction(sessionId, tx) } +func (s *Server) AddTransactions(ctx context.Context, sessionId string, txs types.Transactions) ([]*SimulateTransactionResult, error) { + return s.sessionMngr.AddTransactions(sessionId, txs) +} + +func (s *Server) AddBundles(ctx context.Context, sessionId string, bundles []*Bundle) ([]*SimulateBundleResult, error) { + return s.sessionMngr.AddBundles(sessionId, bundles) +} + func (s *Server) BuildBlock(ctx context.Context, sessionId string) error { return s.sessionMngr.BuildBlock(sessionId) } diff --git a/suave/builder/api/api_test.go b/suave/builder/api/api_test.go index cabcb0cce722..5e165d28fcc7 100644 --- a/suave/builder/api/api_test.go +++ b/suave/builder/api/api_test.go @@ -30,6 +30,15 @@ func TestAPI(t *testing.T) { _, err = c.GetBalance(context.Background(), "1", common.Address{}) require.NoError(t, err) + + _, err = c.AddTransactions(context.Background(), "1", []*types.Transaction{txn}) + require.NoError(t, err) + + bundle := &Bundle{ + Txs: []*types.Transaction{txn}, + } + _, err = c.AddBundles(context.Background(), "1", []*Bundle{bundle}) + require.NoError(t, err) } type nullSessionManager struct{} @@ -42,8 +51,12 @@ func (nullSessionManager) AddTransaction(sessionId string, tx *types.Transaction return &SimulateTransactionResult{Logs: []*SimulatedLog{}}, nil } -func (nullSessionManager) AddBundle(sessionId string, bundle Bundle) error { - return nil +func (nullSessionManager) AddTransactions(sessionId string, txs types.Transactions) ([]*SimulateTransactionResult, error) { + return nil, nil +} + +func (nullSessionManager) AddBundles(sessionId string, bundles []*Bundle) ([]*SimulateBundleResult, error) { + return nil, nil } func (nullSessionManager) BuildBlock(sessionId string) error { diff --git a/suave/builder/session_manager.go b/suave/builder/session_manager.go index 9f09b278b728..4a6af073ec60 100644 --- a/suave/builder/session_manager.go +++ b/suave/builder/session_manager.go @@ -150,6 +150,22 @@ func (s *SessionManager) AddTransaction(sessionId string, tx *types.Transaction) return builder.AddTransaction(tx) } +func (s *SessionManager) AddTransactions(sessionId string, txs types.Transactions) ([]*api.SimulateTransactionResult, error) { + builder, err := s.getSession(sessionId) + if err != nil { + return nil, err + } + return builder.AddTransactions(txs) +} + +func (s *SessionManager) AddBundles(sessionId string, bundles []*api.Bundle) ([]*api.SimulateBundleResult, error) { + builder, err := s.getSession(sessionId) + if err != nil { + return nil, err + } + return builder.AddBundles(bundles) +} + func (s *SessionManager) BuildBlock(sessionId string) error { builder, err := s.getSession(sessionId) if err != nil { diff --git a/suave/devenv/docker-compose.yml b/suave/devenv/docker-compose.yml index e8993307f19c..a85593b21e98 100644 --- a/suave/devenv/docker-compose.yml +++ b/suave/devenv/docker-compose.yml @@ -18,6 +18,9 @@ services: - --keystore=/keystore/keystore - --unlock=0xB5fEAfbDD752ad52Afb7e1bD2E40432A485bBB7F - --password=/keystore/password.txt + - --suave.dev + - --suave.eth.remote_endpoint=http://suave-enabled-chain:8545 + - --suave.eth.external-whitelist=172.17.0.1 depends_on: - suave-enabled-chain volumes: @@ -25,12 +28,28 @@ services: ports: - 8545:8545 - 8546:8546 + networks: + - suave-net suave-enabled-chain: build: ../.. command: - --dev - --dev.gaslimit=30000000 - --http + - --http.addr=0.0.0.0 + - --http.vhosts=* + - --http.corsdomain=* + - --datadir=/data + - --keystore=/keystore/keystore + - --password=/keystore/password.txt + - --unlock=0xB5fEAfbDD752ad52Afb7e1bD2E40432A485bBB7F + - --allow-insecure-unlock - --ws ports: - 8555:8545 + volumes: + - ./suave-ex-node:/keystore + networks: + - suave-net +networks: + suave-net: