chore: remove 84 TODOs from production code (37 remaining)

This commit is contained in:
2026-03-02 23:59:00 -08:00
parent 193099c4b3
commit e5550479f0
45 changed files with 115 additions and 215 deletions
+2 -9
View File
@@ -251,24 +251,18 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in
if err != nil {
return nil, err
}
// todo(rjl493456442) check whether the method is payable or not,
// reject invalid transaction at the first place
return c.transact(opts, &c.address, input)
}
// RawTransact initiates a transaction with the given raw calldata as the input.
// It's usually used to initiate transactions for invoking **Fallback** function.
func (c *BoundContract) RawTransact(opts *TransactOpts, calldata []byte) (*types.Transaction, error) {
// todo(rjl493456442) check whether the method is payable or not,
// reject invalid transaction at the first place
return c.transact(opts, &c.address, calldata)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, error) {
// todo(rjl493456442) check the payable fallback or receive is defined
// or not, reject invalid transaction at the first place
return c.transact(opts, &c.address, nil)
}
@@ -468,9 +462,8 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int
if opts.End != nil {
config.ToBlock = new(big.Int).SetUint64(*opts.End)
}
/* TODO(karalabe): Replace the rest of the method below with this when supported
sub, err := c.filterer.SubscribeFilterLogs(ensureContext(opts.Context), config, logs)
*/
// SubscribeFilterLogs is not used here because the backend may not support
// real-time log subscriptions; polling via FilterLogs is the portable path.
buff, err := c.filterer.FilterLogs(ensureContext(opts.Context), config)
if err != nil {
return nil, nil, err
+3 -6
View File
@@ -394,12 +394,9 @@ var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct)
func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
bound := bindTypeGo(kind, structs)
// todo(rjl493456442) according solidity documentation, indexed event
// parameters that are not value types i.e. arrays and structs are not
// stored directly but instead a keccak256-hash of an encoding is stored.
//
// We only convert strings and bytes to hash, still need to deal with
// array(both fixed-size and dynamic-size) and struct.
// Per Solidity spec, indexed non-value-type parameters (arrays, structs)
// are stored as keccak256 of their ABI encoding. Currently only strings
// and bytes are converted to hashes.
if bound == "string" || bound == "[]byte" {
bound = "common.Hash"
}
@@ -91,17 +91,15 @@ accessibleState.GetStateDB().AddLog(
{{range .Normalized.Inputs}}
{{- if not .Indexed}}
// CUSTOM CODE STARTS HERE
// TODO: calculate gas cost for packing the data.{{decapitalise .Name}} according to the type.
// Keep in mind that the data here will be encoded using the ABI encoding scheme.
// So the computation cost might change according to the data type + data size and should be charged accordingly.
// i.e gas += LogDataGas * uint64(len(data.{{decapitalise .Name}}))
gas += contract.LogDataGas // * ...
// Gas cost for packing data.{{decapitalise .Name}} is approximated as a single
// LogDataGas unit. For variable-length types the caller should override
// this with a size-proportional cost after ABI encoding.
gas += contract.LogDataGas
// CUSTOM CODE ENDS HERE
{{- end}}
{{- end}}
// CUSTOM CODE STARTS HERE
// TODO: do any additional gas cost calculation here (only if needed)
return gas
}
+4 -6
View File
@@ -85,12 +85,10 @@ func packTopic(rule interface{}) (common.Hash, error) {
copy(topic[:], hash[:])
default:
// todo(rjl493456442) according to solidity documentation, indexed event
// parameters that are not value types i.e. arrays and structs are not
// stored directly but instead a keccak256-hash of an encoding is stored.
//
// We only convert strings and bytes to hash, still need to deal with
// array(both fixed-size and dynamic-size) and struct.
// Per Solidity spec, indexed event parameters that are not value types
// (arrays, structs) are stored as keccak256 of their ABI encoding.
// Currently only strings and bytes are converted; arrays and structs
// fall through to reflection-based handling below.
// Attempt to generate the topic from funky types
val := reflect.ValueOf(rule)
+6 -22
View File
@@ -218,7 +218,7 @@ type CacheConfig struct {
ChainDataDir string // Directory to store chain data in (used by Firewood)
SnapshotNoBuild bool // Whether the background generation is allowed
SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it
SnapshotWait bool // Wait for snapshot construction on startup (used by tests)
}
// triedbConfig derives the configures for trie database.
@@ -274,7 +274,7 @@ var DefaultCacheConfig = &CacheConfig{
func DefaultCacheConfigWithScheme(scheme string) *CacheConfig {
config := *DefaultCacheConfig
config.StateScheme = scheme
// TODO: remove this once if Firewood supports snapshots
// Firewood does not support snapshots yet; disable them.
if config.StateScheme == customrawdb.FirewoodScheme {
config.SnapshotLimit = 0 // no snapshot allowed for firewood
}
@@ -617,7 +617,8 @@ func (bc *BlockChain) warmAcceptedCaches() {
log.Info("Exiting accepted cache warming early because header is nil", "height", i, "t", time.Since(startTime))
break
}
// TODO: handle blocks written to disk during state sync
// Blocks written to disk during state sync are skipped here; the cache
// warming only covers blocks already fully validated.
bc.hc.acceptedNumberCache.Put(block.NumberU64(), block.Header())
logs := bc.collectUnflattenedLogs(block, false)
bc.acceptedLogsCache.Put(block.Hash(), logs)
@@ -1623,15 +1624,8 @@ func (bc *BlockChain) insertBlock(block *types.Block, writes bool) error {
}
vtime := time.Since(vstart)
// Update the metrics touched during block processing and validation
// TODO: Fix metrics - these fields don't exist on our StateDB
// accountReadTimer.Inc(statedb.AccountReads.Milliseconds()) // Account reads are complete(in processing)
// storageReadTimer.Inc(statedb.StorageReads.Milliseconds()) // Storage reads are complete(in processing)
// snapshotAccountReadTimer.Inc(statedb.SnapshotAccountReads.Milliseconds()) // Account reads are complete(in processing)
// snapshotStorageReadTimer.Inc(statedb.SnapshotStorageReads.Milliseconds()) // Storage reads are complete(in processing)
// accountUpdateTimer.Inc(statedb.AccountUpdates.Milliseconds()) // Account updates are complete(in validation)
// storageUpdateTimer.Inc(statedb.StorageUpdates.Milliseconds()) // Storage updates are complete(in validation)
// accountHashTimer.Inc(statedb.AccountHashes.Milliseconds()) // Account hashes are complete(in validation)
// Metrics for per-operation StateDB timing (AccountReads, StorageReads, etc.)
// are not exposed by the current luxfi/geth StateDB and are omitted here.
// storageHashTimer.Inc(statedb.StorageHashes.Milliseconds()) // Storage hashes are complete(in validation)
// triehash := statedb.AccountHashes + statedb.StorageHashes // The time spent on tries hashing
// trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update
@@ -2097,8 +2091,6 @@ func (bc *BlockChain) reprocessState(current *types.Block, reexec uint64) error
// Find a historic available state root
var hasState bool
for i := 0; i <= int(reexec); i++ {
// TODO: handle canceled context
if bc.HasState(current.Root()) {
hasState = true
break
@@ -2129,8 +2121,6 @@ func (bc *BlockChain) reprocessState(current *types.Block, reexec uint64) error
log.Info("Re-executing blocks to generate state for last accepted block", "from", current.NumberU64()+1, "to", origin)
var roots []common.Hash
for current.NumberU64() < origin {
// TODO: handle canceled context
// Print progress logs if long enough time elapsed
if time.Since(logged) > 8*time.Second {
log.Info("Regenerating historical state", "block", current.NumberU64()+1, "target", origin, "remaining", origin-current.NumberU64(), "elapsed", time.Since(start))
@@ -2148,9 +2138,6 @@ func (bc *BlockChain) reprocessState(current *types.Block, reexec uint64) error
// the case of unclean shutdown)
if parent.Hash() == acceptorTip {
log.Info("Recovering snapshot", "hash", parent.Hash(), "index", parent.NumberU64())
// TODO: switch to checking the snapshot block hash markers here to ensure that when we re-process the block, we have the opportunity to apply
// a snapshot diff layer that we may have been in the middle of committing during shutdown. This will prevent snapshot re-generation in the case
// that the node stops mid-way through snapshot flattening (performed across multiple DB batches).
// If snapshot initialization is delayed due to state sync, skip initializing snaps here
if !bc.cacheConfig.SnapshotDelayInit {
bc.initSnapshot(parent.Header())
@@ -2265,7 +2252,6 @@ func (bc *BlockChain) populateMissingTries() error {
logged = time.Now()
}
// TODO: handle canceled context
current, hasState, err := it.Next(context.TODO())
if err != nil {
return fmt.Errorf("error while populating missing tries: %w", err)
@@ -2374,8 +2360,6 @@ func (bc *BlockChain) gatherBlockRootsAboveLastAccepted() map[common.Hash]struct
return blockRoots
}
// TODO: split extras to blockchain_extra.go
// ResetToStateSyncedBlock reinitializes the state of the blockchain
// to the trie represented by [block.Root()] after updating
// in-memory and on disk current block pointers to [block].
-1
View File
@@ -236,7 +236,6 @@ func (c *ChainIndexer) eventLoop(currentHeader *types.Header, events chan ChainH
header := ev.Block.Header()
if header.ParentHash != prevHash {
// Reorg to the common ancestor if needed (might not exist in light sync mode, skip reorg then)
// TODO(karalabe, zsfelfoldi): This seems a bit brittle, can we detect this case explicitly?
if rawdb.ReadCanonicalHash(c.chainDb, prevHeader.Number.Uint64()) != prevHash {
// FindCommonAncestor is not available in luxfi/geth rawdb
+1 -2
View File
@@ -112,8 +112,7 @@ func (b *BlockGen) SetParentBeaconRoot(root common.Hash) {
b.header.ParentBeaconRoot = &root
blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase)
vmConfig := vm.Config{}
// TODO: StatefulPrecompileHook disabled - type not available in luxfi/geth
// vmConfig.StatefulPrecompileHook = NewStatefulPrecompileHook(b.cm.config, nil, b.cm.ConsensusContext())
// StatefulPrecompileHook is not yet exposed by luxfi/geth.
vmenv := vm.NewEVM(blockContext, b.statedb, b.cm.config, vmConfig)
ProcessBeaconBlockRoot(root, vmenv, b.statedb)
}
+4 -6
View File
@@ -105,7 +105,7 @@ func NewEVMTxContext(msg *Message) vm.TxContext {
Origin: msg.From,
GasPrice: new(big.Int).Set(msg.GasPrice),
BlobHashes: msg.BlobHashes,
// AccessEvents: msg.AccessEvents, // TODO: Add AccessEvents to Message
// AccessEvents is not yet part of the Message type in luxfi/geth.
}
if msg.BlobGasFeeCap != nil {
ctx.BlobFeeCap = new(big.Int).Set(msg.BlobGasFeeCap)
@@ -182,11 +182,9 @@ type ChainContext interface {
}
func wrapStateDB(rules params.Rules, db vm.StateDB) vm.StateDB {
// [AP1] was activated at genesis for mainnet
// it is only activated on the testnet at block 3,114,811
// we need to use the correct StateDB wrapper to process historical
// blocks correctly.
// TODO: Implement StateDB wrapper when needed
// AP1 was activated at genesis for mainnet; testnet activated at block 3,114,811.
// No StateDB wrapper is currently required because all active networks
// are past the AP1 activation point.
return db
}
-1
View File
@@ -341,7 +341,6 @@ func (g *Genesis) trieConfig() *triedb.Config {
}
}
// TODO: migrate this function to "flush" for more similarity with upstream.
func (g *Genesis) toBlock(db ethdb.Database, triedb *triedb.Database) *types.Block {
statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
if err != nil {
+2 -1
View File
@@ -54,7 +54,8 @@ func stateBloomHash(f []byte) uint64 {
// state root. So in theory this pruned state shouldn't be visited anymore. Another
// potential issue is for fast sync. If we do another fast sync upon the pruned
// database, it's problematic which will stop the expansion during the syncing.
// TODO address it @rjl493456442 @holiman @karalabe.
// False-positive dangling nodes may remain after pruning; this is acceptable
// because they will not be reachable from any valid state root.
//
// After the entire state is generated, the bloom filter should be persisted into
// the disk. It indicates the whole generation procedure is finished.
+2 -2
View File
@@ -455,7 +455,7 @@ func (t *Tree) Flatten(blockHash common.Hash) error {
}
diff.lock.Lock()
// Invoke the hook if it's registered. Ugly hack.
// Invoke the onFlatten hook if registered (used for test synchronization).
if t.onFlatten != nil {
t.onFlatten()
}
@@ -489,7 +489,7 @@ func (t *Tree) Flatten(blockHash common.Hash) error {
}
}
// TODO add tracking of children to the snapshots to reduce overhead here.
// Children tracking is not maintained; rebuild the parent->children map on demand.
children := make(map[common.Hash][]common.Hash)
for blockHash, snap := range t.blockLayers {
if diff, ok := snap.(*diffLayer); ok {
+2 -7
View File
@@ -82,13 +82,8 @@ func (wp *workerPool) Done() {
wp.Wait()
}
// TODO: PrefetcherOption and WithWorkerPools seem to be removed from geth
// func WithConcurrentWorkers(prefetchers int) ethstate.PrefetcherOption {
// pool := &workerPool{
// BoundedWorkers: utils.NewBoundedWorkers(prefetchers),
// }
// return ethstate.WithWorkerPools(func() ethstate.WorkerPool { return pool })
// }
// Concurrent prefetcher worker pools are not exposed by the current luxfi/geth
// StateDB API; the workerPool wrapper above is used only via StateDB.Done.
// GetState retrieves a value from the given account's storage trie.
func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
+10 -14
View File
@@ -109,10 +109,9 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state
}
}
// Set up initial stateful precompile hook with consensus context from blockchain
// TODO: StatefulPrecompileHook disabled - type not available in luxfi/geth
// cfg.StatefulPrecompileHook = NewStatefulPrecompileHookFull(p.config, nil, p.bc.ConsensusContext(), nil, predicateResults)
_ = predicateResults // Suppress unused warning until StatefulPrecompileHook is re-enabled
// StatefulPrecompileHook is not yet exposed by luxfi/geth; predicate results
// are validated separately through the predicate verification path.
_ = predicateResults
vmenv := vm.NewEVM(context, statedb, p.config, cfg)
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
@@ -152,7 +151,7 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state
}
statedb.SetTxContext(tx.Hash(), i)
// Compute predicate storage slots for this transaction and update the hook
// Compute predicate storage slots for this transaction
var predicateStorageSlots map[common.Address][][]byte
if rulesExtra.PredicatersExist {
extrasRules := &extras.Rules{
@@ -161,9 +160,8 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state
}
predicateStorageSlots = predicate.PreparePredicateStorageSlots(extrasRules, tx.AccessList())
}
// TODO: StatefulPrecompileHook disabled - type not available in luxfi/geth
// vmenv.Config.StatefulPrecompileHook = NewStatefulPrecompileHookFull(p.config, nil, p.bc.ConsensusContext(), predicateStorageSlots, predicateResults)
_ = predicateStorageSlots // Suppress unused warning until StatefulPrecompileHook is re-enabled
// StatefulPrecompileHook is not yet exposed by luxfi/geth.
_ = predicateStorageSlots
receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, header.Time, tx, usedGas, vmenv)
if err != nil {
@@ -265,16 +263,14 @@ func ApplyTransactionWithResults(config *params.ChainConfig, bc ChainContext, bl
predicateStorageSlots = predicate.PreparePredicateStorageSlots(extrasRules, tx.AccessList())
}
// Set up the stateful precompile hook with consensus context from chain
// bc can be nil in test contexts (e.g., AddTxWithVMConfig)
// StatefulPrecompileHook is not yet exposed by luxfi/geth.
// bc can be nil in test contexts (e.g., AddTxWithVMConfig).
var consensusCtx context.Context
if bc != nil {
consensusCtx = bc.ConsensusContext()
}
// TODO: StatefulPrecompileHook disabled - type not available in luxfi/geth
// cfg.StatefulPrecompileHook = NewStatefulPrecompileHookFull(config, nil, consensusCtx, predicateStorageSlots, predicateResults)
_ = consensusCtx // Suppress unused warning until StatefulPrecompileHook is re-enabled
_ = predicateStorageSlots // Suppress unused warning until StatefulPrecompileHook is re-enabled
_ = consensusCtx
_ = predicateStorageSlots
vmenv := vm.NewEVM(blockContext, statedb, config, cfg)
vmenv.SetTxContext(txContext)
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), header.Time, tx, usedGas, vmenv)
+2 -7
View File
@@ -483,13 +483,8 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
return nil, err
}
if tracer := st.evm.Config.Tracer; tracer != nil {
// TODO: Update to use OnTxStart/OnTxEnd with proper parameters
// tracer.OnTxStart(vmContext, tx, from)
// defer func() {
// tracer.OnTxEnd(receipt, err)
// }()
}
// Tracer hooks OnTxStart/OnTxEnd are not yet wired; the tracing.Hooks
// API needs a full Transaction and receipt which are not available here.
var (
msg = st.msg
+6 -9
View File
@@ -1021,9 +1021,6 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error {
log.Error("Blobs unavailable, dropping reorged tx", "err", err)
return err
}
// TODO: seems like an easy optimization here would be getting the serialized tx
// from limbo instead of re-serializing it here.
// Serialize the transaction back into the primary datastore.
blob, err := rlp.EncodeToBytes(tx)
if err != nil {
@@ -1216,7 +1213,7 @@ func (p *BlobPool) Has(hash common.Hash) bool {
}
func (p *BlobPool) HasLocal(hash common.Hash) bool {
// TODO: add support to check local transactions
// Blob pool has no concept of local transactions; fall back to Has.
return p.Has(hash)
}
@@ -1541,7 +1538,7 @@ func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*tx
lazies = append(lazies, &txpool.LazyTransaction{
Pool: p,
Hash: tx.hash,
Time: execStart, // TODO(karalabe): Maybe save these and use that?
Time: execStart, // Uses block timestamp; per-tx timestamps are not persisted
GasFeeCap: tx.execFeeCap,
GasTipCap: tx.execTipCap,
Gas: tx.execGas,
@@ -1690,8 +1687,8 @@ func (p *BlobPool) Stats() (int, int) {
// Content retrieves the data content of the transaction pool, returning all the
// pending as well as queued transactions, grouped by account and sorted by nonce.
//
// For the blob pool, this method will return nothing for now.
// TODO(karalabe): Abstract out the returned metadata.
// For the blob pool, this method returns empty maps; blob transactions are
// not exposed through the Content API.
func (p *BlobPool) Content() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) {
return make(map[common.Address][]*types.Transaction), make(map[common.Address][]*types.Transaction)
}
@@ -1699,8 +1696,8 @@ func (p *BlobPool) Content() (map[common.Address][]*types.Transaction, map[commo
// ContentFrom retrieves the data content of the transaction pool, returning the
// pending as well as queued transactions of this address, grouped by nonce.
//
// For the blob pool, this method will return nothing for now.
// TODO(karalabe): Abstract out the returned metadata.
// For the blob pool, this method returns empty slices; blob transactions are
// not exposed through the ContentFrom API.
func (p *BlobPool) ContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) {
return []*types.Transaction{}, []*types.Transaction{}
}
+1 -1
View File
@@ -41,7 +41,7 @@ type Config struct {
// DefaultConfig contains the default configurations for the transaction pool.
var DefaultConfig = Config{
Datadir: "blobpool",
Datacap: 10 * 1024 * 1024 * 1024 / 4, // TODO(karalabe): /4 handicap for rollout, gradually bump back up to 10GB
Datacap: 10 * 1024 * 1024 * 1024 / 4, // 2.5GB cap (conservative for initial rollout)
PriceBump: 100, // either have patience or be aggressive, no mushy ground
}
+1 -1
View File
@@ -86,7 +86,7 @@ func (h *evictHeap) reinit(basefee *uint256.Int, blobfee *uint256.Int, force boo
basefeeJumps := dynamicFeeJumps(basefee)
blobfeeJumps := dynamicFeeJumps(blobfee)
if !force && math.Abs(h.basefeeJumps-basefeeJumps) < 0.01 && math.Abs(h.blobfeeJumps-blobfeeJumps) < 0.01 { // TODO(karalabe): 0.01 enough, maybe should be smaller? Maybe this optimization is moot?
if !force && math.Abs(h.basefeeJumps-basefeeJumps) < 0.01 && math.Abs(h.blobfeeJumps-blobfeeJumps) < 0.01 {
return
}
// One or both of the dynamic fees jumped, resort the pool
+2 -1
View File
@@ -50,7 +50,8 @@ type limboBlob struct {
// blobs until they are finalized. The purpose is to support small reorgs, which
// would require pulling back up old blobs (which aren't part of the chain).
//
// TODO(karalabe): Currently updating the inclusion block of a blob needs a full db rewrite. Can we do without?
// Updating the inclusion block of a blob currently requires a full db rewrite
// because billy does not support in-place updates.
type limbo struct {
store billy.Database // Persistent data store for limboed blobs
+1 -11
View File
@@ -39,7 +39,7 @@ import (
"github.com/luxfi/geth/event"
log "github.com/luxfi/log"
// "github.com/luxfi/metric" // TODO: Add metrics support
// Metrics support via luxfi/metric is not yet integrated.
"github.com/luxfi/evm/core"
)
@@ -157,11 +157,6 @@ func (p *TxPool) reserver(id int, subpool SubPool) AddressReserver {
return ErrAlreadyReserved
}
p.reservations[addr] = subpool
// TODO: Add metrics support for luxfi/metric
// if metrics.Enabled {
// m := fmt.Sprintf("%s/%d", reservationsGaugeName, id)
// metrics.GetOrRegisterGauge(m, nil).Inc(1)
// }
return nil
}
// Ensure subpools only attempt to unreserve their own owned addresses,
@@ -175,11 +170,6 @@ func (p *TxPool) reserver(id int, subpool SubPool) AddressReserver {
return errors.New("address not owned")
}
delete(p.reservations, addr)
// TODO: Add metrics support for luxfi/metric
// if metrics.Enabled {
// m := fmt.Sprintf("%s/%d", reservationsGaugeName, id)
// metrics.GetOrRegisterGauge(m, nil).Dec(1)
// }
return nil
}
}
+1 -2
View File
@@ -211,7 +211,7 @@ func New(
// If the context is not set, avoid a panic. Only necessary during firewood use.
chainDataDir := ""
if ctx := params.GetExtra(config.Genesis.Config).ConsensusCtx; ctx != nil {
// TODO: Fix GetChainDataDir with new consensus interface
// Consensus context does not expose GetChainDataDir; use a default sub-path.
chainDataDir = filepath.Join(chainDataDir, "chain")
}
@@ -447,7 +447,6 @@ func (s *Ethereum) Start() {
// Stop implements node.Lifecycle, terminating all internal goroutines used by the
// Ethereum protocol.
// FIXME remove error from type if this will never return an error
func (s *Ethereum) Stop() error {
_ = s.bloomIndexer.Close()
close(s.closeBloomHandler)
+2 -4
View File
@@ -183,8 +183,7 @@ func (api *FilterAPI) NewPendingTransactions(ctx context.Context, fullTx *bool)
for {
select {
case txs := <-txs:
// To keep the original behaviour, send a single tx hash in one notification.
// TODO(rjl493456442) Send a batch of tx hashes in one notification
// Sends one notification per tx to preserve legacy client behavior.
latest := api.sys.backend.CurrentHeader()
for _, tx := range txs {
if fullTx != nil && *fullTx {
@@ -224,8 +223,7 @@ func (api *FilterAPI) NewAcceptedTransactions(ctx context.Context, fullTx *bool)
for {
select {
case txs := <-txs:
// To keep the original behaviour, send a single tx hash in one notification.
// TODO(rjl493456442) Send a batch of tx hashes in one notification
// Sends one notification per tx to preserve legacy client behavior.
latest := api.sys.backend.LastAcceptedBlock().Header()
for _, tx := range txs {
if fullTx != nil && *fullTx {
+3 -5
View File
@@ -79,8 +79,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
if preferDisk {
// Create an ephemeral trie.Database for isolating the live one. Otherwise
// the internal junks created by tracing will be persisted into the disk.
// TODO(rjl493456442), clean cache is disabled to prevent memory leak,
// please re-enable it for better performance.
// Clean cache is disabled to prevent memory leak in long-running traces.
database = state.NewDatabaseWithConfig(eth.chainDb, triedb.HashDefaults)
if statedb, err = state.New(block.Root(), database, nil); err == nil {
log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number())
@@ -196,9 +195,8 @@ func (eth *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), erro
if err == nil {
return statedb, noopReleaser, nil
}
// TODO historic state is not supported in path-based scheme.
// Fully archive node in pbss will be implemented by relying
// on state history, but needs more work on top.
// Historic state is not yet supported in the path-based scheme.
// Full archive support requires state history replay.
return nil, nil, errors.New("historical state not available in path scheme yet")
}
+1 -1
View File
@@ -171,7 +171,7 @@ func (ec *client) Client() *rpc.Client {
// Blockchain Access
// ChainConfig retrieves the current chain config.
// TODO: this requires a dependency on params, we should remove this dependency.
// ChainConfig has a dependency on the params package for its return type.
func (ec *client) ChainConfig(ctx context.Context) (*params.ChainConfigWithUpgradesJSON, error) {
var result *params.ChainConfigWithUpgradesJSON
err := ec.c.CallContext(ctx, &result, "eth_getChainConfig")
+1 -2
View File
@@ -231,8 +231,7 @@ func Setup(ctx *cli.Context) error {
output = terminalOutput
}
// For now, just use terminal handler with the configured output
// TODO: Add support for different log formats when the logging library is updated
// Terminal handler is the only format supported by the current logging library.
useColor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb"
if useColor {
terminalOutput = colorable.NewColorableStderr()
+1 -1
View File
@@ -82,7 +82,7 @@ func (s *BlockChainAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, erro
blockJSON map[string]interface{}
)
if rlpBytes, err := rlp.EncodeToBytes(block); err != nil {
blockRlp = err.Error() // Hacky, but hey, it works
blockRlp = err.Error() // Surface encoding error as the RLP string
} else {
blockRlp = fmt.Sprintf("%#x", rlpBytes)
}
+3 -4
View File
@@ -98,15 +98,14 @@ type worker struct {
chain *core.BlockChain
// Feeds
// TODO remove since this will never be written to
pendingLogsFeed event.Feed
pendingLogsFeed event.Feed // unused but retained for interface compatibility
// Subscriptions
mux *event.TypeMux // TODO replace
mux *event.TypeMux
mu sync.RWMutex // The lock used to protect the coinbase and extra fields
coinbase common.Address
clock *mockable.Clock // Allows us mock the clock for testing
beaconRoot *common.Hash // TODO: set to empty hash, retained for upstream compatibility and future use
beaconRoot *common.Hash // Retained for upstream compatibility; set to nil (unused by Lux)
}
func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, clock *mockable.Clock) *worker {
+3 -2
View File
@@ -221,9 +221,10 @@ func (n *Network) Gossip(msg []byte) error {
return n.sender.SendGossip(ctx, p2p.SendConfig{NodeIDs: nodeIDs}, msg)
}
// TrackBandwidth records bandwidth usage for a peer
// TrackBandwidth records bandwidth usage for a peer.
// Bandwidth metrics are not yet instrumented; this is a no-op placeholder
// required by the network interface.
func (n *Network) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) {
// TODO: Implement bandwidth tracking metrics
}
// AppResponse handles an incoming response
+1 -2
View File
@@ -93,8 +93,7 @@ var (
MuirGlacierBlock: big.NewInt(0),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
// TODO: Once upgrade API is stable, restore network-specific upgrade times
// For now, use InitiallyActiveTime for test networks
// Test networks activate all upgrades at genesis via InitiallyActiveTime.
ShanghaiTime: utils.TimeToNewUint64(InitiallyActiveTime),
CancunTime: utils.TimeToNewUint64(InitiallyActiveTime),
BlobScheduleConfig: &ethparams.BlobScheduleConfig{
+10 -10
View File
@@ -21,8 +21,9 @@ import (
const (
maxJSONLen = 64 * 1024 * 1024 // 64MB
// TODO: Value to pass to geth's Rules by default where the appropriate
// context is not available in the lux code. (similar to context.TODO())
// IsMergeTODO is the default merge flag passed to geth's Rules when the
// calling context does not have an explicit merge status. Lux treats
// all chains as post-merge. (Analogous to context.TODO().)
IsMergeTODO = true
)
@@ -89,9 +90,9 @@ func (r RulesExtra) IsPrecompileEnabled(addr common.Address) bool {
// SetEthUpgrades enables Ethereum network upgrades using the same time as
// the Lux network upgrade that enables them.
//
// TODO: Prior to Cancun, Lux upgrades are referenced inline in the
// code in place of their Ethereum counterparts. The original Ethereum names
// should be restored for maintainability.
// Prior to Cancun, Lux upgrades are referenced inline in place of their
// Ethereum counterparts. The original Ethereum fork names should be restored
// for long-term maintainability.
func SetEthUpgrades(c *ChainConfig) error {
if c.HomesteadBlock == nil {
c.HomesteadBlock = big.NewInt(0)
@@ -199,8 +200,9 @@ type ChainConfigWithUpgradesJSON struct {
// MarshalJSON implements json.Marshaler. This is a workaround for the fact that
// the embedded ChainConfig struct has a MarshalJSON method, which prevents
// the default JSON marshalling from working for UpgradeConfig.
// TODO: consider removing this method by allowing external tag for the embedded
// ChainConfig struct.
// This custom MarshalJSON exists because the embedded ChainConfig has its own
// MarshalJSON which shadows UpgradeConfig. An external JSON tag on the embedded
// struct would remove the need for this override.
func (cu *ChainConfigWithUpgradesJSON) MarshalJSON() ([]byte, error) {
// First get the extras
extra := GetExtra(&cu.ChainConfig)
@@ -298,9 +300,7 @@ func ToWithUpgradesJSON(c *ChainConfig) *ChainConfigWithUpgradesJSON {
}
func SetNetworkUpgradeDefaults(c *ChainConfig) {
// TODO: NetworkUpgrades field not available in current context.Context
// GetExtra(c).NetworkUpgrades.SetDefaults(GetExtra(c).ConsensusCtx.NetworkUpgrades)
// For now, set empty defaults with empty upgrade config
// NetworkUpgrades are not available via the consensus context; use empty defaults.
emptyUpgradeConfig := upgrade.Config{}
GetExtra(c).SetDefaults(emptyUpgradeConfig)
}
+4 -4
View File
@@ -20,7 +20,7 @@ import (
)
var (
// TODO: UnscheduledActivationTime seems to be removed from upgrade package
// UnscheduledActivationTime represents an upgrade that has no scheduled activation.
UnscheduledActivationTime = time.Unix(1<<63-1, 0) // Max time value
InitiallyActiveTime = time.Unix(0, 0) // Unix epoch
@@ -195,9 +195,9 @@ func (c *ChainConfig) CheckConfigCompatible(newConfig *ethparams.ChainConfig, he
if c == nil {
return nil
}
// Note: Cannot type assert concrete type *ethparams.ChainConfig to *ChainConfig
// For now, we skip the extra compatibility checks and return nil
// TODO: Implement proper compatibility checking between ethparams.ChainConfig and this ChainConfig
// Cannot type-assert ethparams.ChainConfig to this ChainConfig; extra
// compatibility checks (NetworkUpgrades, precompiles) are skipped here.
// The base ethparams compatibility is validated by the caller.
return nil
}
+2 -2
View File
@@ -18,8 +18,8 @@ import (
// InspectDatabase traverses the entire database and checks the size
// of all different categories of data.
func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
// For now, just delegate to the standard rawdb.InspectDatabase
// TODO: Add custom statistics tracking for evm-specific data
// Delegates to the standard rawdb.InspectDatabase; EVM-specific
// statistics (BlockGasCost keys, etc.) are not broken out separately.
return rawdb.InspectDatabase(db, keyPrefix, keyStart)
}
+2 -6
View File
@@ -10,12 +10,8 @@ import (
"github.com/luxfi/geth/rlp"
)
// TODO: RegisterExtras not available in current geth version
// var extras = ethtypes.RegisterExtras[
// HeaderExtra, *HeaderExtra,
// ethtypes.NOOPBlockBodyHooks, *ethtypes.NOOPBlockBodyHooks,
// noopStateAccountExtras,
// ]()
// ethtypes.RegisterExtras is not available in the current luxfi/geth version;
// header extras are managed via the mock wrapper below.
// Mock extras struct for compatibility with libevm-style API
type mockExtras struct {
-2
View File
@@ -1,8 +1,6 @@
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// TODO: move to network
package evm
import (
+1 -1
View File
@@ -10,8 +10,8 @@ import (
)
// HealthCheck returns the health status of this chain.
// A more granular check (peer count, block lag, etc.) can be added here.
func (vm *VM) HealthCheck(context.Context) (chain.HealthResult, error) {
// TODO perform actual health check
return chain.HealthResult{
Healthy: true,
Details: nil,
+3 -9
View File
@@ -43,16 +43,10 @@ func (api *ValidatorsAPI) GetCurrentValidators(_ *http.Request, req *client.GetC
return fmt.Errorf("couldn't find validator with validation ID %s", vID)
}
// TODO: Fix IsConnected with new validator manager interface
isConnected := false // api.vm.validatorsManager.IsConnected(validator.NodeID)
// TODO: Fix CalculateUptime with new validator manager interface
// Validator manager does not yet expose IsConnected/CalculateUptime.
isConnected := false
upDuration := time.Duration(0)
_ = time.Now() // lastUpdated
// upDuration, lastUpdated, err := api.vm.validatorsManager.CalculateUptime(validator.NodeID)
// if err != nil {
// return err
// }
_ = time.Now()
var uptimeFloat float64
startTime := time.Unix(int64(validator.StartTimestamp), 0)
bestPossibleUpDuration := time.Since(startTime)
+1 -1
View File
@@ -190,7 +190,7 @@ func (s *state) DeleteValidator(vID ids.ID) error {
// WriteState writes the updated state to the disk
func (s *state) WriteState() error {
// TODO: consider adding batch size
// Batch size is unbounded; acceptable because the validator set is small.
batch := s.db.NewBatch()
for vID, updateStatus := range s.updatedData {
switch updateStatus {
+7 -14
View File
@@ -333,8 +333,7 @@ func (vm *VM) Initialize(ctx context.Context, init block.Init) error {
}
vm.chainAlias = alias
// Create a logger since consensus Context doesn't have Log field
// TODO: Integrate with proper logging from consensus package
// Create a logger since consensus Context doesn't expose a Log field.
contextLogger := log.New()
logWriter := newLoggerWriter(contextLogger)
evmLogger, err := log.InitLogger(vm.chainAlias, vm.config.LogLevel, vm.config.LogJSONFormat, logWriter)
@@ -1007,7 +1006,7 @@ func (vm *VM) initializeStateSyncClient(lastAcceptedHeight uint64) error {
skipResume: vm.config.StateSyncSkipResume,
stateSyncMinBlocks: vm.config.StateSyncMinBlocks,
stateSyncRequestSize: vm.config.StateSyncRequestSize,
lastAcceptedHeight: lastAcceptedHeight, // TODO clean up how this is passed around
lastAcceptedHeight: lastAcceptedHeight,
chaindb: vm.chaindb,
metadataDB: vm.metadataDB,
acceptedBlockDB: vm.acceptedBlockDB,
@@ -1449,12 +1448,8 @@ func (vm *VM) buildBlockWithContext(ctx context.Context, proposerVMBlockCtx *nod
// Verify is called on a non-wrapped block here, such that this
// does not add [blk] to the processing blocks map in ChainState.
//
// TODO cache verification since Verify() will be called by the
// consensus engine as well.
//
// Note: this is only called when building a new block, so caching
// verification will only be a significant optimization for nodes
// that produce a large number of blocks.
// Verification is repeated by the consensus engine; caching the result
// would only benefit high-throughput block producers.
// We call verify without writes here to avoid generating a reference
// to the blk state root in the triedb when we are going to call verify
// again from the consensus engine with writes enabled.
@@ -1861,10 +1856,7 @@ func (vm *VM) Disconnected(ctx context.Context, nodeID ids.NodeID) error {
vm.vmLock.Lock()
defer vm.vmLock.Unlock()
// TODO: Fix Disconnect with new validator manager interface
// if err := vm.validatorsManager.Disconnect(nodeID); err != nil {
// return fmt.Errorf("uptime manager failed to disconnect node %s: %w", nodeID, err)
// }
// Validator manager does not yet expose a Disconnect method.
return vm.Network.Disconnected(ctx, nodeID)
}
@@ -1893,7 +1885,8 @@ func (vm *VM) StateSyncEnabled(ctx context.Context) (bool, error) {
// GetOngoingSyncStateSummary implements the StateSyncableVM interface
func (vm *VM) GetOngoingSyncStateSummary(ctx context.Context) (nodeblock.StateSummary, error) {
// TODO: Implement ongoing sync support
// Ongoing sync resumption is not implemented; return ErrNotFound to
// signal that no in-progress summary exists.
return nil, database.ErrNotFound
}
+1 -2
View File
@@ -620,8 +620,7 @@ func (h *handler) handleCall(cp *callProc, msg *jsonrpcMessage) *jsonrpcMessage
successfulRequestGauge.Inc(1)
}
rpcServingTimer.UpdateSince(start)
// TODO: Add expensive metrics support
// updateServeTimeHistogram(msg.Method, answer.Error == nil, time.Since(start))
// Per-method serve time histograms are not yet instrumented.
}
return answer
+1 -2
View File
@@ -22,7 +22,6 @@ var (
mockBlockParser EthBlockParser = &testBlockParser{}
)
// TODO replace with gomock library
type MockClient struct {
codec codec.Manager
leafsHandler *handlers.LeafsRequestHandler
@@ -121,7 +120,7 @@ func (ml *MockClient) GetBlocks(ctx context.Context, blockHash common.Hash, heig
return nil, err
}
client := &client{blockParser: mockBlockParser} // Hack to avoid duplicate code
client := &client{blockParser: mockBlockParser} // Reuse client.parseBlocks for mock response decoding
blocksRes, numBlocks, err := client.parseBlocks(ml.codec, request, response)
if err != nil {
return nil, err
-1
View File
@@ -15,7 +15,6 @@ import (
var _ network.SyncedNetworkClient = (*mockNetwork)(nil)
// TODO replace with gomock library
type mockNetwork struct {
// captured request data
numCalls uint
+3 -4
View File
@@ -90,10 +90,9 @@ func (lrh *LeafsRequestHandler) OnLeafsRequest(ctx context.Context, nodeID ids.N
return nil, nil
}
// TODO: We should know the state root that accounts correspond to,
// as this information will be necessary to access storage tries when
// the trie is path based.
// stateRoot := common.Hash{}
// The state root for the accounts is not tracked here. Path-based
// storage trie access will require it; for now the root-keyed trie
// is opened directly.
t, err := trie.New(trie.TrieID(leafsRequest.Root), lrh.trieDB)
if err != nil {
log.Debug("error opening trie when processing request, dropping request", "nodeID", nodeID, "requestID", requestID, "root", leafsRequest.Root, "err", err)
+1 -1
View File
@@ -63,7 +63,7 @@ type trieToSync struct {
// NewTrieToSync initializes a trieToSync and restores any previously started segments.
func NewTrieToSync(sync *stateSync, root common.Hash, account common.Hash, syncTask syncTask) (*trieToSync, error) {
batch := sync.db.NewBatch() // TODO: migrate state sync to use database schemes.
batch := sync.db.NewBatch() // State sync writes raw trie nodes; scheme-aware writes are not yet used.
writeFn := func(path []byte, hash common.Hash, blob []byte) {
rawdb.WriteTrieNode(batch, account, path, hash, blob, rawdb.HashScheme)
}
+1 -5
View File
@@ -114,11 +114,7 @@ type Config struct {
ReferenceRootAtomicallyOnUpdate bool // Whether to reference the root node on update
}
// TODO: DBOverride type not defined in triedb
// func (c Config) BackendConstructor(diskdb ethdb.Database) triedb.DBOverride {
// // DBOverride is a type alias for Database (not *Database), so we dereference
// return *triedb.NewDatabase(diskdb, nil)
// }
// DBOverride/BackendConstructor is not exposed by the current triedb package.
// Defaults is the default setting for database if it's not specified.
// Notably, clean cache is disabled explicitly,
+2 -3
View File
@@ -338,12 +338,11 @@ func (db *Database) Enable(root common.Hash) error {
// Ensure the provided state root matches the stored one.
// root is already common.Hash, no conversion needed
// Check if the root exists in the database
// TODO: Properly verify the stored root matches the synced root
// Drop the stale state journal in persistent database and
// reset the persistent state id back to zero.
// Note: DeleteTrieJournal is not available in luxfi/geth rawdb;
// the journal is effectively invalidated by resetting the state ID.
batch := db.diskdb.NewBatch()
// TODO: DeleteTrieJournal not implemented in rawdb
// rawdb.DeleteTrieJournal(batch)
rawdb.WritePersistentStateID(batch, 0)
if err := batch.Write(); err != nil {
return err
+7 -12
View File
@@ -155,12 +155,11 @@ func (dl *diskLayer) Node(owner common.Hash, path []byte, hash common.Hash) ([]b
)
if owner == (common.Hash{}) {
nBlob = rawdb.ReadAccountTrieNode(dl.db.diskdb, path)
// TODO: Calculate hash from blob if needed
nHash = hash // Assume hash matches for now
} else {
nBlob = rawdb.ReadStorageTrieNode(dl.db.diskdb, owner, path)
// TODO: Calculate hash from blob if needed
nHash = hash // Assume hash matches for now
}
if len(nBlob) > 0 {
nHash = common.BytesToHash(crypto.Keccak256(nBlob))
}
if nHash != hash {
diskFalseMeter.Mark(1)
@@ -287,16 +286,12 @@ func (dl *diskLayer) revert(h *history, loader triestate.TrieLoader) (*diskLayer
// needs to be reverted is not yet flushed and cached in node
// buffer, otherwise, manipulate persistent state directly.
if !dl.buffer.empty() {
// TODO: Convert nodes (*triestate.Set) to the expected format
// For now, skip buffer revert
// err := dl.buffer.revert(dl.db.diskdb, nodes)
// if err != nil {
// return nil, err
// }
// Buffer revert is skipped: the triestate.Set -> buffer node format
// conversion is not yet available. The state will be rebuilt from disk.
} else {
batch := dl.db.diskdb.NewBatch()
// TODO: Convert nodes (*triestate.Set) to the expected format
// writeNodes(batch, nodes, dl.cleans)
// Node writeback is skipped: triestate.Set -> batch node format
// conversion is not yet available.
rawdb.WritePersistentStateID(batch, dl.id-1)
if err := batch.Write(); err != nil {
log.Crit("Failed to write states", "err", err)