From d40d0db7f6fb410ec263a2a3fc009e377cec351d Mon Sep 17 00:00:00 2001 From: antonis19 Date: Thu, 5 Dec 2024 13:38:01 +0100 Subject: [PATCH 1/9] implement StartingTxNum() --- erigon-lib/kv/temporal/kv_temporal.go | 4 ++++ erigon-lib/state/aggregator.go | 12 ++++++++++++ erigon-lib/state/domain.go | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/erigon-lib/kv/temporal/kv_temporal.go b/erigon-lib/kv/temporal/kv_temporal.go index 7e6170db5c1..c7dda1ba789 100644 --- a/erigon-lib/kv/temporal/kv_temporal.go +++ b/erigon-lib/kv/temporal/kv_temporal.go @@ -194,6 +194,10 @@ func (tx *Tx) Commit() error { return mdbxTx.Commit() } +func (tx *Tx) StartingTxNum() uint64 { + return tx.filesTx.StartingTxNum() +} + func (tx *Tx) RangeAsOf(name kv.Domain, fromKey, toKey []byte, asOfTs uint64, asc order.By, limit int) (stream.KV, error) { it, err := tx.filesTx.RangeAsOf(tx.ctx, tx.MdbxTx, name, fromKey, toKey, asOfTs, asc, limit) if err != nil { diff --git a/erigon-lib/state/aggregator.go b/erigon-lib/state/aggregator.go index 17c0b02224a..411ff69357a 100644 --- a/erigon-lib/state/aggregator.go +++ b/erigon-lib/state/aggregator.go @@ -1729,6 +1729,18 @@ func (a *Aggregator) BuildFilesInBackground(txNum uint64) chan struct{} { return fin } +func (ac *AggregatorRoTx) StartingTxNum() uint64 { + earliestTxNum := uint64(math.MaxUint64) + // get the earliest txnum across all domains + for _, domain := range ac.d { + domainStartingTxNum := domain.StartingTxNum() + if domainStartingTxNum < earliestTxNum { + earliestTxNum = domainStartingTxNum + } + } + return earliestTxNum +} + func (ac *AggregatorRoTx) IndexRange(name kv.InvertedIdx, k []byte, fromTs, toTs int, asc order.By, limit int, tx kv.Tx) (timestamps stream.U64, err error) { switch name { case kv.AccountsHistoryIdx: diff --git a/erigon-lib/state/domain.go b/erigon-lib/state/domain.go index 328c25d1f0e..34c7859c5cd 100644 --- a/erigon-lib/state/domain.go +++ b/erigon-lib/state/domain.go @@ -1584,6 +1584,13 @@ func (dt *DomainRoTx) getFromFiles(filekey []byte, maxTxNum uint64) (v []byte, f return nil, false, 0, 0, nil } +func (dt *DomainRoTx) StartingTxNum() uint64 { + if len(dt.files) == 0 { + return 0 + } + return dt.files[0].startTxNum +} + func (dt *DomainRoTx) GetAsOfFile(key []byte, txNum uint64) ([]byte, bool, error) { var v []byte var foundStep uint64 From e77de163f65be3e96d74a2fa76ac16582ab71179 Mon Sep 17 00:00:00 2001 From: antonis19 Date: Thu, 5 Dec 2024 18:24:38 +0100 Subject: [PATCH 2/9] return PrunedError when attempting to access unavailable data --- core/state/history_reader_v3.go | 6 ++++++ erigon-lib/kv/kv_interface.go | 3 +++ erigon-lib/kv/remotedb/kv_remote.go | 10 ++++++++-- turbo/rpchelper/helper.go | 9 ++++++++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/core/state/history_reader_v3.go b/core/state/history_reader_v3.go index 8229fe1feb9..730dc6a20ec 100644 --- a/core/state/history_reader_v3.go +++ b/core/state/history_reader_v3.go @@ -17,6 +17,7 @@ package state import ( + "errors" "fmt" "github.com/erigontech/erigon-lib/common" @@ -25,6 +26,8 @@ import ( "github.com/erigontech/erigon-lib/types/accounts" ) +var PrunedError = errors.New("old data not available due to pruning") + // HistoryReaderV3 Implements StateReader and StateWriter type HistoryReaderV3 struct { txNum uint64 @@ -50,6 +53,9 @@ func (hr *HistoryReaderV3) SetTxNum(txNum uint64) { hr.txNum = txNum } func (hr *HistoryReaderV3) GetTxNum() uint64 { return hr.txNum } func (hr *HistoryReaderV3) SetTrace(trace bool) { hr.trace = trace } +// return the earliest known txnum in files +func (hr *HistoryReaderV3) StartingTxNum() uint64 { return hr.ttx.StartingTxNum() } + func (hr *HistoryReaderV3) ReadSet() map[string]*state.KvList { return nil } func (hr *HistoryReaderV3) ResetReadSet() {} func (hr *HistoryReaderV3) DiscardReadList() {} diff --git a/erigon-lib/kv/kv_interface.go b/erigon-lib/kv/kv_interface.go index 01eec6dbc04..6c2967cae59 100644 --- a/erigon-lib/kv/kv_interface.go +++ b/erigon-lib/kv/kv_interface.go @@ -464,6 +464,9 @@ type TemporalTx interface { Tx TemporalGetter + // return the earliest known txnum + StartingTxNum() uint64 + // DomainGetAsOf - state as of given `ts` // Example: GetAsOf(Account, key, txNum) - retuns account's value before `txNum` transaction changed it // Means if you want re-execute `txNum` on historical state - do `DomainGetAsOf(key, txNum)` to read state diff --git a/erigon-lib/kv/remotedb/kv_remote.go b/erigon-lib/kv/remotedb/kv_remote.go index 723b07ee4b9..a63ab391a3d 100644 --- a/erigon-lib/kv/remotedb/kv_remote.go +++ b/erigon-lib/kv/remotedb/kv_remote.go @@ -626,8 +626,14 @@ func (c *remoteCursorDupSort) PrevNoDup() ([]byte, []byte, error) { return c.pre func (c *remoteCursorDupSort) LastDup() ([]byte, error) { return c.lastDup() } // Temporal Methods -func (tx *tx) GetAsOf(name kv.Domain, k []byte, ts uint64) (v []byte, ok bool, err error) { - reply, err := tx.db.remoteKV.GetLatest(tx.ctx, &remote.GetLatestReq{TxId: tx.id, Table: name.String(), K: k, Ts: ts}) + +func (tx *tx) StateHistoryStartFrom() uint64 { + // TODO: not yet implemented, return 0 for now + return 0 +} + +func (tx *tx) GetAsOf(name kv.Domain, k, k2 []byte, ts uint64) (v []byte, ok bool, err error) { + reply, err := tx.db.remoteKV.GetLatest(tx.ctx, &remote.GetLatestReq{TxId: tx.id, Table: name.String(), K: k, K2: k2, Ts: ts}) if err != nil { return nil, false, err } diff --git a/turbo/rpchelper/helper.go b/turbo/rpchelper/helper.go index da8b03c490d..d2100c6b53f 100644 --- a/turbo/rpchelper/helper.go +++ b/turbo/rpchelper/helper.go @@ -161,7 +161,14 @@ func CreateHistoryStateReader(tx kv.Tx, txNumsReader rawdbv3.TxNumsReader, block if err != nil { return nil, err } - r.SetTxNum(uint64(int(minTxNum) + txnIndex + /* 1 system txNum in beginning of block */ 1)) + txNum := uint64(int(minTxNum) + txnIndex + /* 1 system txNum in beginning of block */ 1) + earliestTxNum := r.StartingTxNum() + if txNum < earliestTxNum { + // data available only starting from earliestTxNum, throw error to avoid unintended + // consequences of using this StateReader + return r, state.PrunedError + } + r.SetTxNum(txNum) return r, nil } From 1ce8f7e1be289861e94d573b40b37ccc4c54e7cc Mon Sep 17 00:00:00 2001 From: antonis19 Date: Wed, 11 Dec 2024 12:00:06 +0100 Subject: [PATCH 3/9] rename functions --- erigon-lib/kv/kv_interface.go | 4 ++-- erigon-lib/kv/temporal/kv_temporal.go | 4 ++-- erigon-lib/state/aggregator.go | 15 +++++++++++---- erigon-lib/state/domain.go | 7 ++++--- turbo/rpchelper/helper.go | 2 +- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/erigon-lib/kv/kv_interface.go b/erigon-lib/kv/kv_interface.go index 6c2967cae59..837d8cf916d 100644 --- a/erigon-lib/kv/kv_interface.go +++ b/erigon-lib/kv/kv_interface.go @@ -464,8 +464,8 @@ type TemporalTx interface { Tx TemporalGetter - // return the earliest known txnum - StartingTxNum() uint64 + // return the earliest known txnum in state history (excluding commitment and receipt history) + StateHistoryStartFrom() uint64 // DomainGetAsOf - state as of given `ts` // Example: GetAsOf(Account, key, txNum) - retuns account's value before `txNum` transaction changed it diff --git a/erigon-lib/kv/temporal/kv_temporal.go b/erigon-lib/kv/temporal/kv_temporal.go index c7dda1ba789..3846f208c31 100644 --- a/erigon-lib/kv/temporal/kv_temporal.go +++ b/erigon-lib/kv/temporal/kv_temporal.go @@ -194,8 +194,8 @@ func (tx *Tx) Commit() error { return mdbxTx.Commit() } -func (tx *Tx) StartingTxNum() uint64 { - return tx.filesTx.StartingTxNum() +func (tx *Tx) StateHistoryStartFrom() uint64 { + return tx.filesTx.StateHistoryStartFrom() } func (tx *Tx) RangeAsOf(name kv.Domain, fromKey, toKey []byte, asOfTs uint64, asc order.By, limit int) (stream.KV, error) { diff --git a/erigon-lib/state/aggregator.go b/erigon-lib/state/aggregator.go index 411ff69357a..d63ea9121e1 100644 --- a/erigon-lib/state/aggregator.go +++ b/erigon-lib/state/aggregator.go @@ -1729,11 +1729,13 @@ func (a *Aggregator) BuildFilesInBackground(txNum uint64) chan struct{} { return fin } -func (ac *AggregatorRoTx) StartingTxNum() uint64 { +// Returns the earliest txnum across accounts , storage , and code +func (ac *AggregatorRoTx) StateHistoryStartFrom() uint64 { earliestTxNum := uint64(math.MaxUint64) - // get the earliest txnum across all domains - for _, domain := range ac.d { - domainStartingTxNum := domain.StartingTxNum() + // get the minimum txnum across accounts , storage , and code + stateDomainNames := []kv.Domain{kv.AccountsDomain, kv.StorageDomain, kv.CodeDomain} + for domainName := range stateDomainNames { + domainStartingTxNum := ac.HistoryStartFrom(kv.Domain(domainName)) if domainStartingTxNum < earliestTxNum { earliestTxNum = domainStartingTxNum } @@ -1741,6 +1743,11 @@ func (ac *AggregatorRoTx) StartingTxNum() uint64 { return earliestTxNum } +// Returns the first known txNum found in history files of a given domain +func (ac *AggregatorRoTx) HistoryStartFrom(domainName kv.Domain) uint64 { + return ac.d[domainName].HistoryStartFrom() +} + func (ac *AggregatorRoTx) IndexRange(name kv.InvertedIdx, k []byte, fromTs, toTs int, asc order.By, limit int, tx kv.Tx) (timestamps stream.U64, err error) { switch name { case kv.AccountsHistoryIdx: diff --git a/erigon-lib/state/domain.go b/erigon-lib/state/domain.go index 34c7859c5cd..667d97473f7 100644 --- a/erigon-lib/state/domain.go +++ b/erigon-lib/state/domain.go @@ -1584,11 +1584,12 @@ func (dt *DomainRoTx) getFromFiles(filekey []byte, maxTxNum uint64) (v []byte, f return nil, false, 0, 0, nil } -func (dt *DomainRoTx) StartingTxNum() uint64 { - if len(dt.files) == 0 { +// Returns the first txNum from available history +func (dt *DomainRoTx) HistoryStartFrom() uint64 { + if len(dt.ht.files) == 0 { return 0 } - return dt.files[0].startTxNum + return dt.ht.files[0].startTxNum } func (dt *DomainRoTx) GetAsOfFile(key []byte, txNum uint64) ([]byte, bool, error) { diff --git a/turbo/rpchelper/helper.go b/turbo/rpchelper/helper.go index d2100c6b53f..173607dfc3f 100644 --- a/turbo/rpchelper/helper.go +++ b/turbo/rpchelper/helper.go @@ -162,7 +162,7 @@ func CreateHistoryStateReader(tx kv.Tx, txNumsReader rawdbv3.TxNumsReader, block return nil, err } txNum := uint64(int(minTxNum) + txnIndex + /* 1 system txNum in beginning of block */ 1) - earliestTxNum := r.StartingTxNum() + earliestTxNum := r.StateHistoryStartFrom() if txNum < earliestTxNum { // data available only starting from earliestTxNum, throw error to avoid unintended // consequences of using this StateReader From bf6f02b85bff4ba768b8375e79104a1c9306a8c1 Mon Sep 17 00:00:00 2001 From: antonis19 Date: Wed, 11 Dec 2024 12:01:09 +0100 Subject: [PATCH 4/9] add StateHistoryStartFrom() --- core/state/history_reader_v3.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/state/history_reader_v3.go b/core/state/history_reader_v3.go index 730dc6a20ec..e9ec010db6e 100644 --- a/core/state/history_reader_v3.go +++ b/core/state/history_reader_v3.go @@ -53,8 +53,20 @@ func (hr *HistoryReaderV3) SetTxNum(txNum uint64) { hr.txNum = txNum } func (hr *HistoryReaderV3) GetTxNum() uint64 { return hr.txNum } func (hr *HistoryReaderV3) SetTrace(trace bool) { hr.trace = trace } -// return the earliest known txnum in files -func (hr *HistoryReaderV3) StartingTxNum() uint64 { return hr.ttx.StartingTxNum() } +// Returns the earliest known txnum in history files for state history +// This is the smallest txNum found across: +// +// - Account history +// +// - Storage history +// +// - Code history +// +// Not considered in the calculation are Commitment history and Receipt history, as +// there are separate functions handling them. +func (hr *HistoryReaderV3) StateHistoryStartFrom() uint64 { + return hr.ttx.StateHistoryStartFrom() +} func (hr *HistoryReaderV3) ReadSet() map[string]*state.KvList { return nil } func (hr *HistoryReaderV3) ResetReadSet() {} From 2cec7f097a69064cfb2ad9a75a1e5341bf520400 Mon Sep 17 00:00:00 2001 From: antonis19 Date: Wed, 11 Dec 2024 12:11:38 +0100 Subject: [PATCH 5/9] fix merge conflict --- erigon-lib/kv/remotedb/kv_remote.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erigon-lib/kv/remotedb/kv_remote.go b/erigon-lib/kv/remotedb/kv_remote.go index a63ab391a3d..ceba1009b7b 100644 --- a/erigon-lib/kv/remotedb/kv_remote.go +++ b/erigon-lib/kv/remotedb/kv_remote.go @@ -632,8 +632,8 @@ func (tx *tx) StateHistoryStartFrom() uint64 { return 0 } -func (tx *tx) GetAsOf(name kv.Domain, k, k2 []byte, ts uint64) (v []byte, ok bool, err error) { - reply, err := tx.db.remoteKV.GetLatest(tx.ctx, &remote.GetLatestReq{TxId: tx.id, Table: name.String(), K: k, K2: k2, Ts: ts}) +func (tx *tx) GetAsOf(name kv.Domain, k []byte, ts uint64) (v []byte, ok bool, err error) { + reply, err := tx.db.remoteKV.GetLatest(tx.ctx, &remote.GetLatestReq{TxId: tx.id, Table: name.String(), K: k, Ts: ts}) if err != nil { return nil, false, err } From ca9bf80e50343f46cda9ed3c760030c517be0e6f Mon Sep 17 00:00:00 2001 From: antonis19 Date: Wed, 11 Dec 2024 12:16:05 +0100 Subject: [PATCH 6/9] fix range loop --- erigon-lib/state/aggregator.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erigon-lib/state/aggregator.go b/erigon-lib/state/aggregator.go index d63ea9121e1..f542bc0c1e4 100644 --- a/erigon-lib/state/aggregator.go +++ b/erigon-lib/state/aggregator.go @@ -1734,8 +1734,8 @@ func (ac *AggregatorRoTx) StateHistoryStartFrom() uint64 { earliestTxNum := uint64(math.MaxUint64) // get the minimum txnum across accounts , storage , and code stateDomainNames := []kv.Domain{kv.AccountsDomain, kv.StorageDomain, kv.CodeDomain} - for domainName := range stateDomainNames { - domainStartingTxNum := ac.HistoryStartFrom(kv.Domain(domainName)) + for _, domainName := range stateDomainNames { + domainStartingTxNum := ac.HistoryStartFrom(domainName) if domainStartingTxNum < earliestTxNum { earliestTxNum = domainStartingTxNum } From 4ddeb0573c1202342793489c17193db94bb5dc51 Mon Sep 17 00:00:00 2001 From: antonis19 Date: Wed, 11 Dec 2024 14:18:27 +0100 Subject: [PATCH 7/9] fix calculation logic --- erigon-lib/state/aggregator.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/erigon-lib/state/aggregator.go b/erigon-lib/state/aggregator.go index f542bc0c1e4..ad89f2e4fde 100644 --- a/erigon-lib/state/aggregator.go +++ b/erigon-lib/state/aggregator.go @@ -1729,14 +1729,20 @@ func (a *Aggregator) BuildFilesInBackground(txNum uint64) chan struct{} { return fin } -// Returns the earliest txnum across accounts , storage , and code +// Gets the txNum where Account, Storage and Code history begins. +// If the node is an archive node all history will be available therefore +// the result will be 0. +// +// For non-archive node old history files get deleted, so this number will vary +// but the goal is to know where the historical data begins func (ac *AggregatorRoTx) StateHistoryStartFrom() uint64 { - earliestTxNum := uint64(math.MaxUint64) - // get the minimum txnum across accounts , storage , and code + var earliestTxNum uint64 = 0 + // get the first txnum where accounts, storage , and code are all available in history files + // This is max(HistoryStart(Accounts), HistoryStart(Storage), HistoryStart(Code)) stateDomainNames := []kv.Domain{kv.AccountsDomain, kv.StorageDomain, kv.CodeDomain} for _, domainName := range stateDomainNames { domainStartingTxNum := ac.HistoryStartFrom(domainName) - if domainStartingTxNum < earliestTxNum { + if domainStartingTxNum > earliestTxNum { earliestTxNum = domainStartingTxNum } } From 8aafcb072b62f47ea4c998fcdfe292c854611ab3 Mon Sep 17 00:00:00 2001 From: antonis19 Date: Thu, 12 Dec 2024 13:44:59 +0100 Subject: [PATCH 8/9] move StateHistoryStartFrom to HistoryReaderV3 --- core/state/history_reader_v3.go | 27 ++++++++++++++++----------- erigon-lib/kv/kv_interface.go | 4 ++-- erigon-lib/kv/remotedb/kv_remote.go | 2 +- erigon-lib/kv/temporal/kv_temporal.go | 4 ++-- erigon-lib/state/aggregator.go | 20 -------------------- 5 files changed, 21 insertions(+), 36 deletions(-) diff --git a/core/state/history_reader_v3.go b/core/state/history_reader_v3.go index e9ec010db6e..dc37f71292c 100644 --- a/core/state/history_reader_v3.go +++ b/core/state/history_reader_v3.go @@ -53,19 +53,24 @@ func (hr *HistoryReaderV3) SetTxNum(txNum uint64) { hr.txNum = txNum } func (hr *HistoryReaderV3) GetTxNum() uint64 { return hr.txNum } func (hr *HistoryReaderV3) SetTrace(trace bool) { hr.trace = trace } -// Returns the earliest known txnum in history files for state history -// This is the smallest txNum found across: +// Gets the txNum where Account, Storage and Code history begins. +// If the node is an archive node all history will be available therefore +// the result will be 0. // -// - Account history -// -// - Storage history -// -// - Code history -// -// Not considered in the calculation are Commitment history and Receipt history, as -// there are separate functions handling them. +// For non-archive node old history files get deleted, so this number will vary +// but the goal is to know where the historical data begins. func (hr *HistoryReaderV3) StateHistoryStartFrom() uint64 { - return hr.ttx.StateHistoryStartFrom() + var earliestTxNum uint64 = 0 + // get the first txnum where accounts, storage , and code are all available in history files + // This is max(HistoryStart(Accounts), HistoryStart(Storage), HistoryStart(Code)) + stateDomainNames := []kv.Domain{kv.AccountsDomain, kv.StorageDomain, kv.CodeDomain} + for _, domainName := range stateDomainNames { + domainStartingTxNum := hr.ttx.HistoryStartFrom(domainName) + if domainStartingTxNum > earliestTxNum { + earliestTxNum = domainStartingTxNum + } + } + return earliestTxNum } func (hr *HistoryReaderV3) ReadSet() map[string]*state.KvList { return nil } diff --git a/erigon-lib/kv/kv_interface.go b/erigon-lib/kv/kv_interface.go index 837d8cf916d..c3a0b0bffad 100644 --- a/erigon-lib/kv/kv_interface.go +++ b/erigon-lib/kv/kv_interface.go @@ -464,8 +464,8 @@ type TemporalTx interface { Tx TemporalGetter - // return the earliest known txnum in state history (excluding commitment and receipt history) - StateHistoryStartFrom() uint64 + // return the earliest known txnum in history of a given domain + HistoryStartFrom(domainName Domain) uint64 // DomainGetAsOf - state as of given `ts` // Example: GetAsOf(Account, key, txNum) - retuns account's value before `txNum` transaction changed it diff --git a/erigon-lib/kv/remotedb/kv_remote.go b/erigon-lib/kv/remotedb/kv_remote.go index ceba1009b7b..6e64863ebb4 100644 --- a/erigon-lib/kv/remotedb/kv_remote.go +++ b/erigon-lib/kv/remotedb/kv_remote.go @@ -627,7 +627,7 @@ func (c *remoteCursorDupSort) LastDup() ([]byte, error) { return c.las // Temporal Methods -func (tx *tx) StateHistoryStartFrom() uint64 { +func (tx *tx) HistoryStartFrom(name kv.Domain) uint64 { // TODO: not yet implemented, return 0 for now return 0 } diff --git a/erigon-lib/kv/temporal/kv_temporal.go b/erigon-lib/kv/temporal/kv_temporal.go index 3846f208c31..6fe2c53fd2e 100644 --- a/erigon-lib/kv/temporal/kv_temporal.go +++ b/erigon-lib/kv/temporal/kv_temporal.go @@ -194,8 +194,8 @@ func (tx *Tx) Commit() error { return mdbxTx.Commit() } -func (tx *Tx) StateHistoryStartFrom() uint64 { - return tx.filesTx.StateHistoryStartFrom() +func (tx *Tx) HistoryStartFrom(name kv.Domain) uint64 { + return tx.filesTx.HistoryStartFrom(name) } func (tx *Tx) RangeAsOf(name kv.Domain, fromKey, toKey []byte, asOfTs uint64, asc order.By, limit int) (stream.KV, error) { diff --git a/erigon-lib/state/aggregator.go b/erigon-lib/state/aggregator.go index ad89f2e4fde..ae37d1931e8 100644 --- a/erigon-lib/state/aggregator.go +++ b/erigon-lib/state/aggregator.go @@ -1729,26 +1729,6 @@ func (a *Aggregator) BuildFilesInBackground(txNum uint64) chan struct{} { return fin } -// Gets the txNum where Account, Storage and Code history begins. -// If the node is an archive node all history will be available therefore -// the result will be 0. -// -// For non-archive node old history files get deleted, so this number will vary -// but the goal is to know where the historical data begins -func (ac *AggregatorRoTx) StateHistoryStartFrom() uint64 { - var earliestTxNum uint64 = 0 - // get the first txnum where accounts, storage , and code are all available in history files - // This is max(HistoryStart(Accounts), HistoryStart(Storage), HistoryStart(Code)) - stateDomainNames := []kv.Domain{kv.AccountsDomain, kv.StorageDomain, kv.CodeDomain} - for _, domainName := range stateDomainNames { - domainStartingTxNum := ac.HistoryStartFrom(domainName) - if domainStartingTxNum > earliestTxNum { - earliestTxNum = domainStartingTxNum - } - } - return earliestTxNum -} - // Returns the first known txNum found in history files of a given domain func (ac *AggregatorRoTx) HistoryStartFrom(domainName kv.Domain) uint64 { return ac.d[domainName].HistoryStartFrom() From 43b228bc9b89977acdc779c9c7ec193f4821d1b2 Mon Sep 17 00:00:00 2001 From: antonis19 Date: Thu, 12 Dec 2024 13:58:13 +0100 Subject: [PATCH 9/9] implement HistoryStartFrom for MemoryMutation --- erigon-lib/kv/membatchwithdb/memory_mutation.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erigon-lib/kv/membatchwithdb/memory_mutation.go b/erigon-lib/kv/membatchwithdb/memory_mutation.go index e40e46e1afa..60cfbb68dda 100644 --- a/erigon-lib/kv/membatchwithdb/memory_mutation.go +++ b/erigon-lib/kv/membatchwithdb/memory_mutation.go @@ -741,3 +741,7 @@ func (m *MemoryMutation) HistoryRange(name kv.Domain, fromTs, toTs int, asc orde panic("not supported") // return m.db.(kv.TemporalTx).HistoryRange(name, fromTs, toTs, asc, limit) } + +func (m *MemoryMutation) HistoryStartFrom(name kv.Domain) uint64 { + return m.db.(kv.TemporalTx).HistoryStartFrom(name) +}