-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* core/types: define Bid and related error message * internal/eth_api: add MevAPI to receive bids from builder * eth/api_admin: add API to support start and stop mev dynamically * miner: add bidSimulator to maintain bid simulation and fetch best bid from * consensus: add func to query the next inturn validator
- Loading branch information
Showing
22 changed files
with
1,423 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package bidutil | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/ethereum/go-ethereum/core/types" | ||
) | ||
|
||
// BidBetterBefore returns the time when the next bid better be received, considering the delay and bid simulation. | ||
// BidBetterBefore is earlier than BidMustBefore. | ||
func BidBetterBefore(parentHeader *types.Header, blockPeriod uint64, delayLeftOver, simulationLeftOver time.Duration) time.Time { | ||
nextHeaderTime := BidMustBefore(parentHeader, blockPeriod, delayLeftOver) | ||
nextHeaderTime = nextHeaderTime.Add(-simulationLeftOver) | ||
return nextHeaderTime | ||
} | ||
|
||
// BidMustBefore returns the time when the next bid must be received, | ||
// only considering the consensus delay but not bid simulation duration. | ||
func BidMustBefore(parentHeader *types.Header, blockPeriod uint64, delayLeftOver time.Duration) time.Time { | ||
nextHeaderTime := time.Unix(int64(parentHeader.Time+blockPeriod), 0) | ||
nextHeaderTime = nextHeaderTime.Add(-delayLeftOver) | ||
return nextHeaderTime | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
package types | ||
|
||
import ( | ||
"fmt" | ||
"sync/atomic" | ||
"time" | ||
|
||
"github.com/holiman/uint256" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/common/hexutil" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
) | ||
|
||
const TxDecodeConcurrencyForPerBid = 5 | ||
|
||
// BidArgs represents the arguments to submit a bid. | ||
type BidArgs struct { | ||
// RawBid from builder directly | ||
RawBid *RawBid | ||
// Signature of the bid from builder | ||
Signature hexutil.Bytes `json:"signature"` | ||
|
||
// PayBidTx is a payment tx to builder from sentry, which is optional | ||
PayBidTx hexutil.Bytes `json:"payBidTx"` | ||
PayBidTxGasUsed uint64 `json:"payBidTxGasUsed"` | ||
} | ||
|
||
func (b *BidArgs) EcrecoverSender() (common.Address, error) { | ||
pk, err := crypto.SigToPub(b.RawBid.Hash().Bytes(), b.Signature) | ||
if err != nil { | ||
return common.Address{}, err | ||
} | ||
|
||
return crypto.PubkeyToAddress(*pk), nil | ||
} | ||
|
||
func (b *BidArgs) ToBid(builder common.Address, signer Signer) (*Bid, error) { | ||
txs, err := b.RawBid.DecodeTxs(signer) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(b.PayBidTx) != 0 { | ||
var payBidTx = new(Transaction) | ||
err = payBidTx.UnmarshalBinary(b.PayBidTx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
txs = append(txs, payBidTx) | ||
} | ||
|
||
bid := &Bid{ | ||
Builder: builder, | ||
BlockNumber: b.RawBid.BlockNumber, | ||
ParentHash: b.RawBid.ParentHash, | ||
Txs: txs, | ||
GasUsed: b.RawBid.GasUsed + b.PayBidTxGasUsed, | ||
GasFee: b.RawBid.GasFee, | ||
BuilderFee: b.RawBid.BuilderFee, | ||
rawBid: *b.RawBid, | ||
} | ||
|
||
if bid.BuilderFee == nil { | ||
bid.BuilderFee = uint256.NewInt(0) | ||
} | ||
|
||
return bid, nil | ||
} | ||
|
||
// RawBid represents a raw bid from builder directly. | ||
type RawBid struct { | ||
BlockNumber uint64 `json:"blockNumber"` | ||
ParentHash common.Hash `json:"parentHash"` | ||
Txs []hexutil.Bytes `json:"txs"` | ||
GasUsed uint64 `json:"gasUsed"` | ||
GasFee *uint256.Int `json:"gasFee"` | ||
BuilderFee *uint256.Int `json:"builderFee"` | ||
|
||
hash atomic.Value | ||
} | ||
|
||
func (b *RawBid) DecodeTxs(signer Signer) ([]*Transaction, error) { | ||
if len(b.Txs) == 0 { | ||
return []*Transaction{}, nil | ||
} | ||
|
||
txChan := make(chan int, len(b.Txs)) | ||
bidTxs := make([]*Transaction, len(b.Txs)) | ||
decode := func(txBytes hexutil.Bytes) (*Transaction, error) { | ||
tx := new(Transaction) | ||
err := tx.UnmarshalBinary(txBytes) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
_, err = Sender(signer, tx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return tx, nil | ||
} | ||
|
||
errChan := make(chan error, TxDecodeConcurrencyForPerBid) | ||
for i := 0; i < TxDecodeConcurrencyForPerBid; i++ { | ||
go func() { | ||
for { | ||
txIndex, ok := <-txChan | ||
if !ok { | ||
errChan <- nil | ||
return | ||
} | ||
|
||
txBytes := b.Txs[txIndex] | ||
tx, err := decode(txBytes) | ||
if err != nil { | ||
errChan <- err | ||
return | ||
} | ||
|
||
bidTxs[txIndex] = tx | ||
} | ||
}() | ||
} | ||
|
||
for i := 0; i < len(b.Txs); i++ { | ||
txChan <- i | ||
} | ||
|
||
close(txChan) | ||
|
||
for i := 0; i < TxDecodeConcurrencyForPerBid; i++ { | ||
err := <-errChan | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to decode tx, %v", err) | ||
} | ||
} | ||
|
||
return bidTxs, nil | ||
} | ||
|
||
// Hash returns the hash of the bid. | ||
func (b *RawBid) Hash() common.Hash { | ||
if hash := b.hash.Load(); hash != nil { | ||
return hash.(common.Hash) | ||
} | ||
|
||
h := rlpHash(b) | ||
b.hash.Store(h) | ||
|
||
return h | ||
} | ||
|
||
// Bid represents a bid. | ||
type Bid struct { | ||
Builder common.Address | ||
BlockNumber uint64 | ||
ParentHash common.Hash | ||
Txs Transactions | ||
GasUsed uint64 | ||
GasFee *uint256.Int | ||
BuilderFee *uint256.Int | ||
|
||
rawBid RawBid | ||
} | ||
|
||
// Hash returns the bid hash. | ||
func (b *Bid) Hash() common.Hash { | ||
return b.rawBid.Hash() | ||
} | ||
|
||
// BidIssue represents a bid issue. | ||
type BidIssue struct { | ||
Validator common.Address | ||
Builder common.Address | ||
BidHash common.Hash | ||
Message string | ||
} | ||
|
||
type MevParams struct { | ||
ValidatorCommission uint64 // 100 means 1% | ||
BidSimulationLeftOver time.Duration | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package types | ||
|
||
import "errors" | ||
|
||
const ( | ||
InvalidBidParamError = -38001 | ||
InvalidPayBidTxError = -38002 | ||
MevNotRunningError = -38003 | ||
MevBusyError = -38004 | ||
MevNotInTurnError = -38005 | ||
) | ||
|
||
var ( | ||
ErrMevNotRunning = newBidError(errors.New("the validator stop accepting bids for now, try again later"), MevNotRunningError) | ||
ErrMevBusy = newBidError(errors.New("the validator is working on too many bids, try again later"), MevBusyError) | ||
ErrMevNotInTurn = newBidError(errors.New("the validator is not in-turn to propose currently, try again later"), MevNotInTurnError) | ||
) | ||
|
||
// bidError is an API error that encompasses an invalid bid with JSON error | ||
// code and a binary data blob. | ||
type bidError struct { | ||
error | ||
code int | ||
} | ||
|
||
// ErrorCode returns the JSON error code for an invalid bid. | ||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal | ||
func (e *bidError) ErrorCode() int { | ||
return e.code | ||
} | ||
|
||
func NewInvalidBidError(message string) *bidError { | ||
return newBidError(errors.New(message), InvalidBidParamError) | ||
} | ||
|
||
func NewInvalidPayBidTxError(message string) *bidError { | ||
return newBidError(errors.New(message), InvalidPayBidTxError) | ||
} | ||
|
||
func newBidError(err error, code int) *bidError { | ||
return &bidError{ | ||
error: err, | ||
code: code, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.