mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 03:10:48 +00:00
Merge branch 'master' into fix-blob-range-copy
This commit is contained in:
commit
2da10777a0
20 changed files with 343 additions and 122 deletions
|
|
@ -53,9 +53,9 @@ func (bc *BlobConfig) blobPrice(excessBlobGas uint64) *big.Int {
|
|||
return new(big.Int).Mul(f, big.NewInt(params.BlobTxBlobGasPerBlob))
|
||||
}
|
||||
|
||||
func latestBlobConfig(cfg *params.ChainConfig, time uint64) *BlobConfig {
|
||||
func latestBlobConfig(cfg *params.ChainConfig, time uint64) (BlobConfig, error) {
|
||||
if cfg.BlobScheduleConfig == nil {
|
||||
return nil
|
||||
return BlobConfig{}, errors.New("no blob config")
|
||||
}
|
||||
var (
|
||||
london = cfg.LondonBlock
|
||||
|
|
@ -80,14 +80,14 @@ func latestBlobConfig(cfg *params.ChainConfig, time uint64) *BlobConfig {
|
|||
case cfg.IsCancun(london, time) && s.Cancun != nil:
|
||||
bc = s.Cancun
|
||||
default:
|
||||
return nil
|
||||
return BlobConfig{}, errors.New("no blob config")
|
||||
}
|
||||
|
||||
return &BlobConfig{
|
||||
return BlobConfig{
|
||||
Target: bc.Target,
|
||||
Max: bc.Max,
|
||||
UpdateFraction: bc.UpdateFraction,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// VerifyEIP4844Header verifies the presence of the excessBlobGas field and that
|
||||
|
|
@ -98,8 +98,8 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade
|
|||
panic("bad header pair")
|
||||
}
|
||||
|
||||
bcfg := latestBlobConfig(config, header.Time)
|
||||
if bcfg == nil {
|
||||
bcfg, err := latestBlobConfig(config, header.Time)
|
||||
if err != nil {
|
||||
panic("called before EIP-4844 is active")
|
||||
}
|
||||
|
||||
|
|
@ -130,11 +130,14 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade
|
|||
// blobs on top of the excess blob gas.
|
||||
func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTimestamp uint64) uint64 {
|
||||
isOsaka := config.IsOsaka(config.LondonBlock, headTimestamp)
|
||||
bcfg := latestBlobConfig(config, headTimestamp)
|
||||
bcfg, err := latestBlobConfig(config, headTimestamp)
|
||||
if err != nil {
|
||||
panic("calculating excess blob gas on nil blob config")
|
||||
}
|
||||
return calcExcessBlobGas(isOsaka, bcfg, parent)
|
||||
}
|
||||
|
||||
func calcExcessBlobGas(isOsaka bool, bcfg *BlobConfig, parent *types.Header) uint64 {
|
||||
func calcExcessBlobGas(isOsaka bool, bcfg BlobConfig, parent *types.Header) uint64 {
|
||||
var parentExcessBlobGas, parentBlobGasUsed uint64
|
||||
if parent.ExcessBlobGas != nil {
|
||||
parentExcessBlobGas = *parent.ExcessBlobGas
|
||||
|
|
@ -169,8 +172,8 @@ func calcExcessBlobGas(isOsaka bool, bcfg *BlobConfig, parent *types.Header) uin
|
|||
|
||||
// CalcBlobFee calculates the blobfee from the header's excess blob gas field.
|
||||
func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int {
|
||||
blobConfig := latestBlobConfig(config, header.Time)
|
||||
if blobConfig == nil {
|
||||
blobConfig, err := latestBlobConfig(config, header.Time)
|
||||
if err != nil {
|
||||
panic("calculating blob fee on unsupported fork")
|
||||
}
|
||||
return blobConfig.blobBaseFee(*header.ExcessBlobGas)
|
||||
|
|
@ -178,8 +181,8 @@ func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int {
|
|||
|
||||
// MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp.
|
||||
func MaxBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
|
||||
blobConfig := latestBlobConfig(cfg, time)
|
||||
if blobConfig == nil {
|
||||
blobConfig, err := latestBlobConfig(cfg, time)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return blobConfig.Max
|
||||
|
|
@ -193,8 +196,8 @@ func MaxBlobGasPerBlock(cfg *params.ChainConfig, time uint64) uint64 {
|
|||
// LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the
|
||||
// configuration, regardless of the currently active fork.
|
||||
func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int {
|
||||
bcfg := latestBlobConfig(cfg, math.MaxUint64)
|
||||
if bcfg == nil {
|
||||
bcfg, err := latestBlobConfig(cfg, math.MaxUint64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return bcfg.Max
|
||||
|
|
@ -202,8 +205,8 @@ func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int {
|
|||
|
||||
// TargetBlobsPerBlock returns the target blobs per block for a block at the given timestamp.
|
||||
func TargetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
|
||||
blobConfig := latestBlobConfig(cfg, time)
|
||||
if blobConfig == nil {
|
||||
blobConfig, err := latestBlobConfig(cfg, time)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return blobConfig.Target
|
||||
|
|
|
|||
|
|
@ -80,12 +80,9 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
|
|||
func NewEVMTxContext(msg *Message) vm.TxContext {
|
||||
ctx := vm.TxContext{
|
||||
Origin: msg.From,
|
||||
GasPrice: new(big.Int).Set(msg.GasPrice),
|
||||
GasPrice: uint256.MustFromBig(msg.GasPrice),
|
||||
BlobHashes: msg.BlobHashes,
|
||||
}
|
||||
if msg.BlobGasFeeCap != nil {
|
||||
ctx.BlobFeeCap = new(big.Int).Set(msg.BlobGasFeeCap)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ type journalEntry interface {
|
|||
revert(*StateDB)
|
||||
|
||||
// dirtied returns the Ethereum address modified by this journal entry.
|
||||
dirtied() *common.Address
|
||||
// indicates false if no address was changed.
|
||||
dirtied() (common.Address, bool)
|
||||
|
||||
// copy returns a deep-copied journal entry.
|
||||
copy() journalEntry
|
||||
|
|
@ -100,8 +101,8 @@ func (j *journal) revertToSnapshot(revid int, s *StateDB) {
|
|||
// append inserts a new modification entry to the end of the change journal.
|
||||
func (j *journal) append(entry journalEntry) {
|
||||
j.entries = append(j.entries, entry)
|
||||
if addr := entry.dirtied(); addr != nil {
|
||||
j.dirties[*addr]++
|
||||
if addr, dirty := entry.dirtied(); dirty {
|
||||
j.dirties[addr]++
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,9 +114,9 @@ func (j *journal) revert(statedb *StateDB, snapshot int) {
|
|||
j.entries[i].revert(statedb)
|
||||
|
||||
// Drop any dirty tracking induced by the change
|
||||
if addr := j.entries[i].dirtied(); addr != nil {
|
||||
if j.dirties[*addr]--; j.dirties[*addr] == 0 {
|
||||
delete(j.dirties, *addr)
|
||||
if addr, dirty := j.entries[i].dirtied(); dirty {
|
||||
if j.dirties[addr]--; j.dirties[addr] == 0 {
|
||||
delete(j.dirties, addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -294,8 +295,8 @@ func (ch createObjectChange) revert(s *StateDB) {
|
|||
delete(s.stateObjects, ch.account)
|
||||
}
|
||||
|
||||
func (ch createObjectChange) dirtied() *common.Address {
|
||||
return &ch.account
|
||||
func (ch createObjectChange) dirtied() (common.Address, bool) {
|
||||
return ch.account, true
|
||||
}
|
||||
|
||||
func (ch createObjectChange) copy() journalEntry {
|
||||
|
|
@ -308,8 +309,8 @@ func (ch createContractChange) revert(s *StateDB) {
|
|||
s.getStateObject(ch.account).newContract = false
|
||||
}
|
||||
|
||||
func (ch createContractChange) dirtied() *common.Address {
|
||||
return nil
|
||||
func (ch createContractChange) dirtied() (common.Address, bool) {
|
||||
return common.Address{}, false
|
||||
}
|
||||
|
||||
func (ch createContractChange) copy() journalEntry {
|
||||
|
|
@ -325,8 +326,8 @@ func (ch selfDestructChange) revert(s *StateDB) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ch selfDestructChange) dirtied() *common.Address {
|
||||
return &ch.account
|
||||
func (ch selfDestructChange) dirtied() (common.Address, bool) {
|
||||
return ch.account, true
|
||||
}
|
||||
|
||||
func (ch selfDestructChange) copy() journalEntry {
|
||||
|
|
@ -340,8 +341,8 @@ var ripemd = common.HexToAddress("0000000000000000000000000000000000000003")
|
|||
func (ch touchChange) revert(s *StateDB) {
|
||||
}
|
||||
|
||||
func (ch touchChange) dirtied() *common.Address {
|
||||
return &ch.account
|
||||
func (ch touchChange) dirtied() (common.Address, bool) {
|
||||
return ch.account, true
|
||||
}
|
||||
|
||||
func (ch touchChange) copy() journalEntry {
|
||||
|
|
@ -354,8 +355,8 @@ func (ch balanceChange) revert(s *StateDB) {
|
|||
s.getStateObject(ch.account).setBalance(ch.prev)
|
||||
}
|
||||
|
||||
func (ch balanceChange) dirtied() *common.Address {
|
||||
return &ch.account
|
||||
func (ch balanceChange) dirtied() (common.Address, bool) {
|
||||
return ch.account, true
|
||||
}
|
||||
|
||||
func (ch balanceChange) copy() journalEntry {
|
||||
|
|
@ -369,8 +370,8 @@ func (ch nonceChange) revert(s *StateDB) {
|
|||
s.getStateObject(ch.account).setNonce(ch.prev)
|
||||
}
|
||||
|
||||
func (ch nonceChange) dirtied() *common.Address {
|
||||
return &ch.account
|
||||
func (ch nonceChange) dirtied() (common.Address, bool) {
|
||||
return ch.account, true
|
||||
}
|
||||
|
||||
func (ch nonceChange) copy() journalEntry {
|
||||
|
|
@ -384,8 +385,8 @@ func (ch codeChange) revert(s *StateDB) {
|
|||
s.getStateObject(ch.account).setCode(crypto.Keccak256Hash(ch.prevCode), ch.prevCode)
|
||||
}
|
||||
|
||||
func (ch codeChange) dirtied() *common.Address {
|
||||
return &ch.account
|
||||
func (ch codeChange) dirtied() (common.Address, bool) {
|
||||
return ch.account, true
|
||||
}
|
||||
|
||||
func (ch codeChange) copy() journalEntry {
|
||||
|
|
@ -399,8 +400,8 @@ func (ch storageChange) revert(s *StateDB) {
|
|||
s.getStateObject(ch.account).setState(ch.key, ch.prevvalue, ch.origvalue)
|
||||
}
|
||||
|
||||
func (ch storageChange) dirtied() *common.Address {
|
||||
return &ch.account
|
||||
func (ch storageChange) dirtied() (common.Address, bool) {
|
||||
return ch.account, true
|
||||
}
|
||||
|
||||
func (ch storageChange) copy() journalEntry {
|
||||
|
|
@ -416,8 +417,8 @@ func (ch transientStorageChange) revert(s *StateDB) {
|
|||
s.setTransientState(ch.account, ch.key, ch.prevalue)
|
||||
}
|
||||
|
||||
func (ch transientStorageChange) dirtied() *common.Address {
|
||||
return nil
|
||||
func (ch transientStorageChange) dirtied() (common.Address, bool) {
|
||||
return common.Address{}, false
|
||||
}
|
||||
|
||||
func (ch transientStorageChange) copy() journalEntry {
|
||||
|
|
@ -432,8 +433,8 @@ func (ch refundChange) revert(s *StateDB) {
|
|||
s.refund = ch.prev
|
||||
}
|
||||
|
||||
func (ch refundChange) dirtied() *common.Address {
|
||||
return nil
|
||||
func (ch refundChange) dirtied() (common.Address, bool) {
|
||||
return common.Address{}, false
|
||||
}
|
||||
|
||||
func (ch refundChange) copy() journalEntry {
|
||||
|
|
@ -452,8 +453,8 @@ func (ch addLogChange) revert(s *StateDB) {
|
|||
s.logSize--
|
||||
}
|
||||
|
||||
func (ch addLogChange) dirtied() *common.Address {
|
||||
return nil
|
||||
func (ch addLogChange) dirtied() (common.Address, bool) {
|
||||
return common.Address{}, false
|
||||
}
|
||||
|
||||
func (ch addLogChange) copy() journalEntry {
|
||||
|
|
@ -475,8 +476,8 @@ func (ch accessListAddAccountChange) revert(s *StateDB) {
|
|||
s.accessList.DeleteAddress(ch.address)
|
||||
}
|
||||
|
||||
func (ch accessListAddAccountChange) dirtied() *common.Address {
|
||||
return nil
|
||||
func (ch accessListAddAccountChange) dirtied() (common.Address, bool) {
|
||||
return common.Address{}, false
|
||||
}
|
||||
|
||||
func (ch accessListAddAccountChange) copy() journalEntry {
|
||||
|
|
@ -489,8 +490,8 @@ func (ch accessListAddSlotChange) revert(s *StateDB) {
|
|||
s.accessList.DeleteSlot(ch.address, ch.slot)
|
||||
}
|
||||
|
||||
func (ch accessListAddSlotChange) dirtied() *common.Address {
|
||||
return nil
|
||||
func (ch accessListAddSlotChange) dirtied() (common.Address, bool) {
|
||||
return common.Address{}, false
|
||||
}
|
||||
|
||||
func (ch accessListAddSlotChange) copy() journalEntry {
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ func (s Storage) Copy() Storage {
|
|||
// - Account values as well as storages can be accessed and modified through the object.
|
||||
// - Finally, call commit to return the changes of storage trie and update account data.
|
||||
type stateObject struct {
|
||||
db *StateDB
|
||||
address common.Address // address of ethereum account
|
||||
addrHash common.Hash // hash of ethereum address of the account
|
||||
origin *types.StateAccount // Account original data without any change applied, nil means it was not existent
|
||||
data types.StateAccount // Account data with all mutations applied in the scope of block
|
||||
db *StateDB
|
||||
address common.Address // address of ethereum account
|
||||
addressHash *common.Hash // hash of ethereum address of the account
|
||||
origin *types.StateAccount // Account original data without any change applied, nil means it was not existent
|
||||
data types.StateAccount // Account data with all mutations applied in the scope of block
|
||||
|
||||
// Write caches.
|
||||
trie Trie // storage trie, which becomes non-nil on first access
|
||||
|
|
@ -102,7 +102,6 @@ func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *s
|
|||
return &stateObject{
|
||||
db: db,
|
||||
address: address,
|
||||
addrHash: crypto.Keccak256Hash(address[:]),
|
||||
origin: origin,
|
||||
data: *acct,
|
||||
originStorage: make(Storage),
|
||||
|
|
@ -112,6 +111,14 @@ func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *s
|
|||
}
|
||||
}
|
||||
|
||||
func (s *stateObject) addrHash() common.Hash {
|
||||
if s.addressHash == nil {
|
||||
h := crypto.Keccak256Hash(s.address[:])
|
||||
s.addressHash = &h
|
||||
}
|
||||
return *s.addressHash
|
||||
}
|
||||
|
||||
func (s *stateObject) markSelfdestructed() {
|
||||
s.selfDestructed = true
|
||||
}
|
||||
|
|
@ -151,7 +158,7 @@ func (s *stateObject) getPrefetchedTrie() Trie {
|
|||
return nil
|
||||
}
|
||||
// Attempt to retrieve the trie from the prefetcher
|
||||
return s.db.prefetcher.trie(s.addrHash, s.data.Root)
|
||||
return s.db.prefetcher.trie(s.addrHash(), s.data.Root)
|
||||
}
|
||||
|
||||
// GetState retrieves a value associated with the given storage key.
|
||||
|
|
@ -203,7 +210,7 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
|||
|
||||
// Schedule the resolved storage slots for prefetching if it's enabled.
|
||||
if s.db.prefetcher != nil && s.data.Root != types.EmptyRootHash {
|
||||
if err = s.db.prefetcher.prefetch(s.addrHash, s.origin.Root, s.address, nil, []common.Hash{key}, true); err != nil {
|
||||
if err = s.db.prefetcher.prefetch(s.addrHash(), s.origin.Root, s.address, nil, []common.Hash{key}, true); err != nil {
|
||||
log.Error("Failed to prefetch storage slot", "addr", s.address, "key", key, "err", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -264,7 +271,7 @@ func (s *stateObject) finalise() {
|
|||
s.pendingStorage[key] = value
|
||||
}
|
||||
if s.db.prefetcher != nil && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash {
|
||||
if err := s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, nil, slotsToPrefetch, false); err != nil {
|
||||
if err := s.db.prefetcher.prefetch(s.addrHash(), s.data.Root, s.address, nil, slotsToPrefetch, false); err != nil {
|
||||
log.Error("Failed to prefetch slots", "addr", s.address, "slots", len(slotsToPrefetch), "err", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -359,7 +366,7 @@ func (s *stateObject) updateTrie() (Trie, error) {
|
|||
s.db.StorageDeleted.Add(1)
|
||||
}
|
||||
if s.db.prefetcher != nil {
|
||||
s.db.prefetcher.used(s.addrHash, s.data.Root, nil, used)
|
||||
s.db.prefetcher.used(s.addrHash(), s.data.Root, nil, used)
|
||||
}
|
||||
s.uncommittedStorage = make(Storage) // empties the commit markers
|
||||
return tr, nil
|
||||
|
|
@ -491,7 +498,7 @@ func (s *stateObject) deepCopy(db *StateDB) *stateObject {
|
|||
obj := &stateObject{
|
||||
db: db,
|
||||
address: s.address,
|
||||
addrHash: s.addrHash,
|
||||
addressHash: nil,
|
||||
origin: s.origin,
|
||||
data: s.data,
|
||||
code: s.code,
|
||||
|
|
|
|||
|
|
@ -867,13 +867,13 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
|||
witness := trie.Witness()
|
||||
s.witness.AddState(witness)
|
||||
if s.witnessStats != nil {
|
||||
s.witnessStats.Add(witness, obj.addrHash)
|
||||
s.witnessStats.Add(witness, obj.addrHash())
|
||||
}
|
||||
} else if obj.trie != nil {
|
||||
witness := obj.trie.Witness()
|
||||
s.witness.AddState(witness)
|
||||
if s.witnessStats != nil {
|
||||
s.witnessStats.Add(witness, obj.addrHash)
|
||||
s.witnessStats.Add(witness, obj.addrHash())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -891,13 +891,13 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
|||
witness := trie.Witness()
|
||||
s.witness.AddState(witness)
|
||||
if s.witnessStats != nil {
|
||||
s.witnessStats.Add(witness, obj.addrHash)
|
||||
s.witnessStats.Add(witness, obj.addrHash())
|
||||
}
|
||||
} else if obj.trie != nil {
|
||||
witness := obj.trie.Witness()
|
||||
s.witness.AddState(witness)
|
||||
if s.witnessStats != nil {
|
||||
s.witnessStats.Add(witness, obj.addrHash)
|
||||
s.witnessStats.Add(witness, obj.addrHash())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1284,7 +1284,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool, blockNum
|
|||
return err
|
||||
}
|
||||
lock.Lock()
|
||||
updates[obj.addrHash] = update
|
||||
updates[obj.addrHash()] = update
|
||||
s.StorageCommits = time.Since(start) // overwrite with the longest storage commit runtime
|
||||
lock.Unlock()
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ func NewEIP2930Signer(chainId *big.Int) Signer {
|
|||
// are replay-protected as well as unprotected homestead transactions.
|
||||
// Deprecated: always use the Signer interface type
|
||||
type EIP155Signer struct {
|
||||
chainId, chainIdMul *big.Int
|
||||
chainId *big.Int
|
||||
}
|
||||
|
||||
func NewEIP155Signer(chainId *big.Int) EIP155Signer {
|
||||
|
|
@ -338,8 +338,7 @@ func NewEIP155Signer(chainId *big.Int) EIP155Signer {
|
|||
chainId = new(big.Int)
|
||||
}
|
||||
return EIP155Signer{
|
||||
chainId: chainId,
|
||||
chainIdMul: new(big.Int).Mul(chainId, big.NewInt(2)),
|
||||
chainId: chainId,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +364,8 @@ func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) {
|
|||
return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId)
|
||||
}
|
||||
V, R, S := tx.RawSignatureValues()
|
||||
V = new(big.Int).Sub(V, s.chainIdMul)
|
||||
V = new(big.Int).Sub(V, s.chainId)
|
||||
V = new(big.Int).Sub(V, s.chainId)
|
||||
V.Sub(V, big8)
|
||||
return recoverPlain(s.Hash(tx), R, S, V, true)
|
||||
}
|
||||
|
|
@ -382,7 +382,8 @@ func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big
|
|||
}
|
||||
if s.chainId.Sign() != 0 {
|
||||
V = big.NewInt(int64(sig[64] + 35))
|
||||
V.Add(V, s.chainIdMul)
|
||||
V.Add(V, s.chainId)
|
||||
V.Add(V, s.chainId)
|
||||
}
|
||||
return R, S, V, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,9 +73,8 @@ type BlockContext struct {
|
|||
type TxContext struct {
|
||||
// Message information
|
||||
Origin common.Address // Provides information for ORIGIN
|
||||
GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set)
|
||||
GasPrice *uint256.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set)
|
||||
BlobHashes []common.Hash // Provides information for BLOBHASH
|
||||
BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set
|
||||
AccessEvents *state.AccessEvents // Capture all state accesses for this tx
|
||||
}
|
||||
|
||||
|
|
@ -125,9 +124,6 @@ type EVM struct {
|
|||
// jumpDests stores results of JUMPDEST analysis.
|
||||
jumpDests JumpDestCache
|
||||
|
||||
hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes
|
||||
hasherBuf common.Hash // Keccak256 hasher result array shared across opcodes
|
||||
|
||||
readOnly bool // Whether to throw on stateful modifications
|
||||
returnData []byte // Last CALL's return data for subsequent reuse
|
||||
}
|
||||
|
|
@ -144,7 +140,6 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
|
|||
chainConfig: chainConfig,
|
||||
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time),
|
||||
jumpDests: newMapJumpDests(),
|
||||
hasher: crypto.NewKeccakState(),
|
||||
}
|
||||
evm.precompiles = activePrecompiledContracts(evm.chainRules)
|
||||
|
||||
|
|
@ -618,7 +613,7 @@ func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *ui
|
|||
// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
|
||||
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
|
||||
func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
||||
inithash := crypto.HashData(evm.hasher, code)
|
||||
inithash := crypto.Keccak256Hash(code)
|
||||
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:])
|
||||
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
|
@ -233,14 +234,12 @@ func opKeccak256(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
offset, size := scope.Stack.pop(), scope.Stack.peek()
|
||||
data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
|
||||
|
||||
evm.hasher.Reset()
|
||||
evm.hasher.Write(data)
|
||||
evm.hasher.Read(evm.hasherBuf[:])
|
||||
hash := crypto.Keccak256Hash(data)
|
||||
|
||||
if evm.Config.EnablePreimageRecording {
|
||||
evm.StateDB.AddPreimage(evm.hasherBuf, data)
|
||||
evm.StateDB.AddPreimage(hash, data)
|
||||
}
|
||||
size.SetBytes(evm.hasherBuf[:])
|
||||
size.SetBytes(hash[:])
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
@ -417,8 +416,7 @@ func opExtCodeHash(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
}
|
||||
|
||||
func opGasprice(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(evm.GasPrice)
|
||||
scope.Stack.push(v)
|
||||
scope.Stack.push(evm.GasPrice.Clone())
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@ package runtime
|
|||
import (
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
func NewEnv(cfg *Config) *vm.EVM {
|
||||
txContext := vm.TxContext{
|
||||
Origin: cfg.Origin,
|
||||
GasPrice: cfg.GasPrice,
|
||||
GasPrice: uint256.MustFromBig(cfg.GasPrice),
|
||||
BlobHashes: cfg.BlobHashes,
|
||||
BlobFeeCap: cfg.BlobFeeCap,
|
||||
}
|
||||
blockContext := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ type vmContext struct {
|
|||
}
|
||||
|
||||
func testCtx() *vmContext {
|
||||
return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1), BaseFee: big.NewInt(0)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
|
||||
return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1), BaseFee: big.NewInt(0)}, txCtx: vm.TxContext{GasPrice: uint256.NewInt(100000)}}
|
||||
}
|
||||
|
||||
func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) {
|
||||
|
|
@ -63,7 +63,7 @@ func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCo
|
|||
contract.Code = contractCode
|
||||
}
|
||||
|
||||
tracer.OnTxStart(evm.GetVMContext(), types.NewTx(&types.LegacyTx{Gas: gasLimit, GasPrice: vmctx.txCtx.GasPrice}), contract.Caller())
|
||||
tracer.OnTxStart(evm.GetVMContext(), types.NewTx(&types.LegacyTx{Gas: gasLimit, GasPrice: vmctx.txCtx.GasPrice.ToBig()}), contract.Caller())
|
||||
tracer.OnEnter(0, byte(vm.CALL), contract.Caller(), contract.Address(), []byte{}, startGas, value.ToBig())
|
||||
ret, err := evm.Run(contract, []byte{}, false)
|
||||
tracer.OnExit(0, ret, startGas-contract.Gas, err, true)
|
||||
|
|
@ -186,7 +186,7 @@ func TestHaltBetweenSteps(t *testing.T) {
|
|||
Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), 0, nil),
|
||||
}
|
||||
evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, chainConfig, vm.Config{Tracer: tracer.Hooks})
|
||||
evm.SetTxContext(vm.TxContext{GasPrice: big.NewInt(1)})
|
||||
evm.SetTxContext(vm.TxContext{GasPrice: uint256.NewInt(1)})
|
||||
tracer.OnTxStart(evm.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
|
||||
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 0, big.NewInt(0))
|
||||
tracer.OnOpcode(0, 0, 0, 0, scope, nil, 0, nil)
|
||||
|
|
@ -210,7 +210,7 @@ func TestNoStepExec(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, chainConfig, vm.Config{Tracer: tracer.Hooks})
|
||||
evm.SetTxContext(vm.TxContext{GasPrice: big.NewInt(100)})
|
||||
evm.SetTxContext(vm.TxContext{GasPrice: uint256.NewInt(100)})
|
||||
tracer.OnTxStart(evm.GetVMContext(), types.NewTx(&types.LegacyTx{}), common.Address{})
|
||||
tracer.OnEnter(0, byte(vm.CALL), common.Address{}, common.Address{}, []byte{}, 1000, big.NewInt(0))
|
||||
tracer.OnExit(0, nil, 0, nil, false)
|
||||
|
|
@ -240,7 +240,7 @@ func TestIsPrecompile(t *testing.T) {
|
|||
chaincfg.ByzantiumBlock = big.NewInt(100)
|
||||
chaincfg.IstanbulBlock = big.NewInt(200)
|
||||
chaincfg.BerlinBlock = big.NewInt(300)
|
||||
txCtx := vm.TxContext{GasPrice: big.NewInt(100000)}
|
||||
txCtx := vm.TxContext{GasPrice: uint256.NewInt(100000)}
|
||||
tracer, err := newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil, chaincfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
|||
|
|
@ -974,6 +974,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *param
|
|||
type RPCTransaction struct {
|
||||
BlockHash *common.Hash `json:"blockHash"`
|
||||
BlockNumber *hexutil.Big `json:"blockNumber"`
|
||||
BlockTimestamp *hexutil.Uint64 `json:"blockTimestamp"`
|
||||
From common.Address `json:"from"`
|
||||
Gas hexutil.Uint64 `json:"gas"`
|
||||
GasPrice *hexutil.Big `json:"gasPrice"`
|
||||
|
|
@ -1020,6 +1021,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
|
|||
if blockHash != (common.Hash{}) {
|
||||
result.BlockHash = &blockHash
|
||||
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
||||
result.BlockTimestamp = (*hexutil.Uint64)(&blockTime)
|
||||
result.TransactionIndex = (*hexutil.Uint64)(&index)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
|||
Want: `{
|
||||
"blockHash": null,
|
||||
"blockNumber": null,
|
||||
"blockTimestamp": null,
|
||||
"from": "0x71562b71999873db5b286df957af199ec94617f7",
|
||||
"gas": "0x7",
|
||||
"gasPrice": "0x6",
|
||||
|
|
@ -170,6 +171,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
|||
Want: `{
|
||||
"blockHash": null,
|
||||
"blockNumber": null,
|
||||
"blockTimestamp": null,
|
||||
"from": "0x71562b71999873db5b286df957af199ec94617f7",
|
||||
"gas": "0x7",
|
||||
"gasPrice": "0x6",
|
||||
|
|
@ -208,6 +210,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
|||
Want: `{
|
||||
"blockHash": null,
|
||||
"blockNumber": null,
|
||||
"blockTimestamp": null,
|
||||
"from": "0x71562b71999873db5b286df957af199ec94617f7",
|
||||
"gas": "0x7",
|
||||
"gasPrice": "0x6",
|
||||
|
|
@ -254,6 +257,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
|||
Want: `{
|
||||
"blockHash": null,
|
||||
"blockNumber": null,
|
||||
"blockTimestamp": null,
|
||||
"from": "0x71562b71999873db5b286df957af199ec94617f7",
|
||||
"gas": "0x7",
|
||||
"gasPrice": "0x6",
|
||||
|
|
@ -301,6 +305,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
|||
Want: `{
|
||||
"blockHash": null,
|
||||
"blockNumber": null,
|
||||
"blockTimestamp": null,
|
||||
"from": "0x71562b71999873db5b286df957af199ec94617f7",
|
||||
"gas": "0x7",
|
||||
"gasPrice": "0x9",
|
||||
|
|
@ -345,6 +350,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
|||
Want: `{
|
||||
"blockHash": null,
|
||||
"blockNumber": null,
|
||||
"blockTimestamp": null,
|
||||
"from": "0x71562b71999873db5b286df957af199ec94617f7",
|
||||
"gas": "0x7",
|
||||
"gasPrice": "0x9",
|
||||
|
|
@ -387,6 +393,7 @@ func allBlobTxs(addr common.Address, config *params.ChainConfig) []txData {
|
|||
Want: `{
|
||||
"blockHash": null,
|
||||
"blockNumber": null,
|
||||
"blockTimestamp": null,
|
||||
"from": "0x71562b71999873db5b286df957af199ec94617f7",
|
||||
"gas": "0x6",
|
||||
"gasPrice": "0x5",
|
||||
|
|
@ -3138,6 +3145,7 @@ func TestRPCMarshalBlock(t *testing.T) {
|
|||
{
|
||||
"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
|
||||
"blockNumber": "0x64",
|
||||
"blockTimestamp": "0x0",
|
||||
"from": "0x0000000000000000000000000000000000000000",
|
||||
"gas": "0x457",
|
||||
"gasPrice": "0x2b67",
|
||||
|
|
@ -3158,6 +3166,7 @@ func TestRPCMarshalBlock(t *testing.T) {
|
|||
{
|
||||
"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
|
||||
"blockNumber": "0x64",
|
||||
"blockTimestamp": "0x0",
|
||||
"from": "0x0000000000000000000000000000000000000000",
|
||||
"gas": "0x457",
|
||||
"gasPrice": "0x2b67",
|
||||
|
|
@ -3176,6 +3185,7 @@ func TestRPCMarshalBlock(t *testing.T) {
|
|||
{
|
||||
"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
|
||||
"blockNumber": "0x64",
|
||||
"blockTimestamp": "0x0",
|
||||
"from": "0x0000000000000000000000000000000000000000",
|
||||
"gas": "0x457",
|
||||
"gasPrice": "0x2b67",
|
||||
|
|
@ -3196,6 +3206,7 @@ func TestRPCMarshalBlock(t *testing.T) {
|
|||
{
|
||||
"blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
|
||||
"blockNumber": "0x64",
|
||||
"blockTimestamp": "0x0",
|
||||
"from": "0x0000000000000000000000000000000000000000",
|
||||
"gas": "0x457",
|
||||
"gasPrice": "0x2b67",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
{
|
||||
"blockHash": "0xedb9ccf3a85f67c095ad48abfb0fa09d47179bb0f902078d289042d12428aca5",
|
||||
"blockNumber": "0x9",
|
||||
"blockTimestamp": "0x5a",
|
||||
"from": "0x703c4b2bd70c169f5717101caee543299fc946c7",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x121a9cca",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
{
|
||||
"blockHash": "0xedb9ccf3a85f67c095ad48abfb0fa09d47179bb0f902078d289042d12428aca5",
|
||||
"blockNumber": "0x9",
|
||||
"blockTimestamp": "0x5a",
|
||||
"from": "0x703c4b2bd70c169f5717101caee543299fc946c7",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x121a9cca",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
{
|
||||
"blockHash": "0xfda6c7cb7a3a712e0c424909a7724cab0448e89e286617fa8d5fd27f63f28bd2",
|
||||
"blockNumber": "0xb",
|
||||
"blockTimestamp": "0x6e",
|
||||
"from": "0x703c4b2bd70c169f5717101caee543299fc946c7",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0xde56ab3",
|
||||
|
|
|
|||
|
|
@ -1375,7 +1375,6 @@ func (err *ConfigCompatError) Error() string {
|
|||
// Rules is a one time interface meaning that it shouldn't be used in between transition
|
||||
// phases.
|
||||
type Rules struct {
|
||||
ChainID *big.Int
|
||||
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
|
||||
IsEIP2929, IsEIP4762 bool
|
||||
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
|
||||
|
|
@ -1386,15 +1385,10 @@ type Rules struct {
|
|||
|
||||
// Rules ensures c's ChainID is not nil.
|
||||
func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules {
|
||||
chainID := c.ChainID
|
||||
if chainID == nil {
|
||||
chainID = new(big.Int)
|
||||
}
|
||||
// disallow setting Merge out of order
|
||||
isMerge = isMerge && c.IsLondon(num)
|
||||
isVerkle := isMerge && c.IsVerkle(num, timestamp)
|
||||
return Rules{
|
||||
ChainID: new(big.Int).Set(chainID),
|
||||
IsHomestead: c.IsHomestead(num),
|
||||
IsEIP150: c.IsEIP150(num),
|
||||
IsEIP155: c.IsEIP155(num),
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ type SendTxArgs struct {
|
|||
BlobHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
|
||||
|
||||
// For BlobTxType transactions with blob sidecar
|
||||
BlobVersion byte `json:"blobVersion,omitempty"`
|
||||
Blobs []kzg4844.Blob `json:"blobs,omitempty"`
|
||||
Commitments []kzg4844.Commitment `json:"commitments,omitempty"`
|
||||
Proofs []kzg4844.Proof `json:"proofs,omitempty"`
|
||||
|
|
@ -235,37 +236,58 @@ func (args *SendTxArgs) validateTxSidecar() error {
|
|||
if args.Commitments != nil && len(args.Commitments) != n {
|
||||
return fmt.Errorf("number of blobs and commitments mismatch (have=%d, want=%d)", len(args.Commitments), n)
|
||||
}
|
||||
if args.Proofs != nil && len(args.Proofs) != n {
|
||||
return fmt.Errorf("number of blobs and proofs mismatch (have=%d, want=%d)", len(args.Proofs), n)
|
||||
}
|
||||
if args.BlobHashes != nil && len(args.BlobHashes) != n {
|
||||
return fmt.Errorf("number of blobs and hashes mismatch (have=%d, want=%d)", len(args.BlobHashes), n)
|
||||
}
|
||||
|
||||
if args.Proofs != nil {
|
||||
if len(args.Proofs) == n {
|
||||
// v1 transaction
|
||||
for i := range args.Blobs {
|
||||
if err := kzg4844.VerifyBlobProof(&args.Blobs[i], args.Commitments[i], args.Proofs[i]); err != nil {
|
||||
return fmt.Errorf("failed to verify blob proof: %v", err)
|
||||
}
|
||||
}
|
||||
} else if len(args.Proofs) == n*kzg4844.CellProofsPerBlob {
|
||||
// v2 transaction
|
||||
if err := kzg4844.VerifyCellProofs(args.Blobs, args.Commitments, args.Proofs); err != nil {
|
||||
return fmt.Errorf("failed to verify blob proof: %v", err)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("number of proofs and blobs mismatch (have=%d, want=%d or %d)", len(args.Proofs), n, n*kzg4844.CellProofsPerBlob)
|
||||
}
|
||||
}
|
||||
if args.Commitments == nil {
|
||||
// Generate commitment and proof.
|
||||
commitments := make([]kzg4844.Commitment, n)
|
||||
proofs := make([]kzg4844.Proof, n)
|
||||
for i := range args.Blobs {
|
||||
c, err := kzg4844.BlobToCommitment(&args.Blobs[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("blobs[%d]: error computing commitment: %v", i, err)
|
||||
}
|
||||
commitments[i] = c
|
||||
p, err := kzg4844.ComputeBlobProof(&args.Blobs[i], c)
|
||||
if err != nil {
|
||||
return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err)
|
||||
}
|
||||
var proofs []kzg4844.Proof
|
||||
if args.BlobVersion == types.BlobSidecarVersion1 {
|
||||
proofs = make([]kzg4844.Proof, 0, n*kzg4844.CellProofsPerBlob)
|
||||
for i := range args.Blobs {
|
||||
p, err := kzg4844.ComputeCellProofs(&args.Blobs[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("blobs[%d]: error computing cell proof: %v", i, err)
|
||||
}
|
||||
proofs = append(proofs, p...)
|
||||
}
|
||||
} else {
|
||||
proofs = make([]kzg4844.Proof, 0, n)
|
||||
for i := range args.Blobs {
|
||||
p, err := kzg4844.ComputeBlobProof(&args.Blobs[i], commitments[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err)
|
||||
}
|
||||
proofs = append(proofs, p)
|
||||
}
|
||||
proofs[i] = p
|
||||
}
|
||||
args.Commitments = commitments
|
||||
args.Proofs = proofs
|
||||
} else {
|
||||
for i := range args.Blobs {
|
||||
if err := kzg4844.VerifyBlobProof(&args.Blobs[i], args.Commitments[i], args.Proofs[i]); err != nil {
|
||||
return fmt.Errorf("failed to verify blob proof: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hashes := make([]common.Hash, n)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package apitypes
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
|
@ -229,3 +230,183 @@ func TestType_TypeName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTxSidecar(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Helper function to create a test blob and its commitment/proof
|
||||
createTestBlob := func() (kzg4844.Blob, kzg4844.Commitment, kzg4844.Proof, common.Hash) {
|
||||
b := make([]byte, 31)
|
||||
rand.Read(b)
|
||||
var blob kzg4844.Blob
|
||||
for i := range b {
|
||||
blob[i+1] = b[i]
|
||||
}
|
||||
commitment, err := kzg4844.BlobToCommitment(&blob)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
proof, err := kzg4844.ComputeBlobProof(&blob, commitment)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hash := kzg4844.CalcBlobHashV1(sha256.New(), &commitment)
|
||||
return blob, commitment, proof, hash
|
||||
}
|
||||
|
||||
// Helper function to create test cell proofs for v1 transactions
|
||||
createTestCellProofs := func(blob kzg4844.Blob) []kzg4844.Proof {
|
||||
cellProofs, err := kzg4844.ComputeCellProofs(&blob)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return cellProofs
|
||||
}
|
||||
|
||||
blob1, commitment1, proof1, hash1 := createTestBlob()
|
||||
blob2, commitment2, proof2, hash2 := createTestBlob()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args SendTxArgs
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "no blobs - should pass",
|
||||
args: SendTxArgs{},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "valid blobs with commitments and proofs",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1, blob2},
|
||||
Commitments: []kzg4844.Commitment{commitment1, commitment2},
|
||||
Proofs: []kzg4844.Proof{proof1, proof2},
|
||||
BlobHashes: []common.Hash{hash1, hash2},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "valid blobs without commitments/proofs - should generate them",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "valid blobs with v1 cell proofs",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1},
|
||||
Commitments: []kzg4844.Commitment{commitment1},
|
||||
Proofs: createTestCellProofs(blob1),
|
||||
BlobHashes: []common.Hash{hash1},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "blobs with v1 version flag - should generate cell proofs",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1},
|
||||
BlobVersion: types.BlobSidecarVersion1,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "proofs provided but commitments not",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1},
|
||||
Proofs: []kzg4844.Proof{proof1},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "commitments provided but proofs not",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1},
|
||||
Commitments: []kzg4844.Commitment{commitment1},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "mismatch between blobs and commitments",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1, blob2},
|
||||
Commitments: []kzg4844.Commitment{commitment1}, // Only one commitment for two blobs
|
||||
Proofs: []kzg4844.Proof{proof1},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "mismatch between blobs and hashes",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1, blob2},
|
||||
Commitments: []kzg4844.Commitment{commitment1, commitment2},
|
||||
Proofs: []kzg4844.Proof{proof1, proof2},
|
||||
BlobHashes: []common.Hash{hash1}, // Only one hash for two blobs
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "wrong number of proofs",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1, blob2},
|
||||
Commitments: []kzg4844.Commitment{commitment1, commitment2},
|
||||
Proofs: []kzg4844.Proof{proof1, proof2, proof1}, // 3 proofs for 2 blobs
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid blob hash",
|
||||
args: SendTxArgs{
|
||||
Blobs: []kzg4844.Blob{blob1},
|
||||
Commitments: []kzg4844.Commitment{commitment1},
|
||||
Proofs: []kzg4844.Proof{proof1},
|
||||
BlobHashes: []common.Hash{hash2}, // Wrong hash
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid proof",
|
||||
args: SendTxArgs{
|
||||
BlobVersion: types.BlobSidecarVersion1,
|
||||
Blobs: []kzg4844.Blob{blob1},
|
||||
Commitments: []kzg4844.Commitment{commitment1},
|
||||
Proofs: []kzg4844.Proof{proof1, proof2}, // wrong proof
|
||||
BlobHashes: []common.Hash{hash1},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Make a copy to avoid modifying the original test case
|
||||
args := tt.args
|
||||
err := args.validateTxSidecar()
|
||||
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("validateTxSidecar() expected error but got none")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("validateTxSidecar() unexpected error = %v", err)
|
||||
}
|
||||
|
||||
// For successful cases, verify that commitments and proofs were generated if they weren't provided
|
||||
if len(args.Blobs) > 0 {
|
||||
if args.Commitments == nil || len(args.Commitments) != len(args.Blobs) {
|
||||
t.Errorf("validateTxSidecar() should have generated commitments")
|
||||
}
|
||||
if args.Proofs == nil || (len(args.Proofs) != len(args.Blobs) && len(args.Proofs) != len(args.Blobs)*kzg4844.CellProofsPerBlob) {
|
||||
t.Errorf("validateTxSidecar() should have generated proofs")
|
||||
}
|
||||
if args.BlobHashes == nil || len(args.BlobHashes) != len(args.Blobs) {
|
||||
t.Errorf("validateTxSidecar() should have generated blob hashes")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,10 +391,6 @@ func decodeKeyEntry(keySection []byte, offset int) (uint64, uint64, []byte, int,
|
|||
|
||||
// decodeRestartTrailer resolves all the offsets recorded at the trailer.
|
||||
func decodeRestartTrailer(keySection []byte) ([]uint32, []uint32, int, error) {
|
||||
var (
|
||||
keyOffsets []uint32
|
||||
valOffsets []uint32
|
||||
)
|
||||
// Decode the number of restart section
|
||||
if len(keySection) < 4 {
|
||||
return nil, nil, 0, fmt.Errorf("key section too short, size: %d", len(keySection))
|
||||
|
|
@ -402,6 +398,10 @@ func decodeRestartTrailer(keySection []byte) ([]uint32, []uint32, int, error) {
|
|||
nRestarts := binary.BigEndian.Uint32(keySection[len(keySection)-4:])
|
||||
|
||||
// Decode the trailer
|
||||
var (
|
||||
keyOffsets = make([]uint32, 0, int(nRestarts))
|
||||
valOffsets = make([]uint32, 0, int(nRestarts))
|
||||
)
|
||||
if len(keySection) < int(8*nRestarts)+4 {
|
||||
return nil, nil, 0, fmt.Errorf("key section too short, restarts: %d, size: %d", nRestarts, len(keySection))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,7 +342,10 @@ func (s *stateSet) encode(w io.Writer) error {
|
|||
AddrHashes []common.Hash
|
||||
Accounts [][]byte
|
||||
}
|
||||
var enc accounts
|
||||
enc := accounts{
|
||||
AddrHashes: make([]common.Hash, 0, len(s.accountData)),
|
||||
Accounts: make([][]byte, 0, len(s.accountData)),
|
||||
}
|
||||
for addrHash, blob := range s.accountData {
|
||||
enc.AddrHashes = append(enc.AddrHashes, addrHash)
|
||||
enc.Accounts = append(enc.Accounts, blob)
|
||||
|
|
@ -505,7 +508,10 @@ func (s *StateSetWithOrigin) encode(w io.Writer) error {
|
|||
Addresses []common.Address
|
||||
Accounts [][]byte
|
||||
}
|
||||
var accounts Accounts
|
||||
accounts := Accounts{
|
||||
Addresses: make([]common.Address, 0, len(s.accountOrigin)),
|
||||
Accounts: make([][]byte, 0, len(s.accountOrigin)),
|
||||
}
|
||||
for address, blob := range s.accountOrigin {
|
||||
accounts.Addresses = append(accounts.Addresses, address)
|
||||
accounts.Accounts = append(accounts.Accounts, blob)
|
||||
|
|
|
|||
Loading…
Reference in a new issue