mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Merge branch 'main' into feature/onfly-sessions
This commit is contained in:
commit
99201b81dd
11 changed files with 413 additions and 27 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
134
miner/builder.go
134
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
|
||||
}
|
||||
return receiptToSimResult(&types.Receipt{Logs: logs}), nil
|
||||
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
|
||||
}
|
||||
}
|
||||
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) FillPending() error {
|
||||
|
|
@ -139,8 +212,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),
|
||||
|
|
@ -169,8 +242,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{},
|
||||
}
|
||||
|
|
@ -223,3 +297,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 newMockBuilderConfig(t *testing.T) (*BuilderConfig, *testWorkerBackend) {
|
||||
|
|
@ -145,6 +291,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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,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)
|
||||
}
|
||||
|
|
@ -36,6 +38,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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@ func TestAPI(t *testing.T) {
|
|||
txn := types.NewTransaction(0, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})
|
||||
_, err = c.AddTransaction(context.Background(), "1", txn)
|
||||
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{}
|
||||
|
|
@ -39,8 +47,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 {
|
||||
|
|
|
|||
|
|
@ -163,6 +163,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, false)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue