Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Version 2.5.0 - Much better concurrent code #3434

Merged
merged 28 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ac25430
First attempt at arrayOfMaps approach
tjayrush Nov 29, 2023
217abc3
Merge branch 'develop' into fix/concurrency-1
tjayrush Nov 29, 2023
e5d8223
Changes interface to rpc.GetTrans to use SimpleAppearance
tjayrush Dec 1, 2023
0e6c9a4
Adds some test cases and cleans a bit
tjayrush Dec 1, 2023
28793c1
Starting to move to new sliceOfMaps method
tjayrush Dec 1, 2023
d6985ed
sliceOfMaps method for export and chifra logs
tjayrush Dec 1, 2023
a927a33
sliceOfMaps method for chifra blocks
tjayrush Dec 1, 2023
5fe7527
Fixes tests
tjayrush Dec 1, 2023
03c21e8
sliceOfMaps method for chifra receipts, traces, and state
tjayrush Dec 1, 2023
4864fe5
sliceOfMaps method for chifra traces
tjayrush Dec 1, 2023
2463023
sliceOfMaps method for all but chifra export
tjayrush Dec 1, 2023
80e72dc
sliceOfMaps method for chifra export --withdrawals
tjayrush Dec 1, 2023
045b442
Cleaning up a bit
tjayrush Dec 1, 2023
2c0a3c6
sliceOfMaps method for chifra export --logs and --traces
tjayrush Dec 1, 2023
dfb2fc8
sliceOfMaps method for chifra export --receipts
tjayrush Dec 1, 2023
d98d412
sliceOfMaps method for chifra export --statements
tjayrush Dec 1, 2023
03f3893
sliceOfMaps method cleanup
tjayrush Dec 1, 2023
8a41328
Fixes tests
tjayrush Dec 1, 2023
2e51b8f
Consistancy
tjayrush Dec 1, 2023
7c38d86
Bump
tjayrush Dec 1, 2023
4118735
Make block queries a tiny bit more consistent
tjayrush Dec 1, 2023
e8d0394
Make transaction queries a tiny bit more consistent
tjayrush Dec 1, 2023
da21192
Cleaning
tjayrush Dec 1, 2023
6ec7d1d
Improves error handling in iterFuncs
tjayrush Dec 1, 2023
0dedd91
Fixing tests
tjayrush Dec 2, 2023
ea5cb62
Merge pull request #3429 from TrueBlocks/fix/concurrency-1
tjayrush Dec 2, 2023
4f06316
Bumps version to v2.5.0-release
tjayrush Dec 2, 2023
30e21a3
Merge pull request #3433 from TrueBlocks/version/bump2.5.0
tjayrush Dec 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ info:
license:
name: GPL 3.0
url: http://www.gnu.org/licenses/
version: 2.2.0-release
version: 2.5.0-release
description: >

A REST layer over the TrueBlocks application. With `chifra daemon`, you can
Expand Down
12 changes: 11 additions & 1 deletion src/apps/chifra/internal/blocks/handle_decache.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (opts *BlocksOptions) HandleDecache() error {

ctx := context.Background()
fetchData := func(modelChan chan types.Modeler[types.RawModeler], errorChan chan error) {
if msg, err := decache.Decache(opts.Conn, itemsToRemove, silent, walk.Cache_Blocks); err != nil {
if msg, err := decache.Decache(opts.Conn, itemsToRemove, silent, opts.getCacheType()); err != nil {
errorChan <- err
} else {
s := types.SimpleMessage{
Expand All @@ -36,3 +36,13 @@ func (opts *BlocksOptions) HandleDecache() error {
opts.Globals.NoHeader = true
return output.StreamMany(ctx, fetchData, opts.Globals.OutputOpts())
}

func (opts *BlocksOptions) getCacheType() walk.CacheType {
cT := walk.Cache_Blocks
if opts.Logs {
cT = walk.Cache_Logs
} else if opts.Traces {
cT = walk.Cache_Traces
}
return cT
}
103 changes: 53 additions & 50 deletions src/apps/chifra/internal/blocks/handle_hashes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ package blocksPkg

import (
"context"
"errors"
"fmt"
"sort"

"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/identifiers"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/utils"
"github.com/ethereum/go-ethereum"
)

func (opts *BlocksOptions) HandleHashes() error {
Expand All @@ -24,62 +23,66 @@ func (opts *BlocksOptions) HandleHashes() error {

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[types.SimpleAppearance]*types.SimpleBlock[string]
if appMap, _, err = identifiers.AsMap[types.SimpleBlock[string]](chain, opts.BlockIds); err != nil {
if sliceOfMaps, cnt, err := identifiers.AsSliceOfMaps[types.SimpleBlock[string]](chain, opts.BlockIds); err != nil {
errorChan <- err
cancel()
}

bar := logger.NewBar(logger.BarOptions{
Type: logger.Expanding,
Enabled: !opts.Globals.TestMode,
Total: int64(len(appMap)),
})
} else if cnt == 0 {
errorChan <- fmt.Errorf("no blocks found for the query")
cancel()

} else {
bar := logger.NewBar(logger.BarOptions{
Enabled: !testMode && !utils.IsTerminal(),
Total: int64(cnt),
})

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")
for _, thisMap := range sliceOfMaps {
thisMap := thisMap
for app := range thisMap {
thisMap[app] = new(types.SimpleBlock[string])
}
cancel()
return nil
} else {
bar.Tick()
*value = block
}
return nil
}

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)
items := make([]*types.SimpleBlock[string], 0, len(thisMap))
iterFunc := func(app types.SimpleAppearance, value *types.SimpleBlock[string]) error {
bn := uint64(app.BlockNumber)
if block, err := opts.Conn.GetBlockHeaderByNumber(bn); err != nil {
delete(thisMap, app)
return err
} else {
*value = block
bar.Tick()
}
return nil
}

items := make([]*types.SimpleBlock[string], 0, len(appMap))
for _, item := range appMap {
items = append(items, item)
}
sort.Slice(items, func(i, j int) bool {
if items[i].BlockNumber == items[j].BlockNumber {
return items[i].Hash.Hex() < items[j].Hash.Hex()
}
return items[i].BlockNumber < items[j].BlockNumber
})
iterErrorChan := make(chan error)
iterCtx, iterCancel := context.WithCancel(context.Background())
defer iterCancel()
go utils.IterateOverMap(iterCtx, iterErrorChan, thisMap, iterFunc)
for err := range iterErrorChan {
if !testMode || nErrors == 0 {
errorChan <- err
nErrors++
}
}

for _, item := range items {
item := item
modelChan <- item
for _, item := range thisMap {
items = append(items, item)
}
sort.Slice(items, func(i, j int) bool {
if items[i].BlockNumber == items[j].BlockNumber {
return items[i].Hash.Hex() < items[j].Hash.Hex()
}
return items[i].BlockNumber < items[j].BlockNumber
})

for _, item := range items {
item := item
modelChan <- item
}
}
bar.Finish(true /* newLine */)
}
}

Expand Down
139 changes: 73 additions & 66 deletions src/apps/chifra/internal/blocks/handle_logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,85 +39,92 @@ func (opts *BlocksOptions) 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 appMap map[types.SimpleAppearance]*types.SimpleTransaction
if appMap, _, err = identifiers.AsMap[types.SimpleTransaction](chain, opts.BlockIds); err != nil {
if sliceOfMaps, cnt, err := identifiers.AsSliceOfMaps[types.SimpleTransaction](chain, opts.BlockIds); err != nil {
errorChan <- err
cancel()
}

bar := logger.NewBar(logger.BarOptions{
Enabled: !opts.Globals.TestMode,
Total: int64(len(appMap)),
})
} else if cnt == 0 {
errorChan <- fmt.Errorf("no blocks found for the query")
cancel()

iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error {
if value.Receipt == nil {
value.Receipt = &types.SimpleReceipt{}
}
} else {
bar := logger.NewBar(logger.BarOptions{
Enabled: !testMode && !utils.IsTerminal(),
Total: int64(cnt),
})

for _, thisMap := range sliceOfMaps {
thisMap := thisMap
for app := range thisMap {
thisMap[app] = new(types.SimpleTransaction)
}

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", bn)
return nil

} else {
l := make([]types.SimpleLog, 0, len(logs))
for index := range logs {
if opts.Articulate {
if err = abiCache.ArticulateLog(&logs[index]); err != nil {
errorChan <- err // continue even with an error
iterFunc := func(app types.SimpleAppearance, value *types.SimpleTransaction) error {
if value.Receipt == nil {
value.Receipt = &types.SimpleReceipt{}
}

bn := uint64(app.BlockNumber)
ts := opts.Conn.GetBlockTimestamp(bn)
if logs, err := opts.Conn.GetLogsByNumber(bn, ts); err != nil {
delete(thisMap, app)
return fmt.Errorf("block at %d returned an error: %w", bn, err)

} else if len(logs) == 0 {
delete(thisMap, app)
return fmt.Errorf("block at %d has no logs", bn)

} else {
l := make([]types.SimpleLog, 0, len(logs))
for index := range logs {
if opts.Articulate {
if err = abiCache.ArticulateLog(&logs[index]); err != nil {
errorChan <- err // continue even with an error
}
}
l = append(l, logs[index])
}
value.Receipt.Logs = append(value.Receipt.Logs, l...)
bar.Tick()
return nil
}
l = append(l, logs[index])
}
bar.Tick()
value.Receipt.Logs = append(value.Receipt.Logs, l...)
}
return nil
}

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
// Reporting more than one error causes tests to fail because they
// appear concurrently so sort differently
nErrors++
}
}
bar.Finish(true)
iterErrorChan := make(chan error)
iterCtx, iterCancel := context.WithCancel(context.Background())
defer iterCancel()
go utils.IterateOverMap(iterCtx, iterErrorChan, thisMap, iterFunc)
for err := range iterErrorChan {
if !testMode || nErrors == 0 {
errorChan <- err
nErrors++
}
}

items := make([]types.SimpleLog, 0, len(appMap))
for _, tx := range appMap {
tx := tx
items = append(items, tx.Receipt.Logs...)
}
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].LogIndex < items[j].LogIndex
items := make([]types.SimpleLog, 0, len(thisMap))
for _, tx := range thisMap {
tx := tx
items = append(items, tx.Receipt.Logs...)
}
return items[i].TransactionIndex < items[j].TransactionIndex
}
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].LogIndex < items[j].LogIndex
}
return items[i].TransactionIndex < items[j].TransactionIndex
}
return items[i].BlockNumber < items[j].BlockNumber
})

for _, item := range items {
item := item
if !logFilter.PassesFilter(&item) {
continue
for _, item := range items {
item := item
if !logFilter.PassesFilter(&item) {
continue
}
modelChan <- &item
}
}
modelChan <- &item
bar.Finish(true /* newLine */)
}
}

Expand Down
Loading