Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions accounts/usbwallet/hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package usbwallet
import (
"errors"
"runtime"
"slices"
"sync"
"sync/atomic"
"time"
Expand Down Expand Up @@ -49,7 +48,7 @@ type Hub struct {
scheme string // Protocol scheme prefixing account and wallet URLs.
vendorID uint16 // USB vendor identifier used for device discovery
productIDs []uint16 // USB product identifiers used for device discovery
usageIDs []uint16 // USB usage page identifier used for macOS device discovery
usageID uint16 // USB usage page identifier used for macOS device discovery
endpointID int // USB endpoint identifier used for non-macOS device discovery
makeDriver func(log.Logger) driver // Factory method to construct a vendor specific driver

Expand Down Expand Up @@ -90,30 +89,30 @@ func NewLedgerHub() (*Hub, error) {
0x5000, /* WebUSB Ledger Nano S Plus */
0x6000, /* WebUSB Ledger Nano FTS */
0x7000, /* WebUSB Ledger Flex */
}, []uint16{0xffa0, 0}, 2, newLedgerDriver)
}, 0xffa0, 0, newLedgerDriver)
}

// NewTrezorHubWithHID creates a new hardware wallet manager for Trezor devices.
func NewTrezorHubWithHID() (*Hub, error) {
return newHub(TrezorScheme, 0x534c, []uint16{0x0001 /* Trezor HID */}, []uint16{0xff00}, 0, newTrezorDriver)
return newHub(TrezorScheme, 0x534c, []uint16{0x0001 /* Trezor HID */}, 0xff00, 0, newTrezorDriver)
}

// NewTrezorHubWithWebUSB creates a new hardware wallet manager for Trezor devices with
// firmware version > 1.8.0
func NewTrezorHubWithWebUSB() (*Hub, error) {
return newHub(TrezorScheme, 0x1209, []uint16{0x53c1 /* Trezor WebUSB */}, []uint16{0xffff} /* No usage id on webusb, don't match unset (0) */, 0, newTrezorDriver)
return newHub(TrezorScheme, 0x1209, []uint16{0x53c1 /* Trezor WebUSB */}, 0xffff /* No usage id on webusb, don't match unset (0) */, 0, newTrezorDriver)
}

// newHub creates a new hardware wallet manager for generic USB devices.
func newHub(scheme string, vendorID uint16, productIDs []uint16, usageIDs []uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) {
func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) {
if !hid.Supported() {
return nil, errors.New("unsupported platform")
}
hub := &Hub{
scheme: scheme,
vendorID: vendorID,
productIDs: productIDs,
usageIDs: usageIDs,
usageID: usageID,
endpointID: endpointID,
makeDriver: makeDriver,
quit: make(chan chan error),
Expand Down Expand Up @@ -186,10 +185,7 @@ func (hub *Hub) refreshWallets() {
// uses `MMII`, encoding a model (MM) and an interface bitfield (II)
mmOnly := info.ProductID & 0xff00
// Windows and Macos use UsageID matching, Linux uses Interface matching
if (info.ProductID == id || mmOnly == id) &&
// TODO: we had the following check in op-geth only, ok to remove?
// info.Path != "" &&
(slices.Contains(hub.usageIDs, info.UsagePage) || info.Interface == hub.endpointID) {
if (info.ProductID == id || mmOnly == id) && (info.UsagePage == hub.usageID || info.Interface == hub.endpointID) {
devices = append(devices, info)
break
}
Expand Down
1 change: 1 addition & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
}

// OP-Stack diff: deliberately only check header after reorg handling, to get un-stuck of degenerate reorg cases.
// The first thing the node will do is reconstruct the verification data for
// the head block (ethash cache or clique voting snapshot). Might as well do
// it in advance.
Expand Down
10 changes: 10 additions & 0 deletions core/blockchain_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,16 @@ func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) []byte {
return bc.statedb.ContractCodeWithPrefix(common.Address{}, hash)
}

// ContractCode retrieves a blob of data associated with a contract hash
// either from ephemeral in-memory cache, or from persistent storage.
// OP-Stack diff: this is a legacy-method, replaced by ContractCodeWithPrefix in upstream,
// but required for old databases to serve snap-sync.
// It tries prefix-style contract-code retrieval first, then falls back to legacy code storage.
// Returns nil if not found.
func (bc *BlockChain) ContractCode(hash common.Hash) []byte {
return bc.statedb.ContractCode(common.Address{}, hash)
}

// State returns a new mutable state based on the current HEAD block.
func (bc *BlockChain) State() (*state.StateDB, error) {
return bc.StateAt(bc.CurrentBlock().Root)
Expand Down
36 changes: 25 additions & 11 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,19 +403,18 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
return chainCfg, block.Hash(), nil, nil
}

// TODO: Reinstate transitioned network check. Not sure where exactly to put it after this refactor.
// If the bedrock block is not 0, that implies that the network was migrated at the bedrock block.
// In this case the genesis state may not be in the state database (e.g. op-geth is performing a snap
// sync without an existing datadir) & even if it were, would not be useful as op-geth is not able to
// execute the pre-bedrock STF.
// transitionedNetwork := genesis != nil && genesis.Config != nil && genesis.Config.BedrockBlock != nil && genesis.Config.BedrockBlock.Uint64() != 0
// OP-Stack note: if it's a bedrock-transition genesis,
// then only commit to DB if it has a StateHash to work with,
// as the genesis config accounts map will not be usable.
transitionedNetwork := genesis != nil && genesis.Config != nil && genesis.Config.BedrockBlock != nil && genesis.Config.BedrockBlock.Uint64() != 0
canCommitGenesis := !transitionedNetwork || genesis.StateHash != nil

// Commit the genesis if the genesis block exists in the ancient database
// but the key-value database is empty without initializing the genesis
// fields. This scenario can occur when the node is created from scratch
// with an existing ancient store.
storedCfg := rawdb.ReadChainConfig(db, ghash)
if storedCfg == nil {
if storedCfg == nil && canCommitGenesis {
// Ensure the stored genesis block matches with the given genesis. Private
// networks must explicitly specify the genesis in the config file, mainnet
// genesis will be used as default and the initialization will always fail.
Expand All @@ -440,7 +439,6 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
}
return chainCfg, block.Hash(), nil, nil
}
log.Info("Stored config", "cfg", storedCfg, "genesis-nil", genesis == nil)
// The genesis block has already been committed previously. Verify that the
// provided genesis with chain overrides matches the existing one, and update
// the stored chain config if necessary.
Expand All @@ -455,20 +453,34 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
}
}

// Check config compatibility and write the config. Compatibility errors
// are returned to the caller unless we're already at block zero.
head := rawdb.ReadHeadHeader(db)
if head == nil {
return nil, common.Hash{}, nil, errors.New("missing head header")
}

// OP-Stack warning: tricky upstream code: method with nil-receiver case.
// Returns genesis.Config if genesis is not nil. Falls back to storedCfg otherwise. And some special L1 cases.
newCfg := genesis.chainConfigOrDefault(ghash, storedCfg)

// OP-Stack note: geth used to have a "Special case" for private networks,
// where it would set newCfg to storedCfg if genesis was nil. That is implied now in chainConfigOrDefault.
// However, a possible upstream bug means that overrides are not always applied to this new config.
// Always apply overrides.
chainCfg, err := overrides.apply(newCfg)
if err != nil {
return nil, common.Hash{}, nil, err
}
newCfg = chainCfg

log.Info("New config", "cfg", newCfg, "genesis-nil", genesis == nil)
var genesisTimestamp *uint64
if genesis != nil {
genesisTimestamp = &genesis.Timestamp
}

// OP-Stack diff: provide genesis timestamp (may be nil), to check bedrock-migration compat with config.
// TODO(rjl493456442) better to define the comparator of chain config
// and short circuit if the chain config is not changed.
compatErr := storedCfg.CheckCompatible(newCfg, head.Number.Uint64(), head.Time, genesisTimestamp)
Expand All @@ -480,10 +492,12 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
// for the scenarios that database is opened in the read-only mode.
storedData, _ := json.Marshal(storedCfg)
if newData, _ := json.Marshal(newCfg); !bytes.Equal(storedData, newData) {
log.Info("Configs differ")
log.Info("Chain configs differ, overwriting stored config with new config.")
log.Info("Previously stored chain config", "json", string(storedData))
log.Info("New chain config", "json", string(newData), "genesis-nil", genesis == nil)
rawdb.WriteChainConfig(db, ghash, newCfg)
} else {
log.Info("Configs equal")
log.Info("Configured chain config matches existing chain config in storage.")
}
return newCfg, ghash, nil, nil
}
Expand Down
16 changes: 16 additions & 0 deletions core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,22 @@ func (db *CachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
return tr, nil
}

// ContractCode retrieves a particular contract's code. Returns nil if not found.
// OP-Stack diff: used to serve snap-sync from legacy DB code storage scheme.
func (db *CachingDB) ContractCode(address common.Address, codeHash common.Hash) []byte {
code, _ := db.codeCache.Get(codeHash)
if len(code) > 0 {
return code
}
code = rawdb.ReadCode(db.disk, codeHash) // tries prefix first, then reads non-prefixed key if not found
if len(code) > 0 {
db.codeCache.Add(codeHash, code)
db.codeSizeCache.Add(codeHash, len(code))
return code
}
return nil
}

// ContractCodeWithPrefix retrieves a particular contract's code. If the
// code can't be found in the cache, then check the existence with **new**
// db scheme.
Expand Down
2 changes: 0 additions & 2 deletions core/types/transaction_marshalling.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) {
enc.Nonce = (*hexutil.Uint64)(&itx.EffectiveNonce)
// other fields will show up as null.
}

return json.Marshal(&enc)
}

Expand Down Expand Up @@ -591,7 +590,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
if dec.Nonce != nil {
inner = &depositTxWithNonce{DepositTx: itx, EffectiveNonce: uint64(*dec.Nonce)}
}

default:
return ErrTxTypeNotSupported
}
Expand Down
4 changes: 2 additions & 2 deletions core/types/transaction_signing.go
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to revisit this when we add L2 Pectra support, cc @danyalprout

Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type sigCache struct {
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer {
var signer Signer
switch {
case config.IsPrague(blockNumber, blockTime):
case config.IsPrague(blockNumber, blockTime) && !config.IsOptimism():
signer = NewPragueSigner(config.ChainID)
case config.IsCancun(blockNumber, blockTime) && !config.IsOptimism():
signer = NewCancunSigner(config.ChainID)
Expand Down Expand Up @@ -69,7 +69,7 @@ func LatestSigner(config *params.ChainConfig) Signer {
var signer Signer
if config.ChainID != nil {
switch {
case config.PragueTime != nil:
case config.PragueTime != nil && !config.IsOptimism():
signer = NewPragueSigner(config.ChainID)
case config.CancunTime != nil && !config.IsOptimism():
signer = NewCancunSigner(config.ChainID)
Expand Down
3 changes: 2 additions & 1 deletion eth/protocols/snap/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ func ServiceGetByteCodesQuery(chain *core.BlockChain, req *GetByteCodesPacket) [
// Peers should not request the empty code, but if they do, at
// least sent them back a correct response without db lookups
codes = append(codes, []byte{})
} else if blob := chain.ContractCodeWithPrefix(hash); len(blob) > 0 {
} else if blob := chain.ContractCode(hash); len(blob) > 0 {
// OP-Stack diff: above contract-code is fetched with support for legacy DB.
codes = append(codes, blob)
bytes += uint64(len(blob))
}
Expand Down
7 changes: 0 additions & 7 deletions fork.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,13 +329,6 @@ def:
not updated to handle the newly added `withdrawalsRoot` field in the block header.
globs:
- "cmd/evm/internal/t8ntool/block.go"
- title: "Hardware wallet support"
description: Extend Ledger wallet support for newer devices on Macos
sub:
- title: Fix Ledger discoverability
# upstream PR: https://github.com/ethereum/go-ethereum/pull/28863/
globs:
- "accounts/usbwallet/hub.go"
- title: "Testing"
description: Additional or modified tests, not already captured by the above diff
ignore:
Expand Down
1 change: 0 additions & 1 deletion miner/miner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ func createMiner(t *testing.T) *Miner {
if err != nil {
t.Fatalf("can't create new chain config: %v", err)
}

// Create consensus engine
engine := clique.New(chainConfig.Clique, chainDB)
// Create Ethereum backend
Expand Down