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

Feature/port chifra abis #2661

Merged
merged 24 commits into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
Prev Previous commit
Next Next commit
Fixed chifra abis --find tests
  • Loading branch information
dszlachta committed Jan 24, 2023
commit 1479483118d1cd2fef2d2523af16161cc270ab85
3 changes: 1 addition & 2 deletions src/apps/chifra/internal/abis/handle_addresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import (
"github.com/ethereum/go-ethereum/common"
)

var testMode = os.Getenv("TEST_MODE") == "true"

func (opts *AbisOptions) HandleAddresses() (err error) {
testMode := opts.Globals.TestMode
result := make(abi.AbiInterfaceMap)
if opts.Known {
if err = abi.PreloadKnownAbis(opts.Globals.Chain, result, false); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

I'm confused by this a little bit. The "Handle" routines typically generate output, but doesn't this return without having generated output? If yes, my question is why do we come in here at all? Why not do this test before calling?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But we only return if there was an error. Should we ignore it and continue even if we cannot read the binary cache?

Expand Down
167 changes: 98 additions & 69 deletions src/apps/chifra/internal/abis/handle_find.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package abisPkg
import (
"bufio"
"bytes"
"context"
"encoding/hex"
"io"
"os"
Expand All @@ -18,95 +19,123 @@ import (
"github.com/ethereum/go-ethereum/crypto"
ants "github.com/panjf2000/ants/v2"

"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/internal/globals"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config"
"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/progress"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
)

func (opts *AbisOptions) HandleAbiFind() error {
testMode := opts.Globals.TestMode
Copy link
Member

Choose a reason for hiding this comment

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

I'll just assume this works if the tests pass.

/* wanted */ /* freq */ /* max */
scanBar := progress.NewScanBar(uint64(len(opts.Find)), 13919, 50000000, .5)

// TODO: SimpleFunctionOutput is a temporary fix for outputing ABIs, we can remove it
// TODO: once we start using StreamMany in this code
var results []types.SimpleFunctionOutput

var wg sync.WaitGroup
checkOne, _ := ants.NewPoolWithFunc(runtime.NumCPU()*2, func(testSig interface{}) {
defer wg.Done()
byts := []byte(testSig.(string))
sigBytes := crypto.Keccak256(byts)
for _, arg := range opts.Find {
if !opts.Globals.TestMode {
scanBar.Report(os.Stderr, "Scanning", testSig.(string))
}
str, _ := hex.DecodeString(arg[2:])
if bytes.Equal(sigBytes[:len(str)], str) {
scanBar.Found++
if len(opts.Find) < 2 || !opts.Globals.TestMode {
logger.Log(logger.Progress, "Found ", scanBar.Found, " of ", scanBar.Wanted, arg, testSig)
ctx, cancel := context.WithCancel(context.Background())
fetchData := func(modelChan chan types.Modeler[types.RawFunction], errorChan chan error) {
var results []types.SimpleFunction
var wg sync.WaitGroup
mutex := sync.Mutex{}
checkOne, _ := ants.NewPoolWithFunc(runtime.NumCPU()*2, func(testSig interface{}) {
defer wg.Done()
byts := []byte(testSig.(string))
sigBytes := crypto.Keccak256(byts)
for _, arg := range opts.Find {
if !opts.Globals.TestMode {
scanBar.Report(os.Stderr, "Scanning", testSig.(string))
}
str, _ := hex.DecodeString(arg[2:])
if bytes.Equal(sigBytes[:len(str)], str) {
scanBar.Found++
if len(opts.Find) < 2 || !opts.Globals.TestMode {
logger.Log(logger.Progress, "Found ", scanBar.Found, " of ", scanBar.Wanted, arg, testSig)
}
found := types.SimpleFunction{Encoding: arg, Signature: testSig.(string)}
if testMode {
mutex.Lock()
results = append(results, found)
mutex.Unlock()
} else {
modelChan <- &found
}
return
}
results = append(results, types.SimpleFunctionOutput{Encoding: arg, Signature: testSig.(string)})
return
}
})
defer checkOne.Release()

// TODO: UnchainedIndex --> This could be part of unchained index
sigsFile, err := os.OpenFile(config.GetPathToRootConfig()+"abis/known-000/uniq_sigs.tab", os.O_RDONLY, 0)
if err != nil {
errorChan <- err
cancel()
return
}
})
defer checkOne.Release()

// TODO: UnchainedIndex --> This could be part of unchained index
sigsFile, err := os.OpenFile(config.GetPathToRootConfig()+"abis/known-000/uniq_sigs.tab", os.O_RDONLY, 0)
if err != nil {
return err
}
defer func() {
sigsFile.Close()
}()
sigsFile.Seek(0, io.SeekStart)
sigsScanner := bufio.NewScanner(sigsFile)
sigsScanner.Split(bufio.ScanLines)

// TODO: UnchainedIndex --> This could be part of unchained index
funcsFile, _ := os.OpenFile(config.GetPathToRootConfig()+"abis/known-000/uniq_funcs.tab", os.O_RDONLY, 0)
defer func() {
funcsFile.Close()
}()

for sigsScanner.Scan() {
s := sigsScanner.Text()
hitsSignature := opts.hitsHint(s)

funcsFile.Seek(0, io.SeekStart)
funcsScanner := bufio.NewScanner(funcsFile)
funcsScanner.Split(bufio.ScanLines)

for funcsScanner.Scan() {
f := funcsScanner.Text()
hitsFunction := opts.hitsHint(f)
if hitsSignature || hitsFunction {
wg.Add(1)
call := f + "(" + s + ")"
_ = checkOne.Invoke(call)
defer func() {
sigsFile.Close()
}()
sigsFile.Seek(0, io.SeekStart)
sigsScanner := bufio.NewScanner(sigsFile)
sigsScanner.Split(bufio.ScanLines)

// TODO: UnchainedIndex --> This could be part of unchained index
funcsFile, _ := os.OpenFile(config.GetPathToRootConfig()+"abis/known-000/uniq_funcs.tab", os.O_RDONLY, 0)
defer func() {
funcsFile.Close()
}()

for sigsScanner.Scan() {
s := sigsScanner.Text()
hitsSignature := opts.hitsHint(s)

funcsFile.Seek(0, io.SeekStart)
funcsScanner := bufio.NewScanner(funcsFile)
funcsScanner.Split(bufio.ScanLines)

for funcsScanner.Scan() {
f := funcsScanner.Text()
hitsFunction := opts.hitsHint(f)
if hitsSignature || hitsFunction {
wg.Add(1)
call := f + "(" + s + ")"
_ = checkOne.Invoke(call)
}
}
}

if scanBar.Satisfied() {
break
if scanBar.Satisfied() {
break
}
}
}

defer wg.Wait()
defer wg.Wait()

if opts.Globals.TestMode {
// Otherwise the test is not reproducable
sort.Slice(results, func(i, j int) bool {
return results[i].Signature < results[j].Signature
})
if opts.Globals.TestMode {
// Otherwise the test is not reproducable
sort.Slice(results, func(i, j int) bool {
return results[i].Signature < results[j].Signature
})
for _, item := range results {
modelChan <- &item
}
}
}

// TODO: Fix export without arrays
return globals.RenderSlice(&opts.Globals, results)
return output.StreamMany(ctx, fetchData, output.OutputOptions{
Writer: opts.Globals.Writer,
Chain: opts.Globals.Chain,
TestMode: opts.Globals.TestMode,
NoHeader: opts.Globals.NoHeader,
ShowRaw: opts.Globals.ShowRaw,
Verbose: opts.Globals.Verbose,
LogLevel: opts.Globals.LogLevel,
Format: opts.Globals.Format,
OutputFn: opts.Globals.OutputFn,
Append: opts.Globals.Append,
JsonIndent: " ",
Extra: map[string]interface{}{
"encodingSignatureOnly": true,
},
})
}

func (opts *AbisOptions) hitsHint(test string) bool {
Expand Down
1 change: 0 additions & 1 deletion src/apps/chifra/internal/globals/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ func RenderSlice[
types.ReportClean |
types.ReportCheck |
types.SimpleFunction |
types.SimpleFunctionOutput |
Copy link
Member

Choose a reason for hiding this comment

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

Thank you!

types.SimpleMonitor |
types.SimpleChunkRecord |
types.SimpleAppearance |
Expand Down
17 changes: 11 additions & 6 deletions src/apps/chifra/pkg/types/types_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ func joinParametersNames(params []SimpleParameter) (result string) {
}

func (s *SimpleFunction) Model(showHidden bool, format string, extraOptions map[string]any) Model {
// Used by chifra abis --find
if extraOptions["encodingSignatureOnly"] == true {
return Model{
Data: map[string]any{
"encoding": s.Encoding,
"signature": s.Signature,
},
Order: []string{"encoding", "signature"},
}
}

model := map[string]interface{}{
"name": s.Name,
"type": s.FunctionType,
Expand Down Expand Up @@ -172,9 +183,3 @@ func (s *SimpleFunction) Model(showHidden bool, format string, extraOptions map[
Order: order,
}
}

// TODO: remove this type when we move ABI output to StreamMany
type SimpleFunctionOutput struct {
Encoding string `json:"encoding,omitempty"`
Signature string `json:"signature,omitempty"`
}
4 changes: 2 additions & 2 deletions test/gold/tools/grabABI/api_tests/grabABI_findSig_csv.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
abis?find=0x1aa3a008&fmt=csv
"encoding","signature"
"0x1aa3a008","register()"
encoding,signature
0x1aa3a008,register()
4 changes: 2 additions & 2 deletions test/gold/tools/grabABI/grabABI_findSig_csv.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
chifra abis --find 0x1aa3a008 --fmt csv
TEST[DATE|TIME] Find: [0x1aa3a008]
TEST[DATE|TIME] Format: csv
PROG[DATE|TIME] Found 1 of 10x1aa3a008register()"encoding","signature"
"0x1aa3a008","register()"
PROG[DATE|TIME] Found 1 of 10x1aa3a008register()encoding,signature
0x1aa3a008,register()
Expand Down