core/types, params: add blob transaction type, RLP encoded for now (#27049)
* core/types, params: add blob transaction type, RLP encoded for now * all: integrate Cancun (and timestamp based forks) into MakeSigner * core/types: fix 2 back-and-forth type refactors * core: fix review comment * core/types: swap blob tx type id to 0x03
This commit is contained in:
parent
4ab4e4f3aa
commit
bbc565ab05
@ -684,7 +684,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
|
|||||||
return fmt.Errorf("could not fetch parent")
|
return fmt.Errorf("could not fetch parent")
|
||||||
}
|
}
|
||||||
// Check transaction validity
|
// Check transaction validity
|
||||||
signer := types.MakeSigner(b.blockchain.Config(), block.Number())
|
signer := types.MakeSigner(b.blockchain.Config(), block.Number(), block.Time())
|
||||||
sender, err := types.Sender(signer, tx)
|
sender, err := types.Sender(signer, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid transaction: %v", err)
|
return fmt.Errorf("invalid transaction: %v", err)
|
||||||
@ -884,7 +884,11 @@ func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (typ
|
|||||||
if number == nil {
|
if number == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()), nil
|
header := rawdb.ReadHeader(fb.db, hash, *number)
|
||||||
|
if header == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return rawdb.ReadReceipts(fb.db, hash, *number, header.Time, fb.bc.Config()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
|
func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
|
||||||
|
@ -125,7 +125,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre)
|
statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre)
|
||||||
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number))
|
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
|
||||||
gaspool = new(core.GasPool)
|
gaspool = new(core.GasPool)
|
||||||
blockHash = common.Hash{0x13, 0x37}
|
blockHash = common.Hash{0x13, 0x37}
|
||||||
rejectedTxs []*rejectedTx
|
rejectedTxs []*rejectedTx
|
||||||
|
@ -112,7 +112,7 @@ func Transaction(ctx *cli.Context) error {
|
|||||||
return NewError(ErrorIO, errors.New("only rlp supported"))
|
return NewError(ErrorIO, errors.New("only rlp supported"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(chainConfig, new(big.Int))
|
signer := types.MakeSigner(chainConfig, new(big.Int), 0)
|
||||||
// We now have the transactions in 'body', which is supposed to be an
|
// We now have the transactions in 'body', which is supposed to be an
|
||||||
// rlp list of transactions
|
// rlp list of transactions
|
||||||
it, err := rlp.NewListIterator([]byte(body))
|
it, err := rlp.NewListIterator([]byte(body))
|
||||||
|
@ -240,7 +240,7 @@ func Transition(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We may have to sign the transactions.
|
// We may have to sign the transactions.
|
||||||
signer := types.MakeSigner(chainConfig, big.NewInt(int64(prestate.Env.Number)))
|
signer := types.MakeSigner(chainConfig, big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp)
|
||||||
|
|
||||||
if txs, err = signUnsignedTransactions(txsWithKeys, signer); err != nil {
|
if txs, err = signUnsignedTransactions(txsWithKeys, signer); err != nil {
|
||||||
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
|
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
|
||||||
|
@ -84,7 +84,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
|
|||||||
toaddr := common.Address{}
|
toaddr := common.Address{}
|
||||||
data := make([]byte, nbytes)
|
data := make([]byte, nbytes)
|
||||||
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
|
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
|
||||||
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)))
|
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), gen.header.Time)
|
||||||
gasPrice := big.NewInt(0)
|
gasPrice := big.NewInt(0)
|
||||||
if gen.header.BaseFee != nil {
|
if gen.header.BaseFee != nil {
|
||||||
gasPrice = gen.header.BaseFee
|
gasPrice = gen.header.BaseFee
|
||||||
@ -128,7 +128,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
|
|||||||
if gen.header.BaseFee != nil {
|
if gen.header.BaseFee != nil {
|
||||||
gasPrice = gen.header.BaseFee
|
gasPrice = gen.header.BaseFee
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)))
|
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), gen.header.Time)
|
||||||
for {
|
for {
|
||||||
gas -= params.TxGas
|
gas -= params.TxGas
|
||||||
if gas < params.TxGas {
|
if gas < params.TxGas {
|
||||||
@ -317,7 +317,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
|
|||||||
if full {
|
if full {
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
rawdb.ReadBody(db, hash, n)
|
rawdb.ReadBody(db, hash, n)
|
||||||
rawdb.ReadReceipts(db, hash, n, chain.Config())
|
rawdb.ReadReceipts(db, hash, n, header.Time, chain.Config())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chain.Stop()
|
chain.Stop()
|
||||||
|
@ -1540,7 +1540,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
|
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
|
||||||
SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)
|
SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
stats = insertStats{startTime: mclock.Now()}
|
stats = insertStats{startTime: mclock.Now()}
|
||||||
@ -2049,7 +2049,7 @@ func (bc *BlockChain) recoverAncestors(block *types.Block) (common.Hash, error)
|
|||||||
// the processing of a block. These logs are later announced as deleted or reborn.
|
// the processing of a block. These logs are later announced as deleted or reborn.
|
||||||
func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log {
|
func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log {
|
||||||
receipts := rawdb.ReadRawReceipts(bc.db, b.Hash(), b.NumberU64())
|
receipts := rawdb.ReadRawReceipts(bc.db, b.Hash(), b.NumberU64())
|
||||||
receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.BaseFee(), b.Transactions())
|
receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.Time(), b.BaseFee(), b.Transactions())
|
||||||
|
|
||||||
var logs []*types.Log
|
var logs []*types.Log
|
||||||
for _, receipt := range receipts {
|
for _, receipt := range receipts {
|
||||||
|
@ -217,7 +217,11 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
|
|||||||
if number == nil {
|
if number == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig)
|
header := bc.GetHeader(hash, *number)
|
||||||
|
if header == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
receipts := rawdb.ReadReceipts(bc.db, hash, *number, header.Time, bc.chainConfig)
|
||||||
if receipts == nil {
|
if receipts == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -809,7 +809,7 @@ func TestFastVsFullChains(t *testing.T) {
|
|||||||
|
|
||||||
// Iterate over all chain data components, and cross reference
|
// Iterate over all chain data components, and cross reference
|
||||||
for i := 0; i < len(blocks); i++ {
|
for i := 0; i < len(blocks); i++ {
|
||||||
num, hash := blocks[i].NumberU64(), blocks[i].Hash()
|
num, hash, time := blocks[i].NumberU64(), blocks[i].Hash(), blocks[i].Time()
|
||||||
|
|
||||||
if ftd, atd := fast.GetTd(hash, num), archive.GetTd(hash, num); ftd.Cmp(atd) != 0 {
|
if ftd, atd := fast.GetTd(hash, num), archive.GetTd(hash, num); ftd.Cmp(atd) != 0 {
|
||||||
t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd)
|
t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd)
|
||||||
@ -832,9 +832,9 @@ func TestFastVsFullChains(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check receipts.
|
// Check receipts.
|
||||||
freceipts := rawdb.ReadReceipts(fastDb, hash, num, fast.Config())
|
freceipts := rawdb.ReadReceipts(fastDb, hash, num, time, fast.Config())
|
||||||
anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, fast.Config())
|
anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, time, fast.Config())
|
||||||
areceipts := rawdb.ReadReceipts(archiveDb, hash, num, fast.Config())
|
areceipts := rawdb.ReadReceipts(archiveDb, hash, num, time, fast.Config())
|
||||||
if types.DeriveSha(freceipts, trie.NewStackTrie(nil)) != types.DeriveSha(areceipts, trie.NewStackTrie(nil)) {
|
if types.DeriveSha(freceipts, trie.NewStackTrie(nil)) != types.DeriveSha(areceipts, trie.NewStackTrie(nil)) {
|
||||||
t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
|
t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
|
||||||
}
|
}
|
||||||
|
@ -625,7 +625,7 @@ func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Rec
|
|||||||
// The current implementation populates these metadata fields by reading the receipts'
|
// The current implementation populates these metadata fields by reading the receipts'
|
||||||
// corresponding block body, so if the block body is not found it will return nil even
|
// corresponding block body, so if the block body is not found it will return nil even
|
||||||
// if the receipt itself is stored.
|
// if the receipt itself is stored.
|
||||||
func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts {
|
func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, config *params.ChainConfig) types.Receipts {
|
||||||
// We're deriving many fields from the block body, retrieve beside the receipt
|
// We're deriving many fields from the block body, retrieve beside the receipt
|
||||||
receipts := ReadRawReceipts(db, hash, number)
|
receipts := ReadRawReceipts(db, hash, number)
|
||||||
if receipts == nil {
|
if receipts == nil {
|
||||||
@ -643,7 +643,7 @@ func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *para
|
|||||||
} else {
|
} else {
|
||||||
baseFee = header.BaseFee
|
baseFee = header.BaseFee
|
||||||
}
|
}
|
||||||
if err := receipts.DeriveFields(config, hash, number, baseFee, body.Transactions); err != nil {
|
if err := receipts.DeriveFields(config, hash, number, time, baseFee, body.Transactions); err != nil {
|
||||||
log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
|
log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ func TestBlockReceiptStorage(t *testing.T) {
|
|||||||
|
|
||||||
// Check that no receipt entries are in a pristine database
|
// Check that no receipt entries are in a pristine database
|
||||||
hash := common.BytesToHash([]byte{0x03, 0x14})
|
hash := common.BytesToHash([]byte{0x03, 0x14})
|
||||||
if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) != 0 {
|
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 {
|
||||||
t.Fatalf("non existent receipts returned: %v", rs)
|
t.Fatalf("non existent receipts returned: %v", rs)
|
||||||
}
|
}
|
||||||
// Insert the body that corresponds to the receipts
|
// Insert the body that corresponds to the receipts
|
||||||
@ -387,7 +387,7 @@ func TestBlockReceiptStorage(t *testing.T) {
|
|||||||
|
|
||||||
// Insert the receipt slice into the database and check presence
|
// Insert the receipt slice into the database and check presence
|
||||||
WriteReceipts(db, hash, 0, receipts)
|
WriteReceipts(db, hash, 0, receipts)
|
||||||
if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) == 0 {
|
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) == 0 {
|
||||||
t.Fatalf("no receipts returned")
|
t.Fatalf("no receipts returned")
|
||||||
} else {
|
} else {
|
||||||
if err := checkReceiptsRLP(rs, receipts); err != nil {
|
if err := checkReceiptsRLP(rs, receipts); err != nil {
|
||||||
@ -396,7 +396,7 @@ func TestBlockReceiptStorage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// Delete the body and ensure that the receipts are no longer returned (metadata can't be recomputed)
|
// Delete the body and ensure that the receipts are no longer returned (metadata can't be recomputed)
|
||||||
DeleteBody(db, hash, 0)
|
DeleteBody(db, hash, 0)
|
||||||
if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); rs != nil {
|
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); rs != nil {
|
||||||
t.Fatalf("receipts returned when body was deleted: %v", rs)
|
t.Fatalf("receipts returned when body was deleted: %v", rs)
|
||||||
}
|
}
|
||||||
// Ensure that receipts without metadata can be returned without the block body too
|
// Ensure that receipts without metadata can be returned without the block body too
|
||||||
@ -407,7 +407,7 @@ func TestBlockReceiptStorage(t *testing.T) {
|
|||||||
WriteBody(db, hash, 0, body)
|
WriteBody(db, hash, 0, body)
|
||||||
|
|
||||||
DeleteReceipts(db, hash, 0)
|
DeleteReceipts(db, hash, 0)
|
||||||
if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) != 0 {
|
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 {
|
||||||
t.Fatalf("deleted receipts returned: %v", rs)
|
t.Fatalf("deleted receipts returned: %v", rs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -727,7 +727,7 @@ func TestReadLogs(t *testing.T) {
|
|||||||
|
|
||||||
hash := common.BytesToHash([]byte{0x03, 0x14})
|
hash := common.BytesToHash([]byte{0x03, 0x14})
|
||||||
// Check that no receipt entries are in a pristine database
|
// Check that no receipt entries are in a pristine database
|
||||||
if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) != 0 {
|
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 {
|
||||||
t.Fatalf("non existent receipts returned: %v", rs)
|
t.Fatalf("non existent receipts returned: %v", rs)
|
||||||
}
|
}
|
||||||
// Insert the body that corresponds to the receipts
|
// Insert the body that corresponds to the receipts
|
||||||
|
@ -130,8 +130,12 @@ func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig)
|
|||||||
if blockHash == (common.Hash{}) {
|
if blockHash == (common.Hash{}) {
|
||||||
return nil, common.Hash{}, 0, 0
|
return nil, common.Hash{}, 0, 0
|
||||||
}
|
}
|
||||||
|
blockHeader := ReadHeader(db, blockHash, *blockNumber)
|
||||||
|
if blockHeader == nil {
|
||||||
|
return nil, common.Hash{}, 0, 0
|
||||||
|
}
|
||||||
// Read all the receipts from the block and return the one with the matching hash
|
// Read all the receipts from the block and return the one with the matching hash
|
||||||
receipts := ReadReceipts(db, blockHash, *blockNumber, config)
|
receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config)
|
||||||
for receiptIndex, receipt := range receipts {
|
for receiptIndex, receipt := range receipts {
|
||||||
if receipt.TxHash == hash {
|
if receipt.TxHash == hash {
|
||||||
return receipt, blockHash, *blockNumber, uint64(receiptIndex)
|
return receipt, blockHash, *blockNumber, uint64(receiptIndex)
|
||||||
|
@ -53,7 +53,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
|||||||
gaspool = new(GasPool).AddGas(block.GasLimit())
|
gaspool = new(GasPool).AddGas(block.GasLimit())
|
||||||
blockContext = NewEVMBlockContext(header, p.bc, nil)
|
blockContext = NewEVMBlockContext(header, p.bc, nil)
|
||||||
evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
|
evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
|
||||||
signer = types.MakeSigner(p.config, header.Number)
|
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
||||||
)
|
)
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
byzantium := p.config.IsByzantium(block.Number())
|
byzantium := p.config.IsByzantium(block.Number())
|
||||||
|
@ -70,11 +70,14 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||||||
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
var (
|
||||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
|
context = NewEVMBlockContext(header, p.bc, nil)
|
||||||
|
vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
|
||||||
|
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
||||||
|
)
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee)
|
msg, err := TransactionToMessage(tx, signer, header.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||||
}
|
}
|
||||||
@ -147,7 +150,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
|
|||||||
// for the transaction, gas used and an error if the transaction failed,
|
// for the transaction, gas used and an error if the transaction failed,
|
||||||
// indicating the block was invalid.
|
// indicating the block was invalid.
|
||||||
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
|
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
|
||||||
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee)
|
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -606,6 +606,10 @@ func (pool *TxPool) validateTxBasics(tx *types.Transaction, local bool) error {
|
|||||||
if !pool.eip1559.Load() && tx.Type() == types.DynamicFeeTxType {
|
if !pool.eip1559.Load() && tx.Type() == types.DynamicFeeTxType {
|
||||||
return core.ErrTxTypeNotSupported
|
return core.ErrTxTypeNotSupported
|
||||||
}
|
}
|
||||||
|
// Reject blob transactions forever, those will have their own pool.
|
||||||
|
if tx.Type() == types.BlobTxType {
|
||||||
|
return core.ErrTxTypeNotSupported
|
||||||
|
}
|
||||||
// Reject transactions over defined size to prevent DOS attacks
|
// Reject transactions over defined size to prevent DOS attacks
|
||||||
if tx.Size() > txMaxSize {
|
if tx.Size() > txMaxSize {
|
||||||
return ErrOversizedData
|
return ErrOversizedData
|
||||||
|
@ -313,8 +313,8 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) {
|
|||||||
|
|
||||||
// DeriveFields fills the receipts with their computed fields based on consensus
|
// DeriveFields fills the receipts with their computed fields based on consensus
|
||||||
// data and contextual infos like containing block and transactions.
|
// data and contextual infos like containing block and transactions.
|
||||||
func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, number uint64, baseFee *big.Int, txs []*Transaction) error {
|
func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, number uint64, time uint64, baseFee *big.Int, txs []*Transaction) error {
|
||||||
signer := MakeSigner(config, new(big.Int).SetUint64(number))
|
signer := MakeSigner(config, new(big.Int).SetUint64(number), time)
|
||||||
|
|
||||||
logIndex := uint(0)
|
logIndex := uint(0)
|
||||||
if len(txs) != len(rs) {
|
if len(txs) != len(rs) {
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
"github.com/kylelemons/godebug/diff"
|
"github.com/kylelemons/godebug/diff"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -99,6 +100,8 @@ func TestDeriveFields(t *testing.T) {
|
|||||||
to3 := common.HexToAddress("0x3")
|
to3 := common.HexToAddress("0x3")
|
||||||
to4 := common.HexToAddress("0x4")
|
to4 := common.HexToAddress("0x4")
|
||||||
to5 := common.HexToAddress("0x5")
|
to5 := common.HexToAddress("0x5")
|
||||||
|
to6 := common.HexToAddress("0x6")
|
||||||
|
to7 := common.HexToAddress("0x7")
|
||||||
txs := Transactions{
|
txs := Transactions{
|
||||||
NewTx(&LegacyTx{
|
NewTx(&LegacyTx{
|
||||||
Nonce: 1,
|
Nonce: 1,
|
||||||
@ -127,19 +130,39 @@ func TestDeriveFields(t *testing.T) {
|
|||||||
Value: big.NewInt(4),
|
Value: big.NewInt(4),
|
||||||
Gas: 4,
|
Gas: 4,
|
||||||
GasTipCap: big.NewInt(44),
|
GasTipCap: big.NewInt(44),
|
||||||
GasFeeCap: big.NewInt(1045),
|
GasFeeCap: big.NewInt(1044),
|
||||||
}),
|
}),
|
||||||
NewTx(&DynamicFeeTx{
|
NewTx(&DynamicFeeTx{
|
||||||
To: &to5,
|
To: &to5,
|
||||||
Nonce: 5,
|
Nonce: 5,
|
||||||
Value: big.NewInt(5),
|
Value: big.NewInt(5),
|
||||||
Gas: 5,
|
Gas: 5,
|
||||||
GasTipCap: big.NewInt(56),
|
GasTipCap: big.NewInt(55),
|
||||||
GasFeeCap: big.NewInt(1055),
|
GasFeeCap: big.NewInt(1055),
|
||||||
}),
|
}),
|
||||||
|
// EIP-4844 transactions.
|
||||||
|
NewTx(&BlobTx{
|
||||||
|
To: &to6,
|
||||||
|
Nonce: 6,
|
||||||
|
Value: uint256.NewInt(6),
|
||||||
|
Gas: 6,
|
||||||
|
GasTipCap: uint256.NewInt(66),
|
||||||
|
GasFeeCap: uint256.NewInt(1066),
|
||||||
|
BlobFeeCap: uint256.NewInt(100066),
|
||||||
|
}),
|
||||||
|
NewTx(&BlobTx{
|
||||||
|
To: &to7,
|
||||||
|
Nonce: 7,
|
||||||
|
Value: uint256.NewInt(7),
|
||||||
|
Gas: 7,
|
||||||
|
GasTipCap: uint256.NewInt(77),
|
||||||
|
GasFeeCap: uint256.NewInt(1077),
|
||||||
|
BlobFeeCap: uint256.NewInt(100077),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
blockNumber := big.NewInt(1)
|
blockNumber := big.NewInt(1)
|
||||||
|
blockTime := uint64(2)
|
||||||
blockHash := common.BytesToHash([]byte{0x03, 0x14})
|
blockHash := common.BytesToHash([]byte{0x03, 0x14})
|
||||||
|
|
||||||
// Create the corresponding receipts
|
// Create the corresponding receipts
|
||||||
@ -246,12 +269,38 @@ func TestDeriveFields(t *testing.T) {
|
|||||||
BlockNumber: blockNumber,
|
BlockNumber: blockNumber,
|
||||||
TransactionIndex: 4,
|
TransactionIndex: 4,
|
||||||
},
|
},
|
||||||
|
&Receipt{
|
||||||
|
Type: BlobTxType,
|
||||||
|
PostState: common.Hash{6}.Bytes(),
|
||||||
|
CumulativeGasUsed: 21,
|
||||||
|
Logs: []*Log{},
|
||||||
|
// derived fields:
|
||||||
|
TxHash: txs[5].Hash(),
|
||||||
|
GasUsed: 6,
|
||||||
|
EffectiveGasPrice: big.NewInt(1066),
|
||||||
|
BlockHash: blockHash,
|
||||||
|
BlockNumber: blockNumber,
|
||||||
|
TransactionIndex: 5,
|
||||||
|
},
|
||||||
|
&Receipt{
|
||||||
|
Type: BlobTxType,
|
||||||
|
PostState: common.Hash{7}.Bytes(),
|
||||||
|
CumulativeGasUsed: 28,
|
||||||
|
Logs: []*Log{},
|
||||||
|
// derived fields:
|
||||||
|
TxHash: txs[6].Hash(),
|
||||||
|
GasUsed: 7,
|
||||||
|
EffectiveGasPrice: big.NewInt(1077),
|
||||||
|
BlockHash: blockHash,
|
||||||
|
BlockNumber: blockNumber,
|
||||||
|
TransactionIndex: 6,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-derive receipts.
|
// Re-derive receipts.
|
||||||
basefee := big.NewInt(1000)
|
basefee := big.NewInt(1000)
|
||||||
derivedReceipts := clearComputedFieldsOnReceipts(receipts)
|
derivedReceipts := clearComputedFieldsOnReceipts(receipts)
|
||||||
err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), basefee, txs)
|
err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), blockTime, basefee, txs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("DeriveFields(...) = %v, want <nil>", err)
|
t.Fatalf("DeriveFields(...) = %v, want <nil>", err)
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,10 @@ var (
|
|||||||
|
|
||||||
// Transaction types.
|
// Transaction types.
|
||||||
const (
|
const (
|
||||||
LegacyTxType = iota
|
LegacyTxType = 0x00
|
||||||
AccessListTxType
|
AccessListTxType = 0x01
|
||||||
DynamicFeeTxType
|
DynamicFeeTxType = 0x02
|
||||||
|
BlobTxType = 0x03
|
||||||
)
|
)
|
||||||
|
|
||||||
// Transaction is an Ethereum transaction.
|
// Transaction is an Ethereum transaction.
|
||||||
@ -82,6 +83,9 @@ type TxData interface {
|
|||||||
value() *big.Int
|
value() *big.Int
|
||||||
nonce() uint64
|
nonce() uint64
|
||||||
to() *common.Address
|
to() *common.Address
|
||||||
|
blobGas() uint64
|
||||||
|
blobGasFeeCap() *big.Int
|
||||||
|
blobHashes() []common.Hash
|
||||||
|
|
||||||
rawSignatureValues() (v, r, s *big.Int)
|
rawSignatureValues() (v, r, s *big.Int)
|
||||||
setSignatureValues(chainID, v, r, s *big.Int)
|
setSignatureValues(chainID, v, r, s *big.Int)
|
||||||
@ -192,6 +196,10 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
|
|||||||
var inner DynamicFeeTx
|
var inner DynamicFeeTx
|
||||||
err := rlp.DecodeBytes(b[1:], &inner)
|
err := rlp.DecodeBytes(b[1:], &inner)
|
||||||
return &inner, err
|
return &inner, err
|
||||||
|
case BlobTxType:
|
||||||
|
var inner BlobTx
|
||||||
|
err := rlp.DecodeBytes(b[1:], &inner) // TODO(karalabe): This needs to be ssz
|
||||||
|
return &inner, err
|
||||||
default:
|
default:
|
||||||
return nil, ErrTxTypeNotSupported
|
return nil, ErrTxTypeNotSupported
|
||||||
}
|
}
|
||||||
@ -281,6 +289,15 @@ func (tx *Transaction) GasTipCap() *big.Int { return new(big.Int).Set(tx.inner.g
|
|||||||
// GasFeeCap returns the fee cap per gas of the transaction.
|
// GasFeeCap returns the fee cap per gas of the transaction.
|
||||||
func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) }
|
func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) }
|
||||||
|
|
||||||
|
// BlobGas returns the data gas limit of the transaction for blob transactions, 0 otherwise.
|
||||||
|
func (tx *Transaction) BlobGas() uint64 { return tx.inner.blobGas() }
|
||||||
|
|
||||||
|
// BlobGasFeeCap returns the data gas fee cap per data gas of the transaction for blob transactions, nil otherwise.
|
||||||
|
func (tx *Transaction) BlobGasFeeCap() *big.Int { return tx.inner.blobGasFeeCap() }
|
||||||
|
|
||||||
|
// BlobHashes returns the hases of the blob commitments for blob transactions, nil otherwise.
|
||||||
|
func (tx *Transaction) BlobHashes() []common.Hash { return tx.inner.blobHashes() }
|
||||||
|
|
||||||
// Value returns the ether amount of the transaction.
|
// Value returns the ether amount of the transaction.
|
||||||
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }
|
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }
|
||||||
|
|
||||||
@ -293,9 +310,12 @@ func (tx *Transaction) To() *common.Address {
|
|||||||
return copyAddressPtr(tx.inner.to())
|
return copyAddressPtr(tx.inner.to())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cost returns gas * gasPrice + value.
|
// Cost returns (gas * gasPrice) + (blobGas * blobGasPrice) + value.
|
||||||
func (tx *Transaction) Cost() *big.Int {
|
func (tx *Transaction) Cost() *big.Int {
|
||||||
total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))
|
total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))
|
||||||
|
if tx.Type() == BlobTxType {
|
||||||
|
total.Add(total, new(big.Int).Mul(tx.BlobGasFeeCap(), new(big.Int).SetUint64(tx.BlobGas())))
|
||||||
|
}
|
||||||
total.Add(total, tx.Value())
|
total.Add(total, tx.Value())
|
||||||
return total
|
return total
|
||||||
}
|
}
|
||||||
@ -364,6 +384,16 @@ func (tx *Transaction) EffectiveGasTipIntCmp(other *big.Int, baseFee *big.Int) i
|
|||||||
return tx.EffectiveGasTipValue(baseFee).Cmp(other)
|
return tx.EffectiveGasTipValue(baseFee).Cmp(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlobGasFeeCapCmp compares the blob fee cap of two transactions.
|
||||||
|
func (tx *Transaction) BlobGasFeeCapCmp(other *Transaction) int {
|
||||||
|
return tx.inner.blobGasFeeCap().Cmp(other.inner.blobGasFeeCap())
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlobGasFeeCapIntCmp compares the blob fee cap of the transaction against the given blob fee cap.
|
||||||
|
func (tx *Transaction) BlobGasFeeCapIntCmp(other *big.Int) int {
|
||||||
|
return tx.inner.blobGasFeeCap().Cmp(other)
|
||||||
|
}
|
||||||
|
|
||||||
// Hash returns the transaction hash.
|
// Hash returns the transaction hash.
|
||||||
func (tx *Transaction) Hash() common.Hash {
|
func (tx *Transaction) Hash() common.Hash {
|
||||||
if hash := tx.hash.Load(); hash != nil {
|
if hash := tx.hash.Load(); hash != nil {
|
||||||
@ -387,7 +417,11 @@ func (tx *Transaction) Size() uint64 {
|
|||||||
return size.(uint64)
|
return size.(uint64)
|
||||||
}
|
}
|
||||||
c := writeCounter(0)
|
c := writeCounter(0)
|
||||||
|
if tx.Type() == BlobTxType {
|
||||||
|
rlp.Encode(&c, &tx.inner) // TODO(karalabe): Replace with SSZ encoding
|
||||||
|
} else {
|
||||||
rlp.Encode(&c, &tx.inner)
|
rlp.Encode(&c, &tx.inner)
|
||||||
|
}
|
||||||
|
|
||||||
size := uint64(c)
|
size := uint64(c)
|
||||||
if tx.Type() != LegacyTxType {
|
if tx.Type() != LegacyTxType {
|
||||||
|
@ -37,9 +37,11 @@ type sigCache struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MakeSigner returns a Signer based on the given chain config and block number.
|
// MakeSigner returns a Signer based on the given chain config and block number.
|
||||||
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer {
|
||||||
var signer Signer
|
var signer Signer
|
||||||
switch {
|
switch {
|
||||||
|
case config.IsCancun(blockTime):
|
||||||
|
signer = NewCancunSigner(config.ChainID)
|
||||||
case config.IsLondon(blockNumber):
|
case config.IsLondon(blockNumber):
|
||||||
signer = NewLondonSigner(config.ChainID)
|
signer = NewLondonSigner(config.ChainID)
|
||||||
case config.IsBerlin(blockNumber):
|
case config.IsBerlin(blockNumber):
|
||||||
@ -63,6 +65,9 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
|||||||
// have the current block number available, use MakeSigner instead.
|
// have the current block number available, use MakeSigner instead.
|
||||||
func LatestSigner(config *params.ChainConfig) Signer {
|
func LatestSigner(config *params.ChainConfig) Signer {
|
||||||
if config.ChainID != nil {
|
if config.ChainID != nil {
|
||||||
|
if config.CancunTime != nil {
|
||||||
|
return NewCancunSigner(config.ChainID)
|
||||||
|
}
|
||||||
if config.LondonBlock != nil {
|
if config.LondonBlock != nil {
|
||||||
return NewLondonSigner(config.ChainID)
|
return NewLondonSigner(config.ChainID)
|
||||||
}
|
}
|
||||||
@ -87,7 +92,7 @@ func LatestSignerForChainID(chainID *big.Int) Signer {
|
|||||||
if chainID == nil {
|
if chainID == nil {
|
||||||
return HomesteadSigner{}
|
return HomesteadSigner{}
|
||||||
}
|
}
|
||||||
return NewLondonSigner(chainID)
|
return NewCancunSigner(chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignTx signs the transaction using the given signer and private key.
|
// SignTx signs the transaction using the given signer and private key.
|
||||||
@ -170,6 +175,75 @@ type Signer interface {
|
|||||||
Equal(Signer) bool
|
Equal(Signer) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type cancunSigner struct{ londonSigner }
|
||||||
|
|
||||||
|
// NewCancunSigner returns a signer that accepts
|
||||||
|
// - EIP-4844 blob transactions
|
||||||
|
// - EIP-1559 dynamic fee transactions
|
||||||
|
// - EIP-2930 access list transactions,
|
||||||
|
// - EIP-155 replay protected transactions, and
|
||||||
|
// - legacy Homestead transactions.
|
||||||
|
func NewCancunSigner(chainId *big.Int) Signer {
|
||||||
|
return cancunSigner{londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s cancunSigner) Sender(tx *Transaction) (common.Address, error) {
|
||||||
|
if tx.Type() != BlobTxType {
|
||||||
|
return s.londonSigner.Sender(tx)
|
||||||
|
}
|
||||||
|
V, R, S := tx.RawSignatureValues()
|
||||||
|
// Blob txs are defined to use 0 and 1 as their recovery
|
||||||
|
// id, add 27 to become equivalent to unprotected Homestead signatures.
|
||||||
|
V = new(big.Int).Add(V, big.NewInt(27))
|
||||||
|
if tx.ChainId().Cmp(s.chainId) != 0 {
|
||||||
|
return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId)
|
||||||
|
}
|
||||||
|
return recoverPlain(s.Hash(tx), R, S, V, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s cancunSigner) Equal(s2 Signer) bool {
|
||||||
|
x, ok := s2.(cancunSigner)
|
||||||
|
return ok && x.chainId.Cmp(s.chainId) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s cancunSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) {
|
||||||
|
txdata, ok := tx.inner.(*BlobTx)
|
||||||
|
if !ok {
|
||||||
|
return s.londonSigner.SignatureValues(tx, sig)
|
||||||
|
}
|
||||||
|
// Check that chain ID of tx matches the signer. We also accept ID zero here,
|
||||||
|
// because it indicates that the chain ID was not specified in the tx.
|
||||||
|
if txdata.ChainID.Sign() != 0 && txdata.ChainID.ToBig().Cmp(s.chainId) != 0 {
|
||||||
|
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
|
||||||
|
}
|
||||||
|
R, S, _ = decodeSignature(sig)
|
||||||
|
V = big.NewInt(int64(sig[64]))
|
||||||
|
return R, S, V, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash returns the hash to be signed by the sender.
|
||||||
|
// It does not uniquely identify the transaction.
|
||||||
|
func (s cancunSigner) Hash(tx *Transaction) common.Hash {
|
||||||
|
if tx.Type() != BlobTxType {
|
||||||
|
return s.londonSigner.Hash(tx)
|
||||||
|
}
|
||||||
|
return prefixedRlpHash(
|
||||||
|
tx.Type(),
|
||||||
|
[]interface{}{
|
||||||
|
s.chainId,
|
||||||
|
tx.Nonce(),
|
||||||
|
tx.GasTipCap(),
|
||||||
|
tx.GasFeeCap(),
|
||||||
|
tx.Gas(),
|
||||||
|
tx.To(),
|
||||||
|
tx.Value(),
|
||||||
|
tx.Data(),
|
||||||
|
tx.AccessList(),
|
||||||
|
tx.BlobGasFeeCap(),
|
||||||
|
tx.BlobHashes(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type londonSigner struct{ eip2930Signer }
|
type londonSigner struct{ eip2930Signer }
|
||||||
|
|
||||||
// NewLondonSigner returns a signer that accepts
|
// NewLondonSigner returns a signer that accepts
|
||||||
|
@ -105,6 +105,9 @@ func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
|||||||
func (tx *AccessListTx) value() *big.Int { return tx.Value }
|
func (tx *AccessListTx) value() *big.Int { return tx.Value }
|
||||||
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
|
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *AccessListTx) to() *common.Address { return tx.To }
|
func (tx *AccessListTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *AccessListTx) blobGas() uint64 { return 0 }
|
||||||
|
func (tx *AccessListTx) blobGasFeeCap() *big.Int { return nil }
|
||||||
|
func (tx *AccessListTx) blobHashes() []common.Hash { return nil }
|
||||||
|
|
||||||
func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
return dst.Set(tx.GasPrice)
|
return dst.Set(tx.GasPrice)
|
||||||
|
132
core/types/tx_blob.go
Normal file
132
core/types/tx_blob.go
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2023 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BlobTx represents an EIP-4844 transaction.
|
||||||
|
type BlobTx struct {
|
||||||
|
ChainID *uint256.Int
|
||||||
|
Nonce uint64
|
||||||
|
GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas
|
||||||
|
GasFeeCap *uint256.Int // a.k.a. maxFeePerGas
|
||||||
|
Gas uint64
|
||||||
|
To *common.Address // `rlp:"nil"` // nil means contract creation
|
||||||
|
Value *uint256.Int
|
||||||
|
Data []byte
|
||||||
|
AccessList AccessList
|
||||||
|
BlobFeeCap *uint256.Int // a.k.a. maxFeePerDataGas
|
||||||
|
BlobHashes []common.Hash
|
||||||
|
|
||||||
|
// Signature values
|
||||||
|
V *uint256.Int `json:"v" gencodec:"required"`
|
||||||
|
R *uint256.Int `json:"r" gencodec:"required"`
|
||||||
|
S *uint256.Int `json:"s" gencodec:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy creates a deep copy of the transaction data and initializes all fields.
|
||||||
|
func (tx *BlobTx) copy() TxData {
|
||||||
|
cpy := &BlobTx{
|
||||||
|
Nonce: tx.Nonce,
|
||||||
|
To: copyAddressPtr(tx.To),
|
||||||
|
Data: common.CopyBytes(tx.Data),
|
||||||
|
Gas: tx.Gas,
|
||||||
|
// These are copied below.
|
||||||
|
AccessList: make(AccessList, len(tx.AccessList)),
|
||||||
|
BlobHashes: make([]common.Hash, len(tx.BlobHashes)),
|
||||||
|
Value: new(uint256.Int),
|
||||||
|
ChainID: new(uint256.Int),
|
||||||
|
GasTipCap: new(uint256.Int),
|
||||||
|
GasFeeCap: new(uint256.Int),
|
||||||
|
BlobFeeCap: new(uint256.Int),
|
||||||
|
V: new(uint256.Int),
|
||||||
|
R: new(uint256.Int),
|
||||||
|
S: new(uint256.Int),
|
||||||
|
}
|
||||||
|
copy(cpy.AccessList, tx.AccessList)
|
||||||
|
copy(cpy.BlobHashes, tx.BlobHashes)
|
||||||
|
|
||||||
|
if tx.Value != nil {
|
||||||
|
cpy.Value.Set(tx.Value)
|
||||||
|
}
|
||||||
|
if tx.ChainID != nil {
|
||||||
|
cpy.ChainID.Set(tx.ChainID)
|
||||||
|
}
|
||||||
|
if tx.GasTipCap != nil {
|
||||||
|
cpy.GasTipCap.Set(tx.GasTipCap)
|
||||||
|
}
|
||||||
|
if tx.GasFeeCap != nil {
|
||||||
|
cpy.GasFeeCap.Set(tx.GasFeeCap)
|
||||||
|
}
|
||||||
|
if tx.BlobFeeCap != nil {
|
||||||
|
cpy.BlobFeeCap.Set(tx.BlobFeeCap)
|
||||||
|
}
|
||||||
|
if tx.V != nil {
|
||||||
|
cpy.V.Set(tx.V)
|
||||||
|
}
|
||||||
|
if tx.R != nil {
|
||||||
|
cpy.R.Set(tx.R)
|
||||||
|
}
|
||||||
|
if tx.S != nil {
|
||||||
|
cpy.S.Set(tx.S)
|
||||||
|
}
|
||||||
|
return cpy
|
||||||
|
}
|
||||||
|
|
||||||
|
// accessors for innerTx.
|
||||||
|
func (tx *BlobTx) txType() byte { return BlobTxType }
|
||||||
|
func (tx *BlobTx) chainID() *big.Int { return tx.ChainID.ToBig() }
|
||||||
|
func (tx *BlobTx) accessList() AccessList { return tx.AccessList }
|
||||||
|
func (tx *BlobTx) data() []byte { return tx.Data }
|
||||||
|
func (tx *BlobTx) gas() uint64 { return tx.Gas }
|
||||||
|
func (tx *BlobTx) gasFeeCap() *big.Int { return tx.GasFeeCap.ToBig() }
|
||||||
|
func (tx *BlobTx) gasTipCap() *big.Int { return tx.GasTipCap.ToBig() }
|
||||||
|
func (tx *BlobTx) gasPrice() *big.Int { return tx.GasFeeCap.ToBig() }
|
||||||
|
func (tx *BlobTx) value() *big.Int { return tx.Value.ToBig() }
|
||||||
|
func (tx *BlobTx) nonce() uint64 { return tx.Nonce }
|
||||||
|
func (tx *BlobTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *BlobTx) blobGas() uint64 { return params.BlobTxDataGasPerBlob * uint64(len(tx.BlobHashes)) }
|
||||||
|
func (tx *BlobTx) blobGasFeeCap() *big.Int { return tx.BlobFeeCap.ToBig() }
|
||||||
|
func (tx *BlobTx) blobHashes() []common.Hash { return tx.BlobHashes }
|
||||||
|
|
||||||
|
func (tx *BlobTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
|
if baseFee == nil {
|
||||||
|
return dst.Set(tx.GasFeeCap.ToBig())
|
||||||
|
}
|
||||||
|
tip := dst.Sub(tx.GasFeeCap.ToBig(), baseFee)
|
||||||
|
if tip.Cmp(tx.GasTipCap.ToBig()) > 0 {
|
||||||
|
tip.Set(tx.GasTipCap.ToBig())
|
||||||
|
}
|
||||||
|
return tip.Add(tip, baseFee)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *BlobTx) rawSignatureValues() (v, r, s *big.Int) {
|
||||||
|
return tx.V.ToBig(), tx.R.ToBig(), tx.S.ToBig()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *BlobTx) setSignatureValues(chainID, v, r, s *big.Int) {
|
||||||
|
tx.ChainID.SetFromBig(chainID)
|
||||||
|
tx.V.SetFromBig(v)
|
||||||
|
tx.R.SetFromBig(r)
|
||||||
|
tx.S.SetFromBig(s)
|
||||||
|
}
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DynamicFeeTx represents an EIP-1559 transaction.
|
||||||
type DynamicFeeTx struct {
|
type DynamicFeeTx struct {
|
||||||
ChainID *big.Int
|
ChainID *big.Int
|
||||||
Nonce uint64
|
Nonce uint64
|
||||||
@ -93,6 +94,9 @@ func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap }
|
|||||||
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
|
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
|
||||||
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
|
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
|
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *DynamicFeeTx) blobGas() uint64 { return 0 }
|
||||||
|
func (tx *DynamicFeeTx) blobGasFeeCap() *big.Int { return nil }
|
||||||
|
func (tx *DynamicFeeTx) blobHashes() []common.Hash { return nil }
|
||||||
|
|
||||||
func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LegacyTx is the transaction data of regular Ethereum transactions.
|
// LegacyTx is the transaction data of the original Ethereum transactions.
|
||||||
type LegacyTx struct {
|
type LegacyTx struct {
|
||||||
Nonce uint64 // nonce of sender account
|
Nonce uint64 // nonce of sender account
|
||||||
GasPrice *big.Int // wei per gas
|
GasPrice *big.Int // wei per gas
|
||||||
@ -102,6 +102,9 @@ func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
|||||||
func (tx *LegacyTx) value() *big.Int { return tx.Value }
|
func (tx *LegacyTx) value() *big.Int { return tx.Value }
|
||||||
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
|
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *LegacyTx) to() *common.Address { return tx.To }
|
func (tx *LegacyTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *LegacyTx) blobGas() uint64 { return 0 }
|
||||||
|
func (tx *LegacyTx) blobGasFeeCap() *big.Int { return nil }
|
||||||
|
func (tx *LegacyTx) blobHashes() []common.Hash { return nil }
|
||||||
|
|
||||||
func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
return dst.Set(tx.GasPrice)
|
return dst.Set(tx.GasPrice)
|
||||||
|
@ -42,7 +42,7 @@ func makeChain(n int, seed byte, parent *types.Block, empty bool) ([]*types.Bloc
|
|||||||
block.SetCoinbase(common.Address{seed})
|
block.SetCoinbase(common.Address{seed})
|
||||||
// Add one tx to every secondblock
|
// Add one tx to every secondblock
|
||||||
if !empty && i%2 == 0 {
|
if !empty && i%2 == 0 {
|
||||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -168,7 +168,7 @@ func (tc *testChain) generate(n int, seed byte, parent *types.Block, heavy bool)
|
|||||||
}
|
}
|
||||||
// Include transactions to the miner to make blocks more interesting.
|
// Include transactions to the miner to make blocks more interesting.
|
||||||
if parent == tc.blocks[0] && i%22 == 0 {
|
if parent == tc.blocks[0] && i%22 == 0 {
|
||||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -58,7 +58,7 @@ func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common
|
|||||||
|
|
||||||
// If the block number is multiple of 3, send a bonus transaction to the miner
|
// If the block number is multiple of 3, send a bonus transaction to the miner
|
||||||
if parent == genesis && i%3 == 0 {
|
if parent == genesis && i%3 == 0 {
|
||||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -111,7 +111,9 @@ func (b *testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.
|
|||||||
|
|
||||||
func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
||||||
if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil {
|
if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil {
|
||||||
return rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig), nil
|
if header := rawdb.ReadHeader(b.db, hash, *number); header != nil {
|
||||||
|
return rawdb.ReadReceipts(b.db, hash, *number, header.Time, params.TestChainConfig), nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) {
|
|||||||
results []*big.Int
|
results []*big.Int
|
||||||
)
|
)
|
||||||
for sent < oracle.checkBlocks && number > 0 {
|
for sent < oracle.checkBlocks && number > 0 {
|
||||||
go oracle.getBlockValues(ctx, types.MakeSigner(oracle.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, oracle.ignorePrice, result, quit)
|
go oracle.getBlockValues(ctx, number, sampleNumber, oracle.ignorePrice, result, quit)
|
||||||
sent++
|
sent++
|
||||||
exp++
|
exp++
|
||||||
number--
|
number--
|
||||||
@ -199,7 +199,7 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) {
|
|||||||
// meaningful returned, try to query more blocks. But the maximum
|
// meaningful returned, try to query more blocks. But the maximum
|
||||||
// is 2*checkBlocks.
|
// is 2*checkBlocks.
|
||||||
if len(res.values) == 1 && len(results)+1+exp < oracle.checkBlocks*2 && number > 0 {
|
if len(res.values) == 1 && len(results)+1+exp < oracle.checkBlocks*2 && number > 0 {
|
||||||
go oracle.getBlockValues(ctx, types.MakeSigner(oracle.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, oracle.ignorePrice, result, quit)
|
go oracle.getBlockValues(ctx, number, sampleNumber, oracle.ignorePrice, result, quit)
|
||||||
sent++
|
sent++
|
||||||
exp++
|
exp++
|
||||||
number--
|
number--
|
||||||
@ -255,7 +255,7 @@ func (s *txSorter) Less(i, j int) bool {
|
|||||||
// and sends it to the result channel. If the block is empty or all transactions
|
// and sends it to the result channel. If the block is empty or all transactions
|
||||||
// are sent by the miner itself(it doesn't make any sense to include this kind of
|
// are sent by the miner itself(it doesn't make any sense to include this kind of
|
||||||
// transaction prices for sampling), nil gasprice is returned.
|
// transaction prices for sampling), nil gasprice is returned.
|
||||||
func (oracle *Oracle) getBlockValues(ctx context.Context, signer types.Signer, blockNum uint64, limit int, ignoreUnder *big.Int, result chan results, quit chan struct{}) {
|
func (oracle *Oracle) getBlockValues(ctx context.Context, blockNum uint64, limit int, ignoreUnder *big.Int, result chan results, quit chan struct{}) {
|
||||||
block, err := oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
|
block, err := oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
|
||||||
if block == nil {
|
if block == nil {
|
||||||
select {
|
select {
|
||||||
@ -264,6 +264,8 @@ func (oracle *Oracle) getBlockValues(ctx context.Context, signer types.Signer, b
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
signer := types.MakeSigner(oracle.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
|
|
||||||
// Sort the transaction by effective tip in ascending sort.
|
// Sort the transaction by effective tip in ascending sort.
|
||||||
txs := make([]*types.Transaction, len(block.Transactions()))
|
txs := make([]*types.Transaction, len(block.Transactions()))
|
||||||
copy(txs, block.Transactions())
|
copy(txs, block.Transactions())
|
||||||
|
@ -209,7 +209,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
|||||||
return nil, vm.BlockContext{}, statedb, release, nil
|
return nil, vm.BlockContext{}, statedb, release, nil
|
||||||
}
|
}
|
||||||
// Recompute transactions up to the target index.
|
// Recompute transactions up to the target index.
|
||||||
signer := types.MakeSigner(eth.blockchain.Config(), block.Number())
|
signer := types.MakeSigner(eth.blockchain.Config(), block.Number(), block.Time())
|
||||||
for idx, tx := range block.Transactions() {
|
for idx, tx := range block.Transactions() {
|
||||||
// Assemble the transaction call message and return if the requested offset
|
// Assemble the transaction call message and return if the requested offset
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||||
|
@ -288,7 +288,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
|||||||
// Fetch and execute the block trace taskCh
|
// Fetch and execute the block trace taskCh
|
||||||
for task := range taskCh {
|
for task := range taskCh {
|
||||||
var (
|
var (
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number())
|
signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time())
|
||||||
blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil)
|
blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil)
|
||||||
)
|
)
|
||||||
// Trace all the transactions contained within
|
// Trace all the transactions contained within
|
||||||
@ -544,7 +544,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
roots []common.Hash
|
roots []common.Hash
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
chainConfig = api.backend.ChainConfig()
|
chainConfig = api.backend.ChainConfig()
|
||||||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
||||||
@ -623,7 +623,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
|||||||
blockHash = block.Hash()
|
blockHash = block.Hash()
|
||||||
is158 = api.backend.ChainConfig().IsEIP158(block.Number())
|
is158 = api.backend.ChainConfig().IsEIP158(block.Number())
|
||||||
blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
results = make([]*txTraceResult, len(txs))
|
results = make([]*txTraceResult, len(txs))
|
||||||
)
|
)
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
@ -656,7 +656,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
|||||||
txs = block.Transactions()
|
txs = block.Transactions()
|
||||||
blockHash = block.Hash()
|
blockHash = block.Hash()
|
||||||
blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
results = make([]*txTraceResult, len(txs))
|
results = make([]*txTraceResult, len(txs))
|
||||||
pend sync.WaitGroup
|
pend sync.WaitGroup
|
||||||
)
|
)
|
||||||
@ -765,7 +765,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
|||||||
// Execute transaction, either tracing all or just the requested one
|
// Execute transaction, either tracing all or just the requested one
|
||||||
var (
|
var (
|
||||||
dumps []string
|
dumps []string
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
chainConfig = api.backend.ChainConfig()
|
chainConfig = api.backend.ChainConfig()
|
||||||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
canon = true
|
canon = true
|
||||||
|
@ -169,7 +169,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
|
|||||||
return nil, vm.BlockContext{}, statedb, release, nil
|
return nil, vm.BlockContext{}, statedb, release, nil
|
||||||
}
|
}
|
||||||
// Recompute transactions up to the target index.
|
// Recompute transactions up to the target index.
|
||||||
signer := types.MakeSigner(b.chainConfig, block.Number())
|
signer := types.MakeSigner(b.chainConfig, block.Number(), block.Time())
|
||||||
for idx, tx := range block.Transactions() {
|
for idx, tx := range block.Transactions() {
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||||
txContext := core.NewEVMTxContext(msg)
|
txContext := core.NewEVMTxContext(msg)
|
||||||
|
@ -121,7 +121,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
|
|||||||
}
|
}
|
||||||
// Configure a blockchain with the given prestate
|
// Configure a blockchain with the given prestate
|
||||||
var (
|
var (
|
||||||
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)))
|
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
|
||||||
origin, _ = signer.Sender(tx)
|
origin, _ = signer.Sender(tx)
|
||||||
txContext = vm.TxContext{
|
txContext = vm.TxContext{
|
||||||
Origin: origin,
|
Origin: origin,
|
||||||
@ -218,7 +218,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
|||||||
if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
|
if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
|
||||||
b.Fatalf("failed to parse testcase input: %v", err)
|
b.Fatalf("failed to parse testcase input: %v", err)
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)))
|
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
|
||||||
msg, err := core.TransactionToMessage(tx, signer, nil)
|
msg, err := core.TransactionToMessage(tx, signer, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
|
@ -85,7 +85,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
|||||||
if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
|
if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
|
||||||
return fmt.Errorf("failed to parse testcase input: %v", err)
|
return fmt.Errorf("failed to parse testcase input: %v", err)
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)))
|
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
|
||||||
origin, _ := signer.Sender(tx)
|
origin, _ := signer.Sender(tx)
|
||||||
txContext := vm.TxContext{
|
txContext := vm.TxContext{
|
||||||
Origin: origin,
|
Origin: origin,
|
||||||
|
@ -92,7 +92,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
|
|||||||
}
|
}
|
||||||
// Configure a blockchain with the given prestate
|
// Configure a blockchain with the given prestate
|
||||||
var (
|
var (
|
||||||
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)))
|
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
|
||||||
origin, _ = signer.Sender(tx)
|
origin, _ = signer.Sender(tx)
|
||||||
txContext = vm.TxContext{
|
txContext = vm.TxContext{
|
||||||
Origin: origin,
|
Origin: origin,
|
||||||
|
@ -1305,8 +1305,8 @@ type RPCTransaction struct {
|
|||||||
|
|
||||||
// newRPCTransaction returns a transaction that will serialize to the RPC
|
// newRPCTransaction returns a transaction that will serialize to the RPC
|
||||||
// representation, with the given location metadata set (if available).
|
// representation, with the given location metadata set (if available).
|
||||||
func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int, config *params.ChainConfig) *RPCTransaction {
|
func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, blockTime uint64, index uint64, baseFee *big.Int, config *params.ChainConfig) *RPCTransaction {
|
||||||
signer := types.MakeSigner(config, new(big.Int).SetUint64(blockNumber))
|
signer := types.MakeSigner(config, new(big.Int).SetUint64(blockNumber), blockTime)
|
||||||
from, _ := types.Sender(signer, tx)
|
from, _ := types.Sender(signer, tx)
|
||||||
v, r, s := tx.RawSignatureValues()
|
v, r, s := tx.RawSignatureValues()
|
||||||
result := &RPCTransaction{
|
result := &RPCTransaction{
|
||||||
@ -1358,13 +1358,17 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
|
|||||||
|
|
||||||
// NewRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
// NewRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
||||||
func NewRPCPendingTransaction(tx *types.Transaction, current *types.Header, config *params.ChainConfig) *RPCTransaction {
|
func NewRPCPendingTransaction(tx *types.Transaction, current *types.Header, config *params.ChainConfig) *RPCTransaction {
|
||||||
var baseFee *big.Int
|
var (
|
||||||
blockNumber := uint64(0)
|
baseFee *big.Int
|
||||||
|
blockNumber = uint64(0)
|
||||||
|
blockTime = uint64(0)
|
||||||
|
)
|
||||||
if current != nil {
|
if current != nil {
|
||||||
baseFee = misc.CalcBaseFee(config, current)
|
baseFee = misc.CalcBaseFee(config, current)
|
||||||
blockNumber = current.Number.Uint64()
|
blockNumber = current.Number.Uint64()
|
||||||
|
blockTime = current.Time
|
||||||
}
|
}
|
||||||
return newRPCTransaction(tx, common.Hash{}, blockNumber, 0, baseFee, config)
|
return newRPCTransaction(tx, common.Hash{}, blockNumber, blockTime, 0, baseFee, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
|
// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
|
||||||
@ -1373,7 +1377,7 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *param
|
|||||||
if index >= uint64(len(txs)) {
|
if index >= uint64(len(txs)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index, b.BaseFee(), config)
|
return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), b.Time(), index, b.BaseFee(), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index.
|
// newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index.
|
||||||
@ -1585,7 +1589,7 @@ func (s *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.H
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return newRPCTransaction(tx, blockHash, blockNumber, index, header.BaseFee, s.b.ChainConfig()), nil
|
return newRPCTransaction(tx, blockHash, blockNumber, header.Time, index, header.BaseFee, s.b.ChainConfig()), nil
|
||||||
}
|
}
|
||||||
// No finalized transaction, try to retrieve it from the pool
|
// No finalized transaction, try to retrieve it from the pool
|
||||||
if tx := s.b.GetPoolTransaction(hash); tx != nil {
|
if tx := s.b.GetPoolTransaction(hash); tx != nil {
|
||||||
@ -1621,7 +1625,10 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.
|
|||||||
// as per specification.
|
// as per specification.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
header, err := s.b.HeaderByHash(ctx, blockHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
receipts, err := s.b.GetReceipts(ctx, blockHash)
|
receipts, err := s.b.GetReceipts(ctx, blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1632,8 +1639,7 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.
|
|||||||
receipt := receipts[index]
|
receipt := receipts[index]
|
||||||
|
|
||||||
// Derive the sender.
|
// Derive the sender.
|
||||||
bigblock := new(big.Int).SetUint64(blockNumber)
|
signer := types.MakeSigner(s.b.ChainConfig(), header.Number, header.Time)
|
||||||
signer := types.MakeSigner(s.b.ChainConfig(), bigblock)
|
|
||||||
from, _ := types.Sender(signer, tx)
|
from, _ := types.Sender(signer, tx)
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
fields := map[string]interface{}{
|
||||||
@ -1697,7 +1703,8 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c
|
|||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
// Print a log with full tx details for manual investigations and interventions
|
// Print a log with full tx details for manual investigations and interventions
|
||||||
signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number)
|
head := b.CurrentBlock()
|
||||||
|
signer := types.MakeSigner(b.ChainConfig(), head.Number, head.Time)
|
||||||
from, err := types.Sender(signer, tx)
|
from, err := types.Sender(signer, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
|
@ -51,7 +51,7 @@ func TestTransaction_RoundTripRpcJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rpcTransaction
|
// rpcTransaction
|
||||||
rpcTx := newRPCTransaction(tx, common.Hash{}, 0, 0, nil, config)
|
rpcTx := newRPCTransaction(tx, common.Hash{}, 0, 0, 0, nil, config)
|
||||||
if data, err := json.Marshal(rpcTx); err != nil {
|
if data, err := json.Marshal(rpcTx); err != nil {
|
||||||
t.Fatalf("test %d: marshalling failed; %v", i, err)
|
t.Fatalf("test %d: marshalling failed; %v", i, err)
|
||||||
} else if err = tx2.UnmarshalJSON(data); err != nil {
|
} else if err = tx2.UnmarshalJSON(data); err != nil {
|
||||||
|
@ -41,7 +41,7 @@ func makeChain(n int, seed byte, parent *types.Block, empty bool) ([]*types.Bloc
|
|||||||
block.SetCoinbase(common.Address{seed})
|
block.SetCoinbase(common.Address{seed})
|
||||||
// Add one tx to every secondblock
|
// Add one tx to every secondblock
|
||||||
if !empty && i%2 == 0 {
|
if !empty && i%2 == 0 {
|
||||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -131,7 +131,7 @@ func (tc *testChain) generate(n int, seed byte, parent *types.Block, heavy bool)
|
|||||||
}
|
}
|
||||||
// Include transactions to the miner to make blocks more interesting.
|
// Include transactions to the miner to make blocks more interesting.
|
||||||
if parent == tc.genesis && i%22 == 0 {
|
if parent == tc.genesis && i%22 == 0 {
|
||||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -57,7 +57,7 @@ func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common
|
|||||||
|
|
||||||
// If the block number is multiple of 3, send a bonus transaction to the miner
|
// If the block number is multiple of 3, send a bonus transaction to the miner
|
||||||
if parent == genesis && i%3 == 0 {
|
if parent == genesis && i%3 == 0 {
|
||||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -371,7 +371,7 @@ func testGetReceipt(t *testing.T, protocol int) {
|
|||||||
block := bc.GetBlockByNumber(i)
|
block := bc.GetBlockByNumber(i)
|
||||||
|
|
||||||
hashes = append(hashes, block.Hash())
|
hashes = append(hashes, block.Hash())
|
||||||
receipts = append(receipts, rawdb.ReadReceipts(server.db, block.Hash(), block.NumberU64(), bc.Config()))
|
receipts = append(receipts, rawdb.ReadReceipts(server.db, block.Hash(), block.NumberU64(), block.Time(), bc.Config()))
|
||||||
}
|
}
|
||||||
// Send the hash request and verify the response
|
// Send the hash request and verify the response
|
||||||
sendRequest(rawPeer.app, GetReceiptsMsg, 42, hashes)
|
sendRequest(rawPeer.app, GetReceiptsMsg, 42, hashes)
|
||||||
|
@ -68,7 +68,9 @@ func odrGetReceipts(ctx context.Context, db ethdb.Database, config *params.Chain
|
|||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
if bc != nil {
|
if bc != nil {
|
||||||
if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
|
if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
|
||||||
receipts = rawdb.ReadReceipts(db, bhash, *number, config)
|
if header := rawdb.ReadHeader(db, bhash, *number); header != nil {
|
||||||
|
receipts = rawdb.ReadReceipts(db, bhash, *number, header.Time, config)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
|
if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
|
||||||
|
@ -57,7 +57,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.
|
|||||||
return nil, vm.BlockContext{}, statedb, release, nil
|
return nil, vm.BlockContext{}, statedb, release, nil
|
||||||
}
|
}
|
||||||
// Recompute transactions up to the target index.
|
// Recompute transactions up to the target index.
|
||||||
signer := types.MakeSigner(leth.blockchain.Config(), block.Number())
|
signer := types.MakeSigner(leth.blockchain.Config(), block.Number(), block.Time())
|
||||||
for idx, tx := range block.Transactions() {
|
for idx, tx := range block.Transactions() {
|
||||||
// Assemble the transaction call message and return if the requested offset
|
// Assemble the transaction call message and return if the requested offset
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||||
|
@ -131,9 +131,10 @@ func TestOdrGetReceiptsLes2(t *testing.T) { testChainOdr(t, 1, odrGetReceipts) }
|
|||||||
func odrGetReceipts(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc *LightChain, bhash common.Hash) ([]byte, error) {
|
func odrGetReceipts(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc *LightChain, bhash common.Hash) ([]byte, error) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
if bc != nil {
|
if bc != nil {
|
||||||
number := rawdb.ReadHeaderNumber(db, bhash)
|
if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
|
||||||
if number != nil {
|
if header := rawdb.ReadHeader(db, bhash, *number); header != nil {
|
||||||
receipts = rawdb.ReadReceipts(db, bhash, *number, bc.Config())
|
receipts = rawdb.ReadReceipts(db, bhash, *number, header.Time, bc.Config())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
number := rawdb.ReadHeaderNumber(db, bhash)
|
number := rawdb.ReadHeaderNumber(db, bhash)
|
||||||
|
@ -175,7 +175,7 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
|
|||||||
genesis := rawdb.ReadCanonicalHash(odr.Database(), 0)
|
genesis := rawdb.ReadCanonicalHash(odr.Database(), 0)
|
||||||
config := rawdb.ReadChainConfig(odr.Database(), genesis)
|
config := rawdb.ReadChainConfig(odr.Database(), genesis)
|
||||||
|
|
||||||
if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.BaseFee(), block.Transactions()); err != nil {
|
if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), block.Transactions()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rawdb.WriteReceipts(odr.Database(), hash, number, receipts)
|
rawdb.WriteReceipts(odr.Database(), hash, number, receipts)
|
||||||
|
@ -801,7 +801,7 @@ func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase co
|
|||||||
|
|
||||||
// Note the passed coinbase may be different with header.Coinbase.
|
// Note the passed coinbase may be different with header.Coinbase.
|
||||||
env := &environment{
|
env := &environment{
|
||||||
signer: types.MakeSigner(w.chainConfig, header.Number),
|
signer: types.MakeSigner(w.chainConfig, header.Number, header.Time),
|
||||||
state: state,
|
state: state,
|
||||||
coinbase: coinbase,
|
coinbase: coinbase,
|
||||||
ancestors: mapset.NewSet[common.Hash](),
|
ancestors: mapset.NewSet[common.Hash](),
|
||||||
|
@ -160,6 +160,7 @@ const (
|
|||||||
RefundQuotient uint64 = 2
|
RefundQuotient uint64 = 2
|
||||||
RefundQuotientEIP3529 uint64 = 5
|
RefundQuotientEIP3529 uint64 = 5
|
||||||
|
|
||||||
|
BlobTxDataGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
|
||||||
BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs
|
BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs
|
||||||
BlobTxDataGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for data gas price
|
BlobTxDataGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for data gas price
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user