github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/abis/handle_find.go (about) 1 // Copyright 2021 The TrueBlocks Authors. All rights reserved. 2 // Use of this source code is governed by a license that can 3 // be found in the LICENSE file. 4 5 package abisPkg 6 7 import ( 8 "bufio" 9 "bytes" 10 "encoding/hex" 11 "io" 12 "os" 13 "path/filepath" 14 "runtime" 15 "sort" 16 "strings" 17 "sync" 18 19 "github.com/ethereum/go-ethereum/crypto" 20 ants "github.com/panjf2000/ants/v2" 21 22 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 23 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" 24 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output" 25 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/progress" 26 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 27 ) 28 29 func (opts *AbisOptions) HandleFind(rCtx *output.RenderCtx) error { 30 testMode := opts.Globals.TestMode 31 /* wanted */ /* freq */ /* max */ 32 scanBar := progress.NewScanBar(uint64(len(opts.Find)), 13919, 50000000, .5) 33 34 // TODO: we might want to use utils.IterateOver Map here 35 36 fetchData := func(modelChan chan types.Modeler, errorChan chan error) { 37 var results []types.Function 38 var wg sync.WaitGroup 39 mutex := sync.Mutex{} 40 checkOne, _ := ants.NewPoolWithFunc(runtime.NumCPU()*2, func(testSig any) { 41 defer wg.Done() 42 byts := []byte(testSig.(string)) 43 sigBytes := crypto.Keccak256(byts) 44 for _, arg := range opts.Find { 45 if !opts.Globals.TestMode { 46 scanBar.Report(os.Stderr, "Scanning", testSig.(string)) 47 } 48 str, _ := hex.DecodeString(arg[2:]) 49 if bytes.Equal(sigBytes[:len(str)], str) { 50 scanBar.Found++ 51 logger.Progress(len(opts.Find) < 2, "Found", scanBar.Found, "of", scanBar.Wanted, arg, testSig) 52 found := types.Function{ 53 Encoding: arg, 54 Signature: testSig.(string), 55 } 56 if testMode { 57 mutex.Lock() 58 results = append(results, found) 59 mutex.Unlock() 60 } else { 61 modelChan <- &found 62 } 63 return 64 } 65 } 66 }) 67 defer checkOne.Release() 68 69 // TODO: UnchainedIndex --> This could be part of unchained index 70 sigFile := filepath.Join(config.PathToRootConfig(), "abis", "known-000", "uniq_sigs.tab") 71 sigsFile, err := os.OpenFile(sigFile, os.O_RDONLY, 0) 72 if err != nil { 73 errorChan <- err 74 rCtx.Cancel() 75 return 76 } 77 defer func() { 78 sigsFile.Close() 79 }() 80 _, _ = sigsFile.Seek(0, io.SeekStart) 81 sigsScanner := bufio.NewScanner(sigsFile) 82 sigsScanner.Split(bufio.ScanLines) 83 84 // TODO: UnchainedIndex --> This could be part of unchained index 85 funcFile := filepath.Join(config.PathToRootConfig(), "abis", "known-000", "uniq_funcs.tab") 86 funcsFile, _ := os.OpenFile(funcFile, os.O_RDONLY, 0) 87 defer func() { 88 funcsFile.Close() 89 }() 90 91 for sigsScanner.Scan() { 92 s := sigsScanner.Text() 93 hitsSignature := opts.hitsHint(s) 94 95 _, _ = funcsFile.Seek(0, io.SeekStart) 96 funcsScanner := bufio.NewScanner(funcsFile) 97 funcsScanner.Split(bufio.ScanLines) 98 99 for funcsScanner.Scan() { 100 f := funcsScanner.Text() 101 hitsFunction := opts.hitsHint(f) 102 if hitsSignature || hitsFunction { 103 wg.Add(1) 104 call := f + "(" + s + ")" 105 _ = checkOne.Invoke(call) 106 } 107 } 108 109 if scanBar.Satisfied() && !opts.Globals.Verbose { 110 break 111 } 112 } 113 114 defer wg.Wait() 115 116 if opts.Globals.TestMode { 117 // Otherwise the test is not reproducable 118 sort.Slice(results, func(i, j int) bool { 119 return results[i].Signature < results[j].Signature 120 }) 121 for _, item := range results { 122 modelChan <- &item 123 } 124 } 125 } 126 127 extraOpts := map[string]any{ 128 "encodingSignatureOnly": true, 129 } 130 return output.StreamMany(rCtx, fetchData, opts.Globals.OutputOptsWithExtra(extraOpts)) 131 } 132 133 func (opts *AbisOptions) hitsHint(test string) bool { 134 hits := len(opts.Hint) == 0 135 if !hits { 136 // test = strings.ToLower(test) 137 for _, hint := range opts.Hint { 138 if strings.Contains(test, hint) { 139 return true 140 } 141 } 142 } 143 return hits 144 }