diff --git a/docs/content/api/openapi.yaml b/docs/content/api/openapi.yaml index 4aa3d07d2e..7a89974c68 100644 --- a/docs/content/api/openapi.yaml +++ b/docs/content/api/openapi.yaml @@ -7,7 +7,7 @@ info: license: name: GPL 3.0 url: http://www.gnu.org/licenses/ - version: 2.1.0-release + version: 2.2.0-release description: > A REST layer over the TrueBlocks application. With `chifra daemon`, you can @@ -3918,6 +3918,9 @@ components: type: string string: type: string + uint64: + type: number + format: uint64 topic: type: string format: bytes diff --git a/docs/templates/api/components.txt b/docs/templates/api/components.txt index 87d97b09b0..e48129aa47 100644 --- a/docs/templates/api/components.txt +++ b/docs/templates/api/components.txt @@ -1531,6 +1531,9 @@ components: type: string string: type: string + uint64: + type: number + format: uint64 topic: type: string format: bytes diff --git a/src/apps/chifra/internal/abis/handle_addresses.go b/src/apps/chifra/internal/abis/handle_show.go similarity index 96% rename from src/apps/chifra/internal/abis/handle_addresses.go rename to src/apps/chifra/internal/abis/handle_show.go index b007977699..8803c3e3fc 100644 --- a/src/apps/chifra/internal/abis/handle_addresses.go +++ b/src/apps/chifra/internal/abis/handle_show.go @@ -14,7 +14,7 @@ import ( "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" ) -func (opts *AbisOptions) HandleAddresses() (err error) { +func (opts *AbisOptions) HandleShow() (err error) { abiCache := articulate.NewAbiCache(opts.Conn, opts.Known) ctx, cancel := context.WithCancel(context.Background()) diff --git a/src/apps/chifra/internal/abis/output.go b/src/apps/chifra/internal/abis/output.go index 3438a057fb..e707979cd8 100644 --- a/src/apps/chifra/internal/abis/output.go +++ b/src/apps/chifra/internal/abis/output.go @@ -59,7 +59,7 @@ func (opts *AbisOptions) AbisInternal() error { } else if len(opts.Encode) > 0 { err = opts.HandleEncode() } else { - err = opts.HandleAddresses() + err = opts.HandleShow() } // EXISTING_CODE timer.Report(msg) diff --git a/src/apps/chifra/internal/blocks/handle_hashes.go b/src/apps/chifra/internal/blocks/handle_hashes.go index 411d673bdc..47b9e5fa33 100644 --- a/src/apps/chifra/internal/blocks/handle_hashes.go +++ b/src/apps/chifra/internal/blocks/handle_hashes.go @@ -19,28 +19,28 @@ import ( func (opts *BlocksOptions) HandleHashes() error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode nErrors := 0 ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawBlock], errorChan chan error) { + // var cnt int var err error - var appMap map[identifiers.ResolvedId]*types.SimpleBlock[string] + var appMap map[types.SimpleAppearance]*types.SimpleBlock[string] if appMap, _, err = identifiers.AsMap[types.SimpleBlock[string]](chain, opts.BlockIds); err != nil { errorChan <- err cancel() } - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - bar := logger.NewBar(logger.BarOptions{ Type: logger.Expanding, Enabled: !opts.Globals.TestMode, Total: int64(len(appMap)), }) - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleBlock[string]) error { - if block, err := opts.Conn.GetBlockHeaderByNumber(app.BlockNumber); err != nil { + iterFunc := func(app types.SimpleAppearance, value *types.SimpleBlock[string]) error { + bn := uint64(app.BlockNumber) + if block, err := opts.Conn.GetBlockHeaderByNumber(bn); err != nil { errorChan <- err if errors.Is(err, ethereum.NotFound) { errorChan <- errors.New("uncles not found") @@ -55,9 +55,11 @@ func (opts *BlocksOptions) HandleHashes() error { } iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - if !opts.Globals.TestMode || nErrors == 0 { + if !testMode || nErrors == 0 { errorChan <- err nErrors++ } diff --git a/src/apps/chifra/internal/blocks/handle_logs.go b/src/apps/chifra/internal/blocks/handle_logs.go index 0b94c54e38..3259d28004 100644 --- a/src/apps/chifra/internal/blocks/handle_logs.go +++ b/src/apps/chifra/internal/blocks/handle_logs.go @@ -20,6 +20,9 @@ import ( func (opts *BlocksOptions) HandleLogs() error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode + nErrors := 0 + abiCache := articulate.NewAbiCache(opts.Conn, opts.Articulate) emitters := []base.Address{} for _, e := range opts.Emitter { @@ -34,35 +37,34 @@ func (opts *BlocksOptions) HandleLogs() error { Topics: topics, } - nErrors := 0 ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawLog], errorChan chan error) { - txMap, _, err := identifiers.AsMap[types.SimpleTransaction](chain, opts.BlockIds) - if err != nil { + // var cnt int + var err error + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.BlockIds); err != nil { errorChan <- err cancel() } bar := logger.NewBar(logger.BarOptions{ Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), + Total: int64(len(appMap)), }) - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { if value.Receipt == nil { value.Receipt = &types.SimpleReceipt{} } - ts := opts.Conn.GetBlockTimestamp(app.BlockNumber) - if logs, err := opts.Conn.GetLogsByNumber(app.BlockNumber, ts); err != nil { - errorChan <- fmt.Errorf("block at %d returned an error: %w", app.BlockNumber, err) + bn := uint64(app.BlockNumber) + ts := opts.Conn.GetBlockTimestamp(bn) + if logs, err := opts.Conn.GetLogsByNumber(bn, ts); err != nil { + errorChan <- fmt.Errorf("block at %d returned an error: %w", bn, err) return nil } else if len(logs) == 0 { - errorChan <- fmt.Errorf("block at %d has no logs", app.BlockNumber) + errorChan <- fmt.Errorf("block at %d has no logs", bn) return nil } else { @@ -82,11 +84,11 @@ func (opts *BlocksOptions) HandleLogs() error { } iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - // iterCancel() - if !opts.Globals.TestMode || nErrors == 0 { + if !testMode || nErrors == 0 { errorChan <- err // Reporting more than one error causes tests to fail because they // appear concurrently so sort differently @@ -95,8 +97,8 @@ func (opts *BlocksOptions) HandleLogs() error { } bar.Finish(true) - items := make([]types.SimpleLog, 0, len(txMap)) - for _, tx := range txMap { + items := make([]types.SimpleLog, 0, len(appMap)) + for _, tx := range appMap { tx := tx items = append(items, tx.Receipt.Logs...) } diff --git a/src/apps/chifra/internal/blocks/handle_show.go b/src/apps/chifra/internal/blocks/handle_show.go index 85816fbf8f..2672d5b5df 100644 --- a/src/apps/chifra/internal/blocks/handle_show.go +++ b/src/apps/chifra/internal/blocks/handle_show.go @@ -19,28 +19,27 @@ import ( func (opts *BlocksOptions) HandleShow() error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode nErrors := 0 ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawBlock], errorChan chan error) { + // var cnt int var err error - var appMap map[identifiers.ResolvedId]*types.SimpleBlock[types.SimpleTransaction] + var appMap map[types.SimpleAppearance]*types.SimpleBlock[types.SimpleTransaction] if appMap, _, err = identifiers.AsMap[types.SimpleBlock[types.SimpleTransaction]](chain, opts.BlockIds); err != nil { errorChan <- err cancel() } - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - bar := logger.NewBar(logger.BarOptions{ Type: logger.Expanding, Enabled: !opts.Globals.TestMode, Total: int64(len(appMap)), }) - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleBlock[types.SimpleTransaction]) error { - if block, err := opts.Conn.GetBlockBodyByNumber(app.BlockNumber); err != nil { + iterFunc := func(app types.SimpleAppearance, value *types.SimpleBlock[types.SimpleTransaction]) error { + if block, err := opts.Conn.GetBlockBodyByNumber(uint64(app.BlockNumber)); err != nil { errorChan <- err if errors.Is(err, ethereum.NotFound) { errorChan <- errors.New("uncles not found") @@ -55,9 +54,11 @@ func (opts *BlocksOptions) HandleShow() error { } iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - if !opts.Globals.TestMode || nErrors == 0 { + if !testMode || nErrors == 0 { errorChan <- err nErrors++ } diff --git a/src/apps/chifra/internal/blocks/handle_uncles.go b/src/apps/chifra/internal/blocks/handle_uncles.go index b71bc8c1d0..a8784d6794 100644 --- a/src/apps/chifra/internal/blocks/handle_uncles.go +++ b/src/apps/chifra/internal/blocks/handle_uncles.go @@ -19,29 +19,29 @@ import ( func (opts *BlocksOptions) HandleUncles() error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode nErrors := 0 ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawBlock], errorChan chan error) { + // var cnt int var err error - var appMap map[identifiers.ResolvedId]*types.SimpleBlock[types.SimpleTransaction] + var appMap map[types.SimpleAppearance]*types.SimpleBlock[types.SimpleTransaction] if appMap, _, err = identifiers.AsMap[types.SimpleBlock[types.SimpleTransaction]](chain, opts.BlockIds); err != nil { errorChan <- err cancel() } - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - uncles := make([]types.SimpleBlock[types.SimpleTransaction], 0, len(appMap)) bar := logger.NewBar(logger.BarOptions{ Type: logger.Expanding, Enabled: !opts.Globals.TestMode, Total: int64(len(appMap)), }) - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleBlock[types.SimpleTransaction]) error { - if uncs, err := opts.Conn.GetUncleBodiesByNumber(app.BlockNumber); err != nil { + uncles := make([]types.SimpleBlock[types.SimpleTransaction], 0, len(appMap)) + iterFunc := func(app types.SimpleAppearance, value *types.SimpleBlock[types.SimpleTransaction]) error { + bn := uint64(app.BlockNumber) + if uncs, err := opts.Conn.GetUncleBodiesByNumber(bn); err != nil { errorChan <- err if errors.Is(err, ethereum.NotFound) { errorChan <- errors.New("uncles not found") @@ -61,9 +61,11 @@ func (opts *BlocksOptions) HandleUncles() error { } iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - if !opts.Globals.TestMode || nErrors == 0 { + if !testMode || nErrors == 0 { errorChan <- err nErrors++ } diff --git a/src/apps/chifra/internal/blocks/handle_uniq.go b/src/apps/chifra/internal/blocks/handle_uniq.go index f58f8a9332..99a5bbc9c8 100644 --- a/src/apps/chifra/internal/blocks/handle_uniq.go +++ b/src/apps/chifra/internal/blocks/handle_uniq.go @@ -20,34 +20,35 @@ import ( func (opts *BlocksOptions) HandleUniq() error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode nErrors := 0 ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawAppearance], errorChan chan error) { + // var cnt int var err error - var appMap map[identifiers.ResolvedId]*types.SimpleAppearance + var appMap map[types.SimpleAppearance]*types.SimpleAppearance if appMap, _, err = identifiers.AsMap[types.SimpleAppearance](chain, opts.BlockIds); err != nil { errorChan <- err cancel() } - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - apps := make([]types.SimpleAppearance, 0, len(appMap)) bar := logger.NewBar(logger.BarOptions{ Type: logger.Expanding, Enabled: !opts.Globals.TestMode, Total: int64(len(appMap)), }) - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleAppearance) error { + + apps := make([]types.SimpleAppearance, 0, len(appMap)) + iterFunc := func(app types.SimpleAppearance, value *types.SimpleAppearance) error { + bn := uint64(app.BlockNumber) procFunc := func(s *types.SimpleAppearance) error { bar.Tick() apps = append(apps, *s) return nil } - if err := uniq.GetUniqAddressesInBlock(chain, opts.Flow, opts.Conn, procFunc, app.BlockNumber); err != nil { + if err := uniq.GetUniqAddressesInBlock(chain, opts.Flow, opts.Conn, procFunc, bn); err != nil { errorChan <- err if errors.Is(err, ethereum.NotFound) { return nil @@ -58,9 +59,11 @@ func (opts *BlocksOptions) HandleUniq() error { } iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - if !opts.Globals.TestMode || nErrors == 0 { + if !testMode || nErrors == 0 { errorChan <- err nErrors++ } diff --git a/src/apps/chifra/internal/blocks/handle_withdrawals.go b/src/apps/chifra/internal/blocks/handle_withdrawals.go index ca1561fdba..0000d6f2ff 100644 --- a/src/apps/chifra/internal/blocks/handle_withdrawals.go +++ b/src/apps/chifra/internal/blocks/handle_withdrawals.go @@ -17,28 +17,28 @@ import ( func (opts *BlocksOptions) HandleWithdrawals() error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode nErrors := 0 ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawWithdrawal], errorChan chan error) { + // var cnt int var err error - var appMap map[identifiers.ResolvedId]*types.SimpleBlock[string] + var appMap map[types.SimpleAppearance]*types.SimpleBlock[string] if appMap, _, err = identifiers.AsMap[types.SimpleBlock[string]](chain, opts.BlockIds); err != nil { errorChan <- err cancel() } - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - bar := logger.NewBar(logger.BarOptions{ Type: logger.Expanding, Enabled: !opts.Globals.TestMode, Total: int64(len(appMap)), }) - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleBlock[string]) error { - if block, err := opts.Conn.GetBlockHeaderByNumber(app.BlockNumber); err != nil { + iterFunc := func(app types.SimpleAppearance, value *types.SimpleBlock[string]) error { + bn := uint64(app.BlockNumber) + if block, err := opts.Conn.GetBlockHeaderByNumber(bn); err != nil { errorChan <- err cancel() return nil @@ -50,9 +50,11 @@ func (opts *BlocksOptions) HandleWithdrawals() error { } iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - if !opts.Globals.TestMode || nErrors == 0 { + if !testMode || nErrors == 0 { errorChan <- err nErrors++ } diff --git a/src/apps/chifra/internal/chunks/handle_check_deep.go b/src/apps/chifra/internal/chunks/handle_check_deep.go index d9523d9af3..bb9375b138 100644 --- a/src/apps/chifra/internal/chunks/handle_check_deep.go +++ b/src/apps/chifra/internal/chunks/handle_check_deep.go @@ -35,25 +35,27 @@ type reporter struct { // actually pinned. The later requires a locally running IPFS node. func (opts *ChunksOptions) CheckDeep(cacheMan *manifest.Manifest, report *simpleReportCheck) error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode + nErrors := 0 mutex := sync.Mutex{} - theMap := make(map[string]*reporter) + appMap := make(map[string]*reporter) for _, chunk := range cacheMan.ChunkMap { - theMap[chunk.Range] = &reporter{chunk, report, &mutex} + appMap[chunk.Range] = &reporter{chunk, report, &mutex} } bar := logger.NewBar(logger.BarOptions{ - Total: int64(len(theMap)), + Total: int64(len(appMap)), Enabled: true, }) addrCnt := 0 var sh *shell.Shell - var procFunc func(rangeStr string, item *reporter) (err error) + var iterFunc func(rangeStr string, item *reporter) (err error) if opts.Mode == "index" { logger.Info("Checking each address in each index against its Bloom filter...") - procFunc = func(rangeStr string, item *reporter) (err error) { + iterFunc = func(rangeStr string, item *reporter) (err error) { rng := base.RangeFromRangeString(item.chunk.Range) _, path := rng.RangeToFilename(chain) bl, err := index.OpenBloom(index.ToBloomPath(path), true /* check */) @@ -87,7 +89,7 @@ func (opts *ChunksOptions) CheckDeep(cacheMan *manifest.Manifest, report *simple } addrCnt++ if i%8000 == 0 { - bar.Prefix = fmt.Sprintf("Checked %d addresses against %d Blooms", addrCnt, len(theMap)) + bar.Prefix = fmt.Sprintf("Checked %d addresses against %d Blooms", addrCnt, len(appMap)) bar.Tick() } } @@ -102,13 +104,12 @@ func (opts *ChunksOptions) CheckDeep(cacheMan *manifest.Manifest, report *simple return nil } - bar.Finish(true) return nil } } else if opts.Mode == "manifest" { sh = shell.NewShell(config.GetPinning().LocalPinUrl) - procFunc = func(rangeStr string, item *reporter) (err error) { + iterFunc = func(rangeStr string, item *reporter) (err error) { bar.Tick() err = checkHashes(item.chunk, "blooom", sh, item) if err != nil { @@ -120,16 +121,17 @@ func (opts *ChunksOptions) CheckDeep(cacheMan *manifest.Manifest, report *simple return fmt.Errorf("unknown mode: %s", opts.Mode) } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - errorChan := make(chan error) - go utils.IterateOverMap(ctx, errorChan, theMap, procFunc) - - // Block until we get an error from any of the iterations or the iteration finishes - if stepErr := <-errorChan; stepErr != nil { - cancel() - return stepErr + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + logger.Fatal(err) + nErrors++ + } } + bar.Finish(true) return nil } diff --git a/src/apps/chifra/internal/export/handle_accounting.go b/src/apps/chifra/internal/export/handle_accounting.go index a2197529bc..cb1966a90b 100644 --- a/src/apps/chifra/internal/export/handle_accounting.go +++ b/src/apps/chifra/internal/export/handle_accounting.go @@ -57,7 +57,7 @@ func (opts *ExportOptions) HandleAccounting(monitorArray []monitor.Monitor) erro } if opts.Accounting { - if statements, err := ledgers.GetStatementsFromAppearance(opts.Conn, &raw); err != nil { + if statements, err := ledgers.GetStatementsFromAppearance(opts.Conn, filter, &raw); err != nil { errorChan <- err } else { tx.Statements = &statements diff --git a/src/apps/chifra/internal/export/handle_neighbors.go b/src/apps/chifra/internal/export/handle_neighbors.go index 37c2795168..5b15cb830c 100644 --- a/src/apps/chifra/internal/export/handle_neighbors.go +++ b/src/apps/chifra/internal/export/handle_neighbors.go @@ -19,6 +19,8 @@ import ( ) func (opts *ExportOptions) HandleNeighbors(monitorArray []monitor.Monitor) error { + testMode := opts.Globals.TestMode + nErrors := 0 filter := filter.NewFilter( opts.Reversed, opts.Reverted, @@ -30,7 +32,10 @@ func (opts *ExportOptions) HandleNeighbors(monitorArray []monitor.Monitor) error ctx := context.Background() fetchData := func(modelChan chan types.Modeler[types.RawAppearance], errorChan chan error) { for _, mon := range monitorArray { - if neighborMap, cnt, err := monitor.ReadAppearancesToMap[bool](&mon, filter); err != nil { + var cnt int + var err error + var appMap map[types.SimpleAppearance]*bool + if appMap, cnt, err = monitor.AsMap[bool](&mon, filter); err != nil { errorChan <- err return } else if !opts.NoZero || cnt > 0 { @@ -39,30 +44,32 @@ func (opts *ExportOptions) HandleNeighbors(monitorArray []monitor.Monitor) error Enabled: !opts.Globals.TestMode, Total: mon.Count(), }) - allNeighbors := make([]Reason, 0) + + neighbors := make([]Reason, 0) iterFunc := func(app types.SimpleAppearance, unused *bool) error { - if neighbors, err := GetNeighbors(&app); err != nil { + if theseNeighbors, err := GetNeighbors(&app); err != nil { return err } else { - allNeighbors = append(allNeighbors, neighbors...) + neighbors = append(neighbors, theseNeighbors...) return nil } } - // Set up and interate over the map calling iterFunc for each appearance - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - errChan := make(chan error) - go utils.IterateOverMap(ctx, errChan, neighborMap, iterFunc) - if stepErr := <-errChan; stepErr != nil { - errorChan <- stepErr - } else { - bar.Finish(true) + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } + bar.Finish(true) // Sort the items back into an ordered array by block number - items := make([]types.SimpleAppearance, 0, len(neighborMap)) - for _, neighbor := range allNeighbors { + items := make([]types.SimpleAppearance, 0, len(appMap)) + for _, neighbor := range neighbors { app := types.SimpleAppearance{ Address: *neighbor.Address, BlockNumber: neighbor.App.BlockNumber, diff --git a/src/apps/chifra/internal/export/handle_show.go b/src/apps/chifra/internal/export/handle_show.go index 2672a253a2..dcac73665f 100644 --- a/src/apps/chifra/internal/export/handle_show.go +++ b/src/apps/chifra/internal/export/handle_show.go @@ -34,7 +34,10 @@ func (opts *ExportOptions) HandleShow(monitorArray []monitor.Monitor) error { ctx := context.Background() fetchData := func(modelChan chan types.Modeler[types.RawTransaction], errorChan chan error) { for _, mon := range monitorArray { - if txMap, cnt, err := monitor.ReadAppearancesToMap[types.SimpleTransaction](&mon, filter); err != nil { + var cnt int + var err error + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, cnt, err = monitor.AsMap[types.SimpleTransaction](&mon, filter); err != nil { errorChan <- err return } else if !opts.NoZero || cnt > 0 { @@ -43,13 +46,14 @@ func (opts *ExportOptions) HandleShow(monitorArray []monitor.Monitor) error { Enabled: !opts.Globals.TestMode, Total: mon.Count(), }) - if err := opts.readTransactions(txMap, filter, bar, false /* readTraces */); err != nil { // calls IterateOverMap + + if err := opts.readTransactions(appMap, filter, bar, false /* readTraces */); err != nil { errorChan <- err return } - items := make([]*types.SimpleTransaction, 0, len(txMap)) - for _, tx := range txMap { + items := make([]*types.SimpleTransaction, 0, len(appMap)) + for _, tx := range appMap { if opts.Articulate { if err = abiCache.ArticulateTransaction(tx); err != nil { errorChan <- err // continue even on error diff --git a/src/apps/chifra/internal/export/handle_traces.go b/src/apps/chifra/internal/export/handle_traces.go index 6034625330..8c144819c3 100644 --- a/src/apps/chifra/internal/export/handle_traces.go +++ b/src/apps/chifra/internal/export/handle_traces.go @@ -6,13 +6,10 @@ package exportPkg import ( "context" - "fmt" - "sort" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/articulate" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/filter" - "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/monitor" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/names" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output" @@ -63,95 +60,3 @@ func (opts *ExportOptions) HandleTraces(monitorArray []monitor.Monitor) error { return output.StreamMany(ctx, fetchData, opts.Globals.OutputOptsWithExtra(extra)) } - -func (opts *ExportOptions) readTraces( - monitorArray []monitor.Monitor, - mon *monitor.Monitor, - filter *filter.AppearanceFilter, - errorChan chan error, - abiCache *articulate.AbiCache, -) ([]*types.SimpleTrace, error) { - if txMap, cnt, err := monitor.ReadAppearancesToMap[types.SimpleTransaction](mon, filter); err != nil { - errorChan <- err - return nil, err - } else if !opts.NoZero || cnt > 0 { - bar := logger.NewBar(logger.BarOptions{ - Prefix: mon.Address.Hex(), - Enabled: !opts.Globals.TestMode, - Total: mon.Count(), - }) - if err := opts.readTransactions(txMap, filter, bar, true /* readTraces */); err != nil { // calls IterateOverMap - return nil, err - } - - // Sort the items back into an ordered array by block number - items := make([]*types.SimpleTrace, 0, len(txMap)) - for _, tx := range txMap { - for index, trace := range tx.Traces { - trace := trace - trace.TraceIndex = uint64(index) - isCreate := trace.Action.CallType == "creation" || trace.TraceType == "create" - if !opts.Factory || isCreate { - if opts.Articulate { - if err := abiCache.ArticulateTrace(&trace); err != nil { - errorChan <- fmt.Errorf("error articulating trace: %v", err) - } - } - items = append(items, &trace) - } - } - } - sort.Slice(items, func(i, j int) bool { - if opts.Reversed { - i, j = j, i - } - itemI := items[i] - itemJ := items[j] - if itemI.BlockNumber == itemJ.BlockNumber { - if itemI.TransactionIndex == itemJ.TransactionIndex { - return itemI.TraceIndex < itemJ.TraceIndex - } - return itemI.TransactionIndex < itemJ.TransactionIndex - } - return itemI.BlockNumber < itemJ.BlockNumber - }) - - // Return the array of items - return items, nil - } else { - errorChan <- fmt.Errorf("no appearances found for %s", mon.Address.Hex()) - return nil, nil - } -} - -/* -TODO: NOTE - bool isSelfDestruct = trace.action.selfDestructed != ""; - if (isSelfDestruct) { - copy.action.from = trace.action.selfDestructed; - copy.action.to = trace.action.refundAddress; - copy.action.callType = "suicide"; - copy.action.value = trace.action.balance; - copy.traceAddress.push_back("s"); - copy.transactionHash = uint_2_Hex(trace.blockNumber * 100000 + trace.transactionIndex); - copy.action.input = "0x"; - } - cout << ((isJson() && !opt->firstOut) ? ", " : ""); - cout << copy; - opt->firstOut = false; - bool isCreation = trace.result.address != ""; - if (isCreation) { - copy.action.from = "0x0"; - copy.action.to = trace.result.address; - copy.action.callType = "creation"; - copy.action.value = trace.action.value; - if (copy.traceAddress.size() == 0) - copy.traceAddress.push_back("null"); - copy.traceAddress.push_back("s"); - copy.transactionHash = uint_2_Hex(trace.blockNumber * 100000 + trace.transactionIndex); - copy.action.input = trace.action.input; - cout << ((isJson() && !opt->firstOut) ? ", " : ""); - cout << copy; - opt->firstOut = false; - -*/ diff --git a/src/apps/chifra/internal/export/iterate_balances.go b/src/apps/chifra/internal/export/iterate_balances.go index a67f66cf91..b769edd6d2 100644 --- a/src/apps/chifra/internal/export/iterate_balances.go +++ b/src/apps/chifra/internal/export/iterate_balances.go @@ -19,17 +19,15 @@ func (opts *ExportOptions) readBalances( filter *filter.AppearanceFilter, errorChan chan error, ) ([]*types.SimpleToken, error) { - + testMode := opts.Globals.TestMode + nErrors := 0 var cnt int var err error - var txMap map[types.SimpleAppearance]*types.SimpleToken - - if txMap, cnt, err = monitor.ReadAppearancesToMap[types.SimpleToken](mon, filter); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleToken + if appMap, cnt, err = monitor.AsMap[types.SimpleToken](mon, filter); err != nil { errorChan <- err return nil, err - } - - if opts.NoZero && cnt == 0 { + } else if opts.NoZero && cnt == 0 { errorChan <- fmt.Errorf("no appearances found for %s", mon.Address.Hex()) return nil, nil } @@ -57,20 +55,21 @@ func (opts *ExportOptions) readBalances( return nil } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - errChan := make(chan error) - go utils.IterateOverMap(ctx, errChan, txMap, iterFunc) - if stepErr := <-errChan; stepErr != nil { - return nil, stepErr - } else { - bar.Finish(true) + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } + bar.Finish(true) // Sort the items back into an ordered array by block number - items := make([]*types.SimpleToken, 0, len(txMap)) - for _, tx := range txMap { + items := make([]*types.SimpleToken, 0, len(appMap)) + for _, tx := range appMap { items = append(items, tx) } sort.Slice(items, func(i, j int) bool { diff --git a/src/apps/chifra/internal/export/iterate_logs.go b/src/apps/chifra/internal/export/iterate_logs.go index 20e5bfbe0b..1344e173c5 100644 --- a/src/apps/chifra/internal/export/iterate_logs.go +++ b/src/apps/chifra/internal/export/iterate_logs.go @@ -21,14 +21,11 @@ func (opts *ExportOptions) readLogs( ) ([]*types.SimpleLog, error) { var cnt int var err error - var txMap map[types.SimpleAppearance]*types.SimpleTransaction - - if txMap, cnt, err = monitor.ReadAppearancesToMap[types.SimpleTransaction](mon, filter); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, cnt, err = monitor.AsMap[types.SimpleTransaction](mon, filter); err != nil { errorChan <- err return nil, err - } - - if opts.NoZero && cnt == 0 { + } else if opts.NoZero && cnt == 0 { errorChan <- fmt.Errorf("no appearances found for %s", mon.Address.Hex()) return nil, nil } @@ -39,19 +36,19 @@ func (opts *ExportOptions) readLogs( Total: mon.Count(), }) - if err := opts.readTransactions(txMap, filter, bar, false /* readTraces */); err != nil { // calls IterateOverMap + if err := opts.readTransactions(appMap, filter, bar, false /* readTraces */); err != nil { return nil, err } // Sort the items back into an ordered array by block number - items := make([]*types.SimpleLog, 0, len(txMap)) - for _, tx := range txMap { + items := make([]*types.SimpleLog, 0, len(appMap)) + for _, tx := range appMap { if tx.Receipt == nil { continue } for _, log := range tx.Receipt.Logs { log := log - if log.ContainsAny(addrArray) && opts.matchesFilter(&log) { + if filter.ApplyLogFilter(&log, addrArray) && opts.matchesFilter(&log) { if opts.Articulate { if err := abiCache.ArticulateLog(&log); err != nil { errorChan <- fmt.Errorf("error articulating log: %v", err) diff --git a/src/apps/chifra/internal/export/iterate_receipts.go b/src/apps/chifra/internal/export/iterate_receipts.go index 075cd93b6b..ddce574dba 100644 --- a/src/apps/chifra/internal/export/iterate_receipts.go +++ b/src/apps/chifra/internal/export/iterate_receipts.go @@ -19,17 +19,13 @@ func (opts *ExportOptions) readReceipts( errorChan chan error, abiCache *articulate.AbiCache, ) ([]*types.SimpleReceipt, error) { - var cnt int var err error - var txMap map[types.SimpleAppearance]*types.SimpleTransaction - - if txMap, cnt, err = monitor.ReadAppearancesToMap[types.SimpleTransaction](mon, filter); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, cnt, err = monitor.AsMap[types.SimpleTransaction](mon, filter); err != nil { errorChan <- err return nil, err - } - - if opts.NoZero && cnt == 0 { + } else if opts.NoZero && cnt == 0 { errorChan <- fmt.Errorf("no appearances found for %s", mon.Address.Hex()) return nil, nil } @@ -40,19 +36,19 @@ func (opts *ExportOptions) readReceipts( Total: mon.Count(), }) - if err := opts.readTransactions(txMap, filter, bar, false /* readTraces */); err != nil { // calls IterateOverMap + if err := opts.readTransactions(appMap, filter, bar, false /* readTraces */); err != nil { return nil, err } - items := make([]*types.SimpleReceipt, 0, len(txMap)) - for _, tx := range txMap { + items := make([]*types.SimpleReceipt, 0, len(appMap)) + for _, tx := range appMap { if tx.Receipt == nil { continue } filteredLogs := make([]types.SimpleLog, 0, len(tx.Receipt.Logs)) for _, log := range tx.Receipt.Logs { log := log - if log.ContainsAny(addrArray) && opts.matchesFilter(&log) { + if filter.ApplyLogFilter(&log, addrArray) && opts.matchesFilter(&log) { if opts.Articulate { if err := abiCache.ArticulateLog(&log); err != nil { errorChan <- fmt.Errorf("error articulating log: %v", err) diff --git a/src/apps/chifra/internal/export/iterate_statements.go b/src/apps/chifra/internal/export/iterate_statements.go index ffea95e8bc..b43770eea5 100644 --- a/src/apps/chifra/internal/export/iterate_statements.go +++ b/src/apps/chifra/internal/export/iterate_statements.go @@ -19,21 +19,13 @@ func (opts *ExportOptions) readStatements( errorChan chan error, abiCache *articulate.AbiCache, ) ([]*types.SimpleStatement, error) { - - if !opts.Accounting { - logger.Fatal("should not happen ==> accounting is not enabled. Implementation error.") - } - var cnt int var err error - var txMap map[types.SimpleAppearance]*types.SimpleTransaction - - if txMap, cnt, err = monitor.ReadAppearancesToMap[types.SimpleTransaction](mon, filter); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, cnt, err = monitor.AsMap[types.SimpleTransaction](mon, filter); err != nil { errorChan <- err return nil, err - } - - if opts.NoZero && cnt == 0 { + } else if opts.NoZero && cnt == 0 { errorChan <- fmt.Errorf("no appearances found for %s", mon.Address.Hex()) return nil, nil } @@ -44,12 +36,12 @@ func (opts *ExportOptions) readStatements( Total: mon.Count(), }) - if err := opts.readTransactions(txMap, filter, bar, false /* readTraces */); err != nil { // calls IterateOverMap + if err := opts.readTransactions(appMap, filter, bar, false /* readTraces */); err != nil { return nil, err } - txArray := make([]*types.SimpleTransaction, 0, len(txMap)) - for _, tx := range txMap { + txArray := make([]*types.SimpleTransaction, 0, len(appMap)) + for _, tx := range appMap { txArray = append(txArray, tx) } @@ -61,7 +53,7 @@ func (opts *ExportOptions) readStatements( }) // Sort the items back into an ordered array by block number - items := make([]*types.SimpleStatement, 0, len(txMap)) + items := make([]*types.SimpleStatement, 0, len(appMap)) chain := opts.Globals.Chain testMode := opts.Globals.TestMode @@ -77,7 +69,7 @@ func (opts *ExportOptions) readStatements( &opts.Asset, ) - apps := make([]types.SimpleAppearance, 0, len(txMap)) + apps := make([]types.SimpleAppearance, 0, len(appMap)) for _, tx := range txArray { apps = append(apps, types.SimpleAppearance{ BlockNumber: uint32(tx.BlockNumber), @@ -89,7 +81,7 @@ func (opts *ExportOptions) readStatements( // we need them sorted for the following to work for _, tx := range txArray { ledgers.Tx = tx // we need this below - if stmts := ledgers.GetStatementsFromTransaction(opts.Conn, tx); len(stmts) > 0 { + if stmts := ledgers.GetStatementsFromTransaction(opts.Conn, filter, tx); len(stmts) > 0 { for _, statement := range stmts { statement := statement items = append(items, statement) diff --git a/src/apps/chifra/internal/export/iterate_traces.go b/src/apps/chifra/internal/export/iterate_traces.go new file mode 100644 index 0000000000..613d99a583 --- /dev/null +++ b/src/apps/chifra/internal/export/iterate_traces.go @@ -0,0 +1,112 @@ +// Copyright 2021 The TrueBlocks Authors. All rights reserved. +// Use of this source code is governed by a license that can +// be found in the LICENSE file. + +package exportPkg + +import ( + "fmt" + "sort" + + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/articulate" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/filter" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/monitor" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" +) + +func (opts *ExportOptions) readTraces( + monitorArray []monitor.Monitor, + mon *monitor.Monitor, + filter *filter.AppearanceFilter, + errorChan chan error, + abiCache *articulate.AbiCache, +) ([]*types.SimpleTrace, error) { + var cnt int + var err error + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, cnt, err = monitor.AsMap[types.SimpleTransaction](mon, filter); err != nil { + errorChan <- err + return nil, err + } else if opts.NoZero && cnt == 0 { + errorChan <- fmt.Errorf("no appearances found for %s", mon.Address.Hex()) + return nil, nil + } + + bar := logger.NewBar(logger.BarOptions{ + Prefix: mon.Address.Hex(), + Enabled: !opts.Globals.TestMode, + Total: mon.Count(), + }) + + if err := opts.readTransactions(appMap, filter, bar, true /* readTraces */); err != nil { + return nil, err + } + + // Sort the items back into an ordered array by block number + items := make([]*types.SimpleTrace, 0, len(appMap)) + for _, tx := range appMap { + for index, trace := range tx.Traces { + trace := trace + trace.TraceIndex = uint64(index) + isCreate := trace.Action.CallType == "creation" || trace.TraceType == "create" + if !opts.Factory || isCreate { + if opts.Articulate { + if err := abiCache.ArticulateTrace(&trace); err != nil { + errorChan <- fmt.Errorf("error articulating trace: %v", err) + } + } + items = append(items, &trace) + } + } + } + sort.Slice(items, func(i, j int) bool { + if opts.Reversed { + i, j = j, i + } + itemI := items[i] + itemJ := items[j] + if itemI.BlockNumber == itemJ.BlockNumber { + if itemI.TransactionIndex == itemJ.TransactionIndex { + return itemI.TraceIndex < itemJ.TraceIndex + } + return itemI.TransactionIndex < itemJ.TransactionIndex + } + return itemI.BlockNumber < itemJ.BlockNumber + }) + + // Return the array of items + return items, nil +} + +/* +TODO: NOTE + bool isSelfDestruct = trace.action.selfDestructed != ""; + if (isSelfDestruct) { + copy.action.from = trace.action.selfDestructed; + copy.action.to = trace.action.refundAddress; + copy.action.callType = "suicide"; + copy.action.value = trace.action.balance; + copy.traceAddress.push_back("s"); + copy.transactionHash = uint_2_Hex(trace.blockNumber * 100000 + trace.transactionIndex); + copy.action.input = "0x"; + } + cout << ((isJson() && !opt->firstOut) ? ", " : ""); + cout << copy; + opt->firstOut = false; + bool isCreation = trace.result.address != ""; + if (isCreation) { + copy.action.from = "0x0"; + copy.action.to = trace.result.address; + copy.action.callType = "creation"; + copy.action.value = trace.action.value; + if (copy.traceAddress.size() == 0) + copy.traceAddress.push_back("null"); + copy.traceAddress.push_back("s"); + copy.transactionHash = uint_2_Hex(trace.blockNumber * 100000 + trace.transactionIndex); + copy.action.input = trace.action.input; + cout << ((isJson() && !opt->firstOut) ? ", " : ""); + cout << copy; + opt->firstOut = false; + +*/ diff --git a/src/apps/chifra/internal/export/iterate_transactions.go b/src/apps/chifra/internal/export/iterate_transactions.go index 6a780f9636..c35e9a4519 100644 --- a/src/apps/chifra/internal/export/iterate_transactions.go +++ b/src/apps/chifra/internal/export/iterate_transactions.go @@ -36,10 +36,10 @@ func (opts *ExportOptions) readTransactions( } // Set up and interate over the map calling iterFunc for each appearance - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() errChan := make(chan error) - go utils.IterateOverMap(ctx, errChan, theMap, iterFunc) + go utils.IterateOverMap(iterCtx, errChan, theMap, iterFunc) if stepErr := <-errChan; stepErr != nil { return stepErr } else if bar != nil { diff --git a/src/apps/chifra/internal/export/iterate_withdrawals.go b/src/apps/chifra/internal/export/iterate_withdrawals.go index b9ac93ecf3..c89b5c4063 100644 --- a/src/apps/chifra/internal/export/iterate_withdrawals.go +++ b/src/apps/chifra/internal/export/iterate_withdrawals.go @@ -17,17 +17,15 @@ func (opts *ExportOptions) readWithdrawals( filter *filter.AppearanceFilter, errorChan chan error, ) ([]*types.SimpleWithdrawal, error) { - + nErrors := 0 + testMode := opts.Globals.TestMode var cnt int var err error - var withdrawalMap map[types.SimpleAppearance]*types.SimpleBlock[string] - - if withdrawalMap, cnt, err = monitor.ReadAppearancesToMap[types.SimpleBlock[string]](mon, filter); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleBlock[string] + if appMap, cnt, err = monitor.AsMap[types.SimpleBlock[string]](mon, filter); err != nil { errorChan <- err return nil, err - } - - if opts.NoZero && cnt == 0 { + } else if opts.NoZero && cnt == 0 { errorChan <- fmt.Errorf("no appearances found for %s", mon.Address.Hex()) return nil, nil } @@ -59,20 +57,21 @@ func (opts *ExportOptions) readWithdrawals( return nil } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - errChan := make(chan error) - go utils.IterateOverMap(ctx, errChan, withdrawalMap, iterFunc) - if stepErr := <-errChan; stepErr != nil { - return nil, stepErr - } else { - bar.Finish(true) + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } + bar.Finish(true) // Sort the items back into an ordered array by block number - items := make([]*types.SimpleWithdrawal, 0, len(withdrawalMap)) - for _, block := range withdrawalMap { + items := make([]*types.SimpleWithdrawal, 0, len(appMap)) + for _, block := range appMap { for _, with := range block.Withdrawals { items = append(items, &with) } diff --git a/src/apps/chifra/internal/list/handle_list.go b/src/apps/chifra/internal/list/handle_list.go index 925e5b7f2d..94111087e6 100644 --- a/src/apps/chifra/internal/list/handle_list.go +++ b/src/apps/chifra/internal/list/handle_list.go @@ -17,7 +17,7 @@ import ( "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/utils" ) -func (opts *ListOptions) HandleListAppearances(monitorArray []monitor.Monitor) error { +func (opts *ListOptions) HandleShow(monitorArray []monitor.Monitor) error { chain := opts.Globals.Chain filter := filter.NewFilter( opts.Reversed, diff --git a/src/apps/chifra/internal/list/output.go b/src/apps/chifra/internal/list/output.go index 99decd3652..b749ee8a3d 100644 --- a/src/apps/chifra/internal/list/output.go +++ b/src/apps/chifra/internal/list/output.go @@ -64,7 +64,7 @@ func (opts *ListOptions) ListInternal() error { } else if opts.Bounds { err = opts.HandleBounds(monitorArray) } else if !opts.Silent { - err = opts.HandleListAppearances(monitorArray) + err = opts.HandleShow(monitorArray) } // EXISTING_CODE timer.Report(msg) diff --git a/src/apps/chifra/internal/logs/handle_show.go b/src/apps/chifra/internal/logs/handle_show.go index c6b4f864b4..bf4437bfab 100644 --- a/src/apps/chifra/internal/logs/handle_show.go +++ b/src/apps/chifra/internal/logs/handle_show.go @@ -23,29 +23,25 @@ func (opts *LogsOptions) HandleShow() error { fetchData := func(modelChan chan types.Modeler[types.RawLog], errorChan chan error) { // var cnt int var err error - var txMap map[identifiers.ResolvedId]*types.SimpleTransaction - - if txMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { errorChan <- err cancel() } else { bar := logger.NewBar(logger.BarOptions{ Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), + Total: int64(len(appMap)), }) - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { a := &types.RawAppearance{ BlockNumber: uint32(app.BlockNumber), TransactionIndex: uint32(app.TransactionIndex), } if tx, err := opts.Conn.GetTransactionByAppearance(a, false /* needsTraces */); err != nil { - return fmt.Errorf("transaction at %s returned an error: %w", app.String(), err) + return fmt.Errorf("transaction at %s returned an error: %w", app.Orig(), err) } else if tx == nil || tx.Receipt == nil { - return fmt.Errorf("transaction at %s has no logs", app.String()) + return fmt.Errorf("transaction at %s has no logs", app.Orig()) } else { for index := range tx.Receipt.Logs { if opts.Articulate { @@ -61,21 +57,19 @@ func (opts *LogsOptions) HandleShow() error { } iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - iterCancel() if !testMode || nErrors == 0 { errorChan <- err - // Reporting more than one error causes tests to fail because they - // appear concurrently so sort differently nErrors++ } } bar.Finish(true) - items := make([]types.SimpleLog, 0, len(txMap)) - for _, tx := range txMap { + items := make([]types.SimpleLog, 0, len(appMap)) + for _, tx := range appMap { if tx.Receipt != nil { items = append(items, tx.Receipt.Logs...) } diff --git a/src/apps/chifra/internal/names/handle_clean.go b/src/apps/chifra/internal/names/handle_clean.go index d88d0fd7ab..11cc0a367d 100644 --- a/src/apps/chifra/internal/names/handle_clean.go +++ b/src/apps/chifra/internal/names/handle_clean.go @@ -105,10 +105,7 @@ func (opts *NamesOptions) cleanNames() (int, error) { } }() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - errorChan := make(chan error) - go utils.IterateOverMap(ctx, errorChan, allNames, func(address base.Address, name types.SimpleName) error { + iterFunc := func(address base.Address, name types.SimpleName) error { modified, err := cleanName(chain, &name) if err != nil { return wrapErrorWithAddr(&address, err) @@ -138,7 +135,12 @@ func (opts *NamesOptions) cleanNames() (int, error) { } } return nil - }) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + errorChan := make(chan error) + go utils.IterateOverMap(ctx, errorChan, allNames, iterFunc) // Block until we get an error from any of the iterations or the iteration finishes if stepErr := <-errorChan; stepErr != nil { diff --git a/src/apps/chifra/internal/names/handle_clean_integration_test.go b/src/apps/chifra/internal/names/handle_clean_integration_test.go index 434410300e..bd150d7587 100644 --- a/src/apps/chifra/internal/names/handle_clean_integration_test.go +++ b/src/apps/chifra/internal/names/handle_clean_integration_test.go @@ -261,21 +261,19 @@ func BenchmarkCleanConcurrent(b *testing.B) { b.Fatal(err) } - dataset := make(map[base.Address]types.SimpleName, benchmarkLimit) + appMap := make(map[base.Address]types.SimpleName, benchmarkLimit) count := 0 for addr, name := range allNames { if count == benchmarkLimit { break } count++ - dataset[addr] = name + appMap[addr] = name } b.StartTimer() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - errorChan := make(chan error) - go utils.IterateOverMap(ctx, errorChan, dataset, func(key base.Address, name types.SimpleName) error { + + iterFunc := func(key base.Address, name types.SimpleName) error { modified, err := cleanName("mainnet", &name) if err != nil { panic(err) @@ -294,8 +292,13 @@ func BenchmarkCleanConcurrent(b *testing.B) { panic(err) } return nil - }) - if err := <-errorChan; err != nil { + } + + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + if err := <-iterErrorChan; err != nil { b.Fatal(err) } } diff --git a/src/apps/chifra/internal/receipts/handle_show.go b/src/apps/chifra/internal/receipts/handle_show.go index 7a0ba7ca46..3f5912a7f9 100644 --- a/src/apps/chifra/internal/receipts/handle_show.go +++ b/src/apps/chifra/internal/receipts/handle_show.go @@ -21,27 +21,27 @@ func (opts *ReceiptsOptions) HandleShow() error { ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawReceipt], errorChan chan error) { - if txMap, _, err := identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { + // var cnt int + var err error + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { errorChan <- err cancel() } else { bar := logger.NewBar(logger.BarOptions{ Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), + Total: int64(len(appMap)), }) - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { a := &types.RawAppearance{ BlockNumber: uint32(app.BlockNumber), TransactionIndex: uint32(app.TransactionIndex), } if tx, err := opts.Conn.GetTransactionByAppearance(a, false /* needsTraces */); err != nil { - return fmt.Errorf("transaction at %s returned an error: %w", app.String(), err) + return fmt.Errorf("transaction at %s returned an error: %w", app.Orig(), err) } else if tx == nil || tx.Receipt == nil { - return fmt.Errorf("transaction at %s has no logs", app.String()) + return fmt.Errorf("transaction at %s has no logs", app.Orig()) } else { if opts.Articulate { if err = abiCache.ArticulateReceipt(tx.Receipt); err != nil { @@ -55,21 +55,19 @@ func (opts *ReceiptsOptions) HandleShow() error { } iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - iterCancel() if !testMode || nErrors == 0 { errorChan <- err - // Reporting more than one error causes tests to fail because they - // appear concurrently so sort differently nErrors++ } } bar.Finish(true) - items := make([]types.SimpleReceipt, 0, len(txMap)) - for _, tx := range txMap { + items := make([]types.SimpleReceipt, 0, len(appMap)) + for _, tx := range appMap { if tx.Receipt != nil { items = append(items, *tx.Receipt) } diff --git a/src/apps/chifra/internal/slurp/handle_appearances.go b/src/apps/chifra/internal/slurp/handle_appearances.go index beed34d22c..69dcd063e1 100644 --- a/src/apps/chifra/internal/slurp/handle_appearances.go +++ b/src/apps/chifra/internal/slurp/handle_appearances.go @@ -37,7 +37,7 @@ func (opts *SlurpOptions) HandleAppearances() error { }) for !done { - txs, nFetched, err := opts.Conn.GetESTransactionByAddress(addr, tt, &paginator) + txs, nFetched, err := opts.Conn.GetESTransactionByAddress(opts.Globals.Chain, addr, tt, &paginator) done = nFetched < paginator.PerPage totalFetched += nFetched if err != nil { diff --git a/src/apps/chifra/internal/slurp/handle_show.go b/src/apps/chifra/internal/slurp/handle_show.go index f2f07c7b0c..22bafa38e4 100644 --- a/src/apps/chifra/internal/slurp/handle_show.go +++ b/src/apps/chifra/internal/slurp/handle_show.go @@ -35,7 +35,7 @@ func (opts *SlurpOptions) HandleShow() error { Total: 250, // estimate since we have no idea how many there are }) for !done { - txs, nFetched, err := opts.Conn.GetESTransactionByAddress(addr, tt, &paginator) + txs, nFetched, err := opts.Conn.GetESTransactionByAddress(opts.Globals.Chain, addr, tt, &paginator) done = nFetched < paginator.PerPage totalFetched += nFetched if err != nil { diff --git a/src/apps/chifra/internal/state/handle_call.go b/src/apps/chifra/internal/state/handle_call.go index 5375fd6cc6..ae2b94c8a2 100644 --- a/src/apps/chifra/internal/state/handle_call.go +++ b/src/apps/chifra/internal/state/handle_call.go @@ -17,6 +17,9 @@ import ( func (opts *StateOptions) HandleCall() error { chain := opts.Globals.Chain + testMode := opts.Globals.TestMode + nErrors := 0 + artFunc := func(str string, function *types.SimpleFunction) error { return articulate.ArticulateFunction(function, "", str[2:]) } @@ -28,69 +31,64 @@ func (opts *StateOptions) HandleCall() error { ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawResult], errorChan chan error) { + // var cnt int var err error - var txMap map[identifiers.ResolvedId]*types.SimpleResult - if txMap, _, err = identifiers.AsMap[types.SimpleResult](chain, opts.BlockIds); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleResult + if appMap, _, err = identifiers.AsMap[types.SimpleResult](chain, opts.BlockIds); err != nil { errorChan <- err cancel() - } - - bar := logger.NewBar(logger.BarOptions{ - Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), - }) - - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() + } else { + bar := logger.NewBar(logger.BarOptions{ + Enabled: !opts.Globals.TestMode, + Total: int64(len(appMap)), + }) - nErrors := 0 - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleResult) error { - if contractCall, _, err := call.NewContractCall(opts.Conn, callAddress, opts.Call); err != nil { - wrapped := fmt.Errorf("the --call value provided (%s) was not found: %s", opts.Call, err) - errorChan <- wrapped - cancel() - } else { - contractCall.BlockNumber = app.BlockNumber - results, err := contractCall.Call(artFunc) - if err != nil { - errorChan <- err + iterFunc := func(app types.SimpleAppearance, value *types.SimpleResult) error { + bn := uint64(app.BlockNumber) + if contractCall, _, err := call.NewContractCall(opts.Conn, callAddress, opts.Call); err != nil { + wrapped := fmt.Errorf("the --call value provided (%s) was not found: %s", opts.Call, err) + errorChan <- wrapped cancel() } else { - bar.Tick() - *value = *results + contractCall.BlockNumber = bn + results, err := contractCall.Call(artFunc) + if err != nil { + errorChan <- err + cancel() + } else { + bar.Tick() + *value = *results + } } + return nil } - return nil - } - iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) - for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - // iterCancel() - if !opts.Globals.TestMode || nErrors == 0 { - errorChan <- err - // Reporting more than one error causes tests to fail because they - // appear concurrently so sort differently - nErrors++ + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } - } - bar.Finish(true) + bar.Finish(true) - items := make([]types.SimpleResult, 0, len(txMap)) - for _, v := range txMap { - v := v - items = append(items, *v) - } - sort.Slice(items, func(i, j int) bool { - return items[i].BlockNumber < items[j].BlockNumber - }) + items := make([]types.SimpleResult, 0, len(appMap)) + for _, v := range appMap { + v := v + items = append(items, *v) + } + sort.Slice(items, func(i, j int) bool { + return items[i].BlockNumber < items[j].BlockNumber + }) - for _, item := range items { - item := item - modelChan <- &item + for _, item := range items { + item := item + modelChan <- &item + } } - } extra := map[string]interface{}{ diff --git a/src/apps/chifra/internal/traces/handle_counts.go b/src/apps/chifra/internal/traces/handle_counts.go index 4125e5a6ad..a3a02043a2 100644 --- a/src/apps/chifra/internal/traces/handle_counts.go +++ b/src/apps/chifra/internal/traces/handle_counts.go @@ -23,77 +23,73 @@ func (opts *TracesOptions) HandleCounts() error { ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawModeler], errorChan chan error) { + // var cnt int var err error - var txMap map[identifiers.ResolvedId]*types.SimpleTransaction - if txMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { errorChan <- err cancel() - } - - bar := logger.NewBar(logger.BarOptions{ - Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), - }) - - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() + } else { + bar := logger.NewBar(logger.BarOptions{ + Enabled: !opts.Globals.TestMode, + Total: int64(len(appMap)), + }) - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { - a := &types.RawAppearance{ - BlockNumber: uint32(app.BlockNumber), - TransactionIndex: uint32(app.TransactionIndex), - } + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { + a := &types.RawAppearance{ + BlockNumber: uint32(app.BlockNumber), + TransactionIndex: uint32(app.TransactionIndex), + } - if tx, err := opts.Conn.GetTransactionByAppearance(a, true); err != nil { - errorChan <- fmt.Errorf("transaction at %s returned an error: %w", app.String(), err) - return nil + if tx, err := opts.Conn.GetTransactionByAppearance(a, true); err != nil { + errorChan <- fmt.Errorf("transaction at %s returned an error: %w", app.Orig(), err) + return nil - } else if tx == nil || len(tx.Traces) == 0 { - errorChan <- fmt.Errorf("transaction at %s has no traces", app.String()) - return nil + } else if tx == nil || len(tx.Traces) == 0 { + errorChan <- fmt.Errorf("transaction at %s has no traces", app.Orig()) + return nil - } else { - *value = *tx - bar.Tick() - return nil + } else { + *value = *tx + bar.Tick() + return nil + } } - } - iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) - for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - // iterCancel() - if !testMode || nErrors == 0 { - errorChan <- err - // Reporting more than one error causes tests to fail because they - // appear concurrently so sort differently - nErrors++ + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } - } - bar.Finish(true) + bar.Finish(true) - items := make([]*types.SimpleTransaction, 0, len(txMap)) - for _, tx := range txMap { - items = append(items, tx) - } - sort.Slice(items, func(i, j int) bool { - if items[i].BlockNumber == items[j].BlockNumber { - return items[i].TransactionIndex < items[j].TransactionIndex + items := make([]*types.SimpleTransaction, 0, len(appMap)) + for _, tx := range appMap { + items = append(items, tx) } - return items[i].BlockNumber < items[j].BlockNumber - }) - for _, item := range items { - item := item - if !item.BlockHash.IsZero() { - counter := simpleTraceCount{ - BlockNumber: uint64(item.BlockNumber), - TransactionIndex: uint64(item.TransactionIndex), - TransactionHash: item.Hash, - Timestamp: item.Timestamp, - TracesCnt: uint64(len(item.Traces)), + sort.Slice(items, func(i, j int) bool { + if items[i].BlockNumber == items[j].BlockNumber { + return items[i].TransactionIndex < items[j].TransactionIndex + } + return items[i].BlockNumber < items[j].BlockNumber + }) + for _, item := range items { + item := item + if !item.BlockHash.IsZero() { + counter := simpleTraceCount{ + BlockNumber: uint64(item.BlockNumber), + TransactionIndex: uint64(item.TransactionIndex), + TransactionHash: item.Hash, + Timestamp: item.Timestamp, + TracesCnt: uint64(len(item.Traces)), + } + modelChan <- &counter } - modelChan <- &counter } } } diff --git a/src/apps/chifra/internal/traces/handle_filter.go b/src/apps/chifra/internal/traces/handle_filter.go index 53ca3c1dbe..fd62162c1b 100644 --- a/src/apps/chifra/internal/traces/handle_filter.go +++ b/src/apps/chifra/internal/traces/handle_filter.go @@ -20,8 +20,9 @@ import ( func (opts *TracesOptions) HandleFilter() error { chain := opts.Globals.Chain - abiCache := articulate.NewAbiCache(opts.Conn, opts.Articulate) + testMode := opts.Globals.TestMode nErrors := 0 + abiCache := articulate.NewAbiCache(opts.Conn, opts.Articulate) traceFilter := types.SimpleTraceFilter{} _, br := traceFilter.ParseBangString(chain, opts.Filter) @@ -29,102 +30,99 @@ func (opts *TracesOptions) HandleFilter() error { if _, err := validate.ValidateIdentifiersWithBounds(chain, []string{fmt.Sprintf("%d-%d", br.First, br.Last+1)}, validate.ValidBlockIdWithRangeAndDate, 1, &ids); err != nil { return err } + opts.TransactionIds = ids ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawTrace], errorChan chan error) { + // var cnt int var err error - var txMap map[identifiers.ResolvedId]*types.SimpleTransaction - if txMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, ids); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { errorChan <- err cancel() - } - - bar := logger.NewBar(logger.BarOptions{ - Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), - }) - - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { - a := &types.RawAppearance{ - BlockNumber: uint32(app.BlockNumber), - } + } else { + bar := logger.NewBar(logger.BarOptions{ + Enabled: !opts.Globals.TestMode, + Total: int64(len(appMap)), + }) + + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { + a := &types.RawAppearance{ + BlockNumber: uint32(app.BlockNumber), + } - if block, err := opts.Conn.GetBlockBodyByNumber(uint64(a.BlockNumber)); err != nil { - errorChan <- fmt.Errorf("block at %s returned an error: %w", app.String(), err) - return nil - } else { - for _, tx := range block.Transactions { - tx := tx - if traces, err := opts.Conn.GetTracesByTransactionHash(tx.Hash.Hex(), &tx); err != nil { - errorChan <- fmt.Errorf("block at %s returned an error: %w", app.String(), err) - return nil - - } else if len(traces) == 0 { - errorChan <- fmt.Errorf("block at %s has no traces", app.String()) - return nil - - } else { - tr := make([]types.SimpleTrace, 0, len(traces)) - for index := range traces { - if opts.Articulate { - if err = abiCache.ArticulateTrace(&traces[index]); err != nil { - errorChan <- err // continue even with an error + if block, err := opts.Conn.GetBlockBodyByNumber(uint64(a.BlockNumber)); err != nil { + errorChan <- fmt.Errorf("block at %s returned an error: %w", app.Orig(), err) + return nil + } else { + for _, tx := range block.Transactions { + tx := tx + if traces, err := opts.Conn.GetTracesByTransactionHash(tx.Hash.Hex(), &tx); err != nil { + errorChan <- fmt.Errorf("block at %s returned an error: %w", app.Orig(), err) + return nil + + } else if len(traces) == 0 { + errorChan <- fmt.Errorf("block at %s has no traces", app.Orig()) + return nil + + } else { + tr := make([]types.SimpleTrace, 0, len(traces)) + for index := range traces { + if opts.Articulate { + if err = abiCache.ArticulateTrace(&traces[index]); err != nil { + errorChan <- err // continue even with an error + } } + traces[index].TraceIndex = uint64(index) + tr = append(tr, traces[index]) } - traces[index].TraceIndex = uint64(index) - tr = append(tr, traces[index]) + value.Traces = append(value.Traces, tr...) } - value.Traces = append(value.Traces, tr...) } + bar.Tick() + return nil } - bar.Tick() - return nil } - } - iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) - for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - // iterCancel() - if !opts.Globals.TestMode || nErrors == 0 { - errorChan <- err - // Reporting more than one error causes tests to fail because they - // appear concurrently so sort differently - nErrors++ + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } - } - bar.Finish(true) + bar.Finish(true) - items := make([]types.SimpleTrace, 0, len(txMap)) - for _, tx := range txMap { - tx := tx - items = append(items, tx.Traces...) - } - sort.Slice(items, func(i, j int) bool { - if items[i].BlockNumber == items[j].BlockNumber { - if items[i].TransactionIndex == items[j].TransactionIndex { - return items[i].TraceIndex < items[j].TraceIndex - } - return items[i].TransactionIndex < items[j].TransactionIndex + items := make([]types.SimpleTrace, 0, len(appMap)) + for _, tx := range appMap { + tx := tx + items = append(items, tx.Traces...) } - return items[i].BlockNumber < items[j].BlockNumber - }) - - nPassed := uint64(0) - nShown := uint64(0) - for nTested, item := range items { - item := item - ok, _ := traceFilter.PassesBasic(&item, uint64(nTested), nPassed) - if ok { - if (traceFilter.After == 0 || nPassed >= traceFilter.After) && (traceFilter.Count == 0 || uint64(nShown) < traceFilter.Count) { - modelChan <- &item - nShown++ + sort.Slice(items, func(i, j int) bool { + if items[i].BlockNumber == items[j].BlockNumber { + if items[i].TransactionIndex == items[j].TransactionIndex { + return items[i].TraceIndex < items[j].TraceIndex + } + return items[i].TransactionIndex < items[j].TransactionIndex + } + return items[i].BlockNumber < items[j].BlockNumber + }) + + nPassed := uint64(0) + nShown := uint64(0) + for nTested, item := range items { + item := item + ok, _ := traceFilter.PassesBasic(&item, uint64(nTested), nPassed) + if ok { + if (traceFilter.After == 0 || nPassed >= traceFilter.After) && (traceFilter.Count == 0 || uint64(nShown) < traceFilter.Count) { + modelChan <- &item + nShown++ + } + nPassed++ } - nPassed++ } } } diff --git a/src/apps/chifra/internal/traces/handle_show.go b/src/apps/chifra/internal/traces/handle_show.go index 3bcd4aebdc..3eab990d87 100644 --- a/src/apps/chifra/internal/traces/handle_show.go +++ b/src/apps/chifra/internal/traces/handle_show.go @@ -25,81 +25,77 @@ func (opts *TracesOptions) HandleShow() error { ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawTrace], errorChan chan error) { + // var cnt int var err error - var txMap map[identifiers.ResolvedId]*types.SimpleTransaction - if txMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { errorChan <- err cancel() - } - - bar := logger.NewBar(logger.BarOptions{ - Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), - }) - - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { - a := &types.RawAppearance{ - BlockNumber: uint32(app.BlockNumber), - TransactionIndex: uint32(app.TransactionIndex), - } + } else { + bar := logger.NewBar(logger.BarOptions{ + Enabled: !opts.Globals.TestMode, + Total: int64(len(appMap)), + }) + + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { + a := &types.RawAppearance{ + BlockNumber: uint32(app.BlockNumber), + TransactionIndex: uint32(app.TransactionIndex), + } - if tx, err := opts.Conn.GetTransactionByAppearance(a, true); err != nil { - errorChan <- fmt.Errorf("transaction at %s returned an error: %w", app.String(), err) - return nil + if tx, err := opts.Conn.GetTransactionByAppearance(a, true); err != nil { + errorChan <- fmt.Errorf("transaction at %s returned an error: %w", app.Orig(), err) + return nil - } else if tx == nil || len(tx.Traces) == 0 { - errorChan <- fmt.Errorf("transaction at %s has no traces", app.String()) - return nil + } else if tx == nil || len(tx.Traces) == 0 { + errorChan <- fmt.Errorf("transaction at %s has no traces", app.Orig()) + return nil - } else { - for index := range tx.Traces { - if opts.Articulate { - if err = abiCache.ArticulateTrace(&tx.Traces[index]); err != nil { - errorChan <- err // continue even with an error + } else { + for index := range tx.Traces { + if opts.Articulate { + if err = abiCache.ArticulateTrace(&tx.Traces[index]); err != nil { + errorChan <- err // continue even with an error + } } } + *value = *tx + bar.Tick() + return nil } - *value = *tx - bar.Tick() - return nil } - } - iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) - for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - // iterCancel() - if !testMode || nErrors == 0 { - errorChan <- err - // Reporting more than one error causes tests to fail because they - // appear concurrently so sort differently - nErrors++ + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } - } - bar.Finish(true) + bar.Finish(true) - items := make([]types.SimpleTrace, 0, len(txMap)) - for _, receipt := range txMap { - items = append(items, receipt.Traces...) - } - sort.Slice(items, func(i, j int) bool { - if items[i].BlockNumber == items[j].BlockNumber { - if items[i].TransactionIndex == items[j].TransactionIndex { - return items[i].GetSortString() < items[j].GetSortString() - } - return items[i].TransactionIndex < items[j].TransactionIndex + items := make([]types.SimpleTrace, 0, len(appMap)) + for _, receipt := range appMap { + items = append(items, receipt.Traces...) } - return items[i].BlockNumber < items[j].BlockNumber - }) + sort.Slice(items, func(i, j int) bool { + if items[i].BlockNumber == items[j].BlockNumber { + if items[i].TransactionIndex == items[j].TransactionIndex { + return items[i].GetSortString() < items[j].GetSortString() + } + return items[i].TransactionIndex < items[j].TransactionIndex + } + return items[i].BlockNumber < items[j].BlockNumber + }) - for _, item := range items { - item := item - if !item.BlockHash.IsZero() { - modelChan <- &item + for _, item := range items { + item := item + if !item.BlockHash.IsZero() { + modelChan <- &item + } } } } diff --git a/src/apps/chifra/internal/transactions/handle_accountfor.go b/src/apps/chifra/internal/transactions/handle_accountfor.go index a07f78d3f9..db4cca3375 100644 --- a/src/apps/chifra/internal/transactions/handle_accountfor.go +++ b/src/apps/chifra/internal/transactions/handle_accountfor.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/filter" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/ledger" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" @@ -17,6 +18,13 @@ func (opts *TransactionsOptions) HandleAccounting() (err error) { testMode := opts.Globals.TestMode ether := opts.Globals.Ether noZero := false // opts.Globals.NoZero + filter := filter.NewFilter( + false, + false, + []string{}, + base.BlockRange{First: 0, Last: utils.NOPOS}, + base.RecordRange{First: 0, Last: utils.NOPOS}, + ) ledgers := ledger.NewLedger( opts.Conn, @@ -41,7 +49,7 @@ func (opts *TransactionsOptions) HandleAccounting() (err error) { } for _, app := range txIds { - if statements, err := ledgers.GetStatementsFromAppearance(opts.Conn, &app); err != nil { + if statements, err := ledgers.GetStatementsFromAppearance(opts.Conn, filter, &app); err != nil { errorChan <- err } else { for _, statement := range statements { diff --git a/src/apps/chifra/internal/transactions/handle_logs.go b/src/apps/chifra/internal/transactions/handle_logs.go index 4749d2acc7..ac19cec7fe 100644 --- a/src/apps/chifra/internal/transactions/handle_logs.go +++ b/src/apps/chifra/internal/transactions/handle_logs.go @@ -39,73 +39,70 @@ func (opts *TransactionsOptions) HandleLogs() error { ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawLog], errorChan chan error) { - + // var cnt int var err error - var txMap map[identifiers.ResolvedId]*types.SimpleTransaction - - if txMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { errorChan <- err cancel() - } + } else { + bar := logger.NewBar(logger.BarOptions{ + Enabled: !opts.Globals.TestMode, + Total: int64(len(appMap)), + }) - bar := logger.NewBar(logger.BarOptions{ - Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), - }) - - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { - a := &types.RawAppearance{ - BlockNumber: uint32(app.BlockNumber), - TransactionIndex: uint32(app.TransactionIndex), - } - if tx, err := opts.Conn.GetTransactionByAppearance(a, opts.Traces /* needsTraces */); err != nil { - return fmt.Errorf("transaction at %s returned an error: %w", app.String(), err) - } else if tx == nil { - return fmt.Errorf("transaction at %s has no logs", app.String()) - } else { - if opts.Articulate && tx.ArticulatedTx == nil { - if err = abiCache.ArticulateTransaction(tx); err != nil { - errorChan <- err // continue even with an error + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { + a := &types.RawAppearance{ + BlockNumber: uint32(app.BlockNumber), + TransactionIndex: uint32(app.TransactionIndex), + } + if tx, err := opts.Conn.GetTransactionByAppearance(a, opts.Traces /* needsTraces */); err != nil { + return fmt.Errorf("transaction at %s returned an error: %w", app.Orig(), err) + } else if tx == nil { + return fmt.Errorf("transaction at %s has no logs", app.Orig()) + } else { + if opts.Articulate && tx.ArticulatedTx == nil { + if err = abiCache.ArticulateTransaction(tx); err != nil { + errorChan <- err // continue even with an error + } } + *value = *tx + bar.Tick() + return nil } - *value = *tx - bar.Tick() - return nil } - } - iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) - for err := range iterErrorChan { - iterCancel() - if !testMode || nErrors == 0 { - errorChan <- err - nErrors++ + iterErrorChan := make(chan error) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) + for err := range iterErrorChan { + if !testMode || nErrors == 0 { + errorChan <- err + nErrors++ + } } - } - bar.Finish(true) + bar.Finish(true) - items := make([]types.SimpleTransaction, 0, len(txMap)) - for _, tx := range txMap { - items = append(items, *tx) - } - sort.Slice(items, func(i, j int) bool { - if items[i].BlockNumber == items[j].BlockNumber { - return items[i].TransactionIndex < items[j].TransactionIndex + items := make([]types.SimpleTransaction, 0, len(appMap)) + for _, tx := range appMap { + items = append(items, *tx) } - return items[i].BlockNumber < items[j].BlockNumber - }) + sort.Slice(items, func(i, j int) bool { + if items[i].BlockNumber == items[j].BlockNumber { + return items[i].TransactionIndex < items[j].TransactionIndex + } + return items[i].BlockNumber < items[j].BlockNumber + }) - for _, item := range items { - item := item - if !item.BlockHash.IsZero() { - for _, log := range item.Receipt.Logs { - log := log - if logFilter.PassesFilter(&log) { - modelChan <- &log + for _, item := range items { + item := item + if !item.BlockHash.IsZero() { + for _, log := range item.Receipt.Logs { + log := log + if logFilter.PassesFilter(&log) { + modelChan <- &log + } } } } diff --git a/src/apps/chifra/internal/transactions/handle_show.go b/src/apps/chifra/internal/transactions/handle_show.go index 42cb0c655a..17daa17dbf 100644 --- a/src/apps/chifra/internal/transactions/handle_show.go +++ b/src/apps/chifra/internal/transactions/handle_show.go @@ -21,27 +21,27 @@ func (opts *TransactionsOptions) HandleShow() (err error) { ctx, cancel := context.WithCancel(context.Background()) fetchData := func(modelChan chan types.Modeler[types.RawTransaction], errorChan chan error) { - if txMap, _, err := identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { + // var cnt int + var err error + var appMap map[types.SimpleAppearance]*types.SimpleTransaction + if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.TransactionIds); err != nil { errorChan <- err cancel() } else { bar := logger.NewBar(logger.BarOptions{ Enabled: !opts.Globals.TestMode, - Total: int64(len(txMap)), + Total: int64(len(appMap)), }) - iterCtx, iterCancel := context.WithCancel(context.Background()) - defer iterCancel() - - iterFunc := func(app identifiers.ResolvedId, value *types.SimpleTransaction) error { + iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error { a := &types.RawAppearance{ BlockNumber: uint32(app.BlockNumber), TransactionIndex: uint32(app.TransactionIndex), } if tx, err := opts.Conn.GetTransactionByAppearance(a, opts.Traces /* needsTraces */); err != nil { - return fmt.Errorf("transaction at %s returned an error: %w", app.String(), err) + return fmt.Errorf("transaction at %s returned an error: %w", app.Orig(), err) } else if tx == nil { - return fmt.Errorf("transaction at %s has no logs", app.String()) + return fmt.Errorf("transaction at %s has no logs", app.Orig()) } else { if opts.Articulate && tx.ArticulatedTx == nil { if err = abiCache.ArticulateTransaction(tx); err != nil { @@ -55,21 +55,19 @@ func (opts *TransactionsOptions) HandleShow() (err error) { } iterErrorChan := make(chan error) - go utils.IterateOverMap(iterCtx, iterErrorChan, txMap, iterFunc) + iterCtx, iterCancel := context.WithCancel(context.Background()) + defer iterCancel() + go utils.IterateOverMap(iterCtx, iterErrorChan, appMap, iterFunc) for err := range iterErrorChan { - // TODO: I don't really want to quit looping here. Just report the error and keep going. - iterCancel() if !testMode || nErrors == 0 { errorChan <- err - // Reporting more than one error causes tests to fail because they - // appear concurrently so sort differently nErrors++ } } bar.Finish(true) - items := make([]types.SimpleTransaction, 0, len(txMap)) - for _, tx := range txMap { + items := make([]types.SimpleTransaction, 0, len(appMap)) + for _, tx := range appMap { items = append(items, *tx) } sort.Slice(items, func(i, j int) bool { diff --git a/src/apps/chifra/pkg/filter/filter.go b/src/apps/chifra/pkg/filter/filter.go index 6ccb2cf9e3..948471dc07 100644 --- a/src/apps/chifra/pkg/filter/filter.go +++ b/src/apps/chifra/pkg/filter/filter.go @@ -106,3 +106,19 @@ func (f *AppearanceFilter) ApplyTxFilters(tx *types.SimpleTransaction) (passed, // fmt.Println("len:", len(f.fourBytes), "matchesFourbyte", matchesFourbyte, "matchesReverted", matchesReverted) return matchesFourbyte && matchesReverted, false } + +func (f *AppearanceFilter) ApplyLogFilter(log *types.SimpleLog, addrArray []base.Address) bool { + haystack := make([]byte, 66*len(log.Topics)+len(log.Data)) + haystack = append(haystack, log.Address.Hex()[2:]...) + for _, topic := range log.Topics { + haystack = append(haystack, topic.Hex()[2:]...) + } + haystack = append(haystack, log.Data[2:]...) + + for _, addr := range addrArray { + if strings.Contains(string(haystack), addr.Hex()[2:]) { + return true + } + } + return false +} diff --git a/src/apps/chifra/pkg/identifiers/app_map.go b/src/apps/chifra/pkg/identifiers/app_map.go index fce3d7f8cb..25d1aaa83c 100644 --- a/src/apps/chifra/pkg/identifiers/app_map.go +++ b/src/apps/chifra/pkg/identifiers/app_map.go @@ -6,16 +6,6 @@ import ( "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" ) -type ResolvedId struct { - BlockNumber uint64 - TransactionIndex uint64 - Original string -} - -func (r *ResolvedId) String() string { - return r.Original -} - type mappedType interface { types.SimpleTransaction | types.SimpleBlock[string] | @@ -28,27 +18,27 @@ type mappedType interface { // AsMap takes command line identifiers for blocks or transactions and returns a map of appearances to allocated // pointers to SimpleTransactions or SimpleBlock[string]. The map is keyed by the appearance and the value is // the allocated pointer. We don't know what type of identifier we have until we try to resolve it. -func AsMap[T mappedType](chain string, ids []Identifier) (map[ResolvedId]*T, int, error) { - ret := make(map[ResolvedId]*T) +func AsMap[T mappedType](chain string, ids []Identifier) (map[types.SimpleAppearance]*T, int, error) { + ret := make(map[types.SimpleAppearance]*T) for index, rng := range ids { if rawIds, err := rng.ResolveTxs(chain); err != nil { if blockIds, err := rng.ResolveBlocks(chain); err != nil { return nil, 0, err } else { for _, raw := range blockIds { - s := ResolvedId{ - BlockNumber: uint64(raw), - Original: strings.Replace(ids[index].Orig, "-", ".", -1), + s := types.SimpleAppearance{ + BlockNumber: uint32(raw), + Reason: strings.Replace(ids[index].Orig, "-", ".", -1), } ret[s] = new(T) } } } else { for _, raw := range rawIds { - s := ResolvedId{ - BlockNumber: uint64(raw.BlockNumber), - TransactionIndex: uint64(raw.TransactionIndex), - Original: strings.Replace(ids[index].Orig, "-", ".", -1), + s := types.SimpleAppearance{ + BlockNumber: uint32(raw.BlockNumber), + TransactionIndex: uint32(raw.TransactionIndex), + Reason: strings.Replace(ids[index].Orig, "-", ".", -1), } ret[s] = new(T) } diff --git a/src/apps/chifra/pkg/ledger/ledger.go b/src/apps/chifra/pkg/ledger/ledger.go index 7bc0ef6d10..ff503390b5 100644 --- a/src/apps/chifra/pkg/ledger/ledger.go +++ b/src/apps/chifra/pkg/ledger/ledger.go @@ -23,7 +23,7 @@ type Ledger struct { AsEther bool NoZero bool UseTraces bool - AssetFilter *[]base.Address + AssetFilter []base.Address Tx *types.SimpleTransaction Conn *rpc.Connection } @@ -41,12 +41,14 @@ func NewLedger(conn *rpc.Connection, acctFor base.Address, fb, lb base.Blknum, a NoZero: noZero, UseTraces: useTraces, } + if assetFilters != nil { - assets := make([]base.Address, 0, len(*assetFilters)) - for _, addr := range *assetFilters { - assets = append(assets, base.HexToAddress(addr)) + l.AssetFilter = make([]base.Address, len(*assetFilters)) + for i, addr := range *assetFilters { + l.AssetFilter[i] = base.HexToAddress(addr) } - l.AssetFilter = &assets + } else { + l.AssetFilter = []base.Address{} } parts := names.Custom | names.Prefund | names.Regular @@ -57,11 +59,11 @@ func NewLedger(conn *rpc.Connection, acctFor base.Address, fb, lb base.Blknum, a // assetOfInterest returns true if the asset filter is empty or the asset matches func (l *Ledger) assetOfInterest(needle base.Address) bool { - if l.AssetFilter == nil || len(*l.AssetFilter) == 0 { + if len(l.AssetFilter) == 0 { return true } - for _, asset := range *l.AssetFilter { + for _, asset := range l.AssetFilter { if asset.Hex() == needle.Hex() { return true } diff --git a/src/apps/chifra/pkg/ledger/stmnt_from_app.go b/src/apps/chifra/pkg/ledger/stmnt_from_app.go index 0db83a566d..bea0715e8c 100644 --- a/src/apps/chifra/pkg/ledger/stmnt_from_app.go +++ b/src/apps/chifra/pkg/ledger/stmnt_from_app.go @@ -1,19 +1,24 @@ package ledger import ( + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/filter" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" ) // GetStatementsFromAppearance visits an appearance and returns a list of (hopefully) reconciled statements. -func (l *Ledger) GetStatementsFromAppearance(conn *rpc.Connection, app *types.RawAppearance) (statements []types.SimpleStatement, err error) { +func (l *Ledger) GetStatementsFromAppearance( + conn *rpc.Connection, + filter *filter.AppearanceFilter, + app *types.RawAppearance, +) (statements []types.SimpleStatement, err error) { var tx *types.SimpleTransaction if tx, err = conn.GetTransactionByAppearance(app, false); err != nil { return []types.SimpleStatement{}, err } else { l.Tx = tx // we need this below - if stmts := l.GetStatementsFromTransaction(conn, tx); len(stmts) > 0 { + if stmts := l.GetStatementsFromTransaction(conn, filter, tx); len(stmts) > 0 { for _, statement := range stmts { statement := statement statements = append(statements, *statement) diff --git a/src/apps/chifra/pkg/ledger/stmnt_from_tx.go b/src/apps/chifra/pkg/ledger/stmnt_from_tx.go index c21ac13e32..15ce293b75 100644 --- a/src/apps/chifra/pkg/ledger/stmnt_from_tx.go +++ b/src/apps/chifra/pkg/ledger/stmnt_from_tx.go @@ -4,13 +4,18 @@ import ( "math/big" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/filter" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" ) // GetStatementsFromTransaction returns a statement from a given transaction -func (l *Ledger) GetStatementsFromTransaction(conn *rpc.Connection, trans *types.SimpleTransaction) (statements []*types.SimpleStatement) { +func (l *Ledger) GetStatementsFromTransaction( + conn *rpc.Connection, + filter *filter.AppearanceFilter, + trans *types.SimpleTransaction, +) (statements []*types.SimpleStatement) { if false && conn.StoreReadable() { statementGroup := &types.SimpleStatementGroup{ Address: l.AccountFor, @@ -120,7 +125,8 @@ func (l *Ledger) GetStatementsFromTransaction(conn *rpc.Connection, trans *types if trans.Receipt != nil { for _, log := range trans.Receipt.Logs { log := log - if l.assetOfInterest(log.Address) && log.ContainsAddress(l.AccountFor) { + addrArray := []base.Address{l.AccountFor} + if filter.ApplyLogFilter(&log, addrArray) && l.assetOfInterest(log.Address) { if statement, err := l.getStatementFromLog(conn, &log); statement != nil { if statement.Sender == l.AccountFor || statement.Recipient == l.AccountFor { add := !l.NoZero || statement.MoneyMoved() diff --git a/src/apps/chifra/pkg/monitor/monitor_read.go b/src/apps/chifra/pkg/monitor/monitor_read.go index 69eacb0f23..33f6b93773 100644 --- a/src/apps/chifra/pkg/monitor/monitor_read.go +++ b/src/apps/chifra/pkg/monitor/monitor_read.go @@ -63,8 +63,8 @@ func (mon *Monitor) ReadAppearanceAt(idx int64, app *index.AppearanceRecord) (er return } -// ReadAppearancesToMap reads all appearances from the monitor and returns a map of the appearances to the given type. -func ReadAppearancesToMap[T any](mon *Monitor, filter *filter.AppearanceFilter) (theMap map[types.SimpleAppearance]*T, cnt int, err error) { +// AsMap reads all appearances from the monitor and returns a map of the appearances to the given type. +func AsMap[T any](mon *Monitor, filter *filter.AppearanceFilter) (theMap map[types.SimpleAppearance]*T, cnt int, err error) { if apps, cnt, err := mon.ReadAndFilterAppearances(filter); err != nil { return nil, 0, err } else if cnt == 0 { diff --git a/src/apps/chifra/pkg/rpc/etherscan.go b/src/apps/chifra/pkg/rpc/etherscan.go index 3910dbdecb..fe94b0651c 100644 --- a/src/apps/chifra/pkg/rpc/etherscan.go +++ b/src/apps/chifra/pkg/rpc/etherscan.go @@ -22,8 +22,8 @@ type Paginator struct { PerPage int } -func (conn *Connection) GetESTransactionByAddress(addr, requestType string, paginator *Paginator) ([]types.SimpleSlurp, int, error) { - url, err := getEtherscanUrl(addr, requestType, paginator) +func (conn *Connection) GetESTransactionByAddress(chain, addr, requestType string, paginator *Paginator) ([]types.SimpleSlurp, int, error) { + url, err := getEtherscanUrl(chain, addr, requestType, paginator) if err != nil { return []types.SimpleSlurp{}, 0, err } @@ -66,7 +66,7 @@ func (conn *Connection) GetESTransactionByAddress(addr, requestType string, pagi } // func (conn *Connection) getESTransactionByHash(txHash base.Hash) (types.SimpleSlurp, error) { -// url, err := getEtherscanUrl(txHash.Hex(), "byHash", &Paginator{Page: 1, PerPage: 10}) +// url, err := getEtherscanUrl(chain, txHash.Hex(), "byHash", &Paginator{Page: 1, PerPage: 10}) // if err != nil { // return types.SimpleSlurp{}, err // } @@ -166,7 +166,7 @@ func (conn *Connection) responseToTransactions(addr, requestType string, rawTxs return ret, len(ret), nil } -func getEtherscanUrl(value string, requestType string, paginator *Paginator) (string, error) { +func getEtherscanUrl(chain, value string, requestType string, paginator *Paginator) (string, error) { var actions = map[string]string{ "ext": "txlist", "int": "txlistinternal", diff --git a/src/apps/chifra/pkg/types/types_appearance.go b/src/apps/chifra/pkg/types/types_appearance.go index 3374a9e5b9..ab3ac8d571 100644 --- a/src/apps/chifra/pkg/types/types_appearance.go +++ b/src/apps/chifra/pkg/types/types_appearance.go @@ -171,4 +171,8 @@ func (s *SimpleAppearance) Date() string { return utils.FormattedDate(s.Timestamp) } +func (s *SimpleAppearance) Orig() string { + return s.Reason // when converted from an Identifier, this is the original string +} + // EXISTING_CODE diff --git a/src/apps/chifra/pkg/types/types_log.go b/src/apps/chifra/pkg/types/types_log.go index 10bc1e83d1..f7ba318cfd 100644 --- a/src/apps/chifra/pkg/types/types_log.go +++ b/src/apps/chifra/pkg/types/types_log.go @@ -327,31 +327,6 @@ func (s *SimpleLog) FinishUnmarshal() { // EXISTING_CODE // -func (s *SimpleLog) getHaystack() string { - haystack := make([]byte, 66*len(s.Topics)+len(s.Data)) - haystack = append(haystack, s.Address.Hex()[2:]...) - for _, topic := range s.Topics { - haystack = append(haystack, topic.Hex()[2:]...) - } - haystack = append(haystack, s.Data[2:]...) - return string(haystack) -} - -func (s *SimpleLog) ContainsAny(addrArray []base.Address) bool { - haystack := s.getHaystack() - for _, addr := range addrArray { - if strings.Contains(string(haystack), addr.Hex()[2:]) { - return true - } - } - return false -} - -func (s *SimpleLog) ContainsAddress(addr base.Address) bool { - haystack := s.getHaystack() - return strings.Contains(string(haystack), addr.Hex()[2:]) -} - func (r *RawLog) RawToSimple(vals map[string]any) (SimpleLog, error) { hash, ok := vals["hash"].(base.Hash) if !ok { diff --git a/src/apps/chifra/pkg/version/version_strings.go b/src/apps/chifra/pkg/version/version_strings.go index ad4b6e9cd1..1f5993f968 100644 --- a/src/apps/chifra/pkg/version/version_strings.go +++ b/src/apps/chifra/pkg/version/version_strings.go @@ -7,4 +7,4 @@ package version -const LibraryVersion = "GHC-TrueBlocks//2.1.0-release" +const LibraryVersion = "GHC-TrueBlocks//2.2.0-release" diff --git a/src/dev_tools/makeClass/handle_datamodel.cpp b/src/dev_tools/makeClass/handle_datamodel.cpp index 6d81f0d998..7e7b11a93e 100644 --- a/src/dev_tools/makeClass/handle_datamodel.cpp +++ b/src/dev_tools/makeClass/handle_datamodel.cpp @@ -372,6 +372,9 @@ const char* STR_YAML_TAIL = " type: string\n" " string:\n" " type: string\n" + " uint64:\n" + " type: number\n" + " format: uint64\n" " topic:\n" " type: string\n" " format: bytes\n" diff --git a/src/dev_tools/utillib/version.cpp b/src/dev_tools/utillib/version.cpp index 7cbd714a63..319be7b1aa 100644 --- a/src/dev_tools/utillib/version.cpp +++ b/src/dev_tools/utillib/version.cpp @@ -18,7 +18,7 @@ namespace qblocks { // Run make generate in order for this to take effect // search: change-version #define MAJOR 2 -#define MINOR 1 +#define MINOR 2 #define BUILD 0 // Run make generate in order for this to take effect diff --git a/src/examples/findFirst/findFirst.go b/src/examples/findFirst/findFirst.go index 1e853f0c30..67f880843c 100644 --- a/src/examples/findFirst/findFirst.go +++ b/src/examples/findFirst/findFirst.go @@ -70,24 +70,21 @@ func fastWay(conn *rpc.Connection) { fmt.Println(err) } - var theMap map[identifiers.ResolvedId]*types.SimpleBlock[string] var err error - - if theMap, _, err = identifiers.AsMap[types.SimpleBlock[string]](chain, BlockIds); err != nil { + var appMap map[types.SimpleAppearance]*types.SimpleBlock[string] + if appMap, _, err = identifiers.AsMap[types.SimpleBlock[string]](chain, BlockIds); err != nil { fmt.Println(err) } else { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - var firstBlock types.SimpleBlock[string] firstBlock.BlockNumber = utils.NOPOS - iterateFunc := func(key identifiers.ResolvedId, value *types.SimpleBlock[string]) error { + iterateFunc := func(key types.SimpleAppearance, value *types.SimpleBlock[string]) error { + bn := uint64(key.BlockNumber) if theBlock, err := conn.GetBlockHeaderByNumber(base.Blknum(key.BlockNumber)); err != nil { return err } else { if len(theBlock.Transactions) > 0 { // fmt.Println("Found", theBlock.Hash.String(), ":", len(theBlock.Transactions), "transactions") - if theBlock.BlockNumber > 0 && key.BlockNumber < firstBlock.BlockNumber { + if theBlock.BlockNumber > 0 && bn < firstBlock.BlockNumber { firstBlock = theBlock fmt.Println(" Set", firstBlock.BlockNumber, firstBlock.Hash.String(), ":", len(firstBlock.Transactions), "transactions ") } @@ -98,7 +95,9 @@ func fastWay(conn *rpc.Connection) { } errorChan := make(chan error) - go utils.IterateOverMap(ctx, errorChan, theMap, iterateFunc) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go utils.IterateOverMap(ctx, errorChan, appMap, iterateFunc) for err := range errorChan { fmt.Println(err) } diff --git a/test/gold/tools/ethNames/ethNames_show_version.txt b/test/gold/tools/ethNames/ethNames_show_version.txt index 0b6c7a84cf..4da802deb4 100644 --- a/test/gold/tools/ethNames/ethNames_show_version.txt +++ b/test/gold/tools/ethNames/ethNames_show_version.txt @@ -1,2 +1,2 @@ chifra names --version -names version GHC-TrueBlocks//2.1.0-release +names version GHC-TrueBlocks//2.2.0-release