Skip to content

Updates chifra abis with --listItems #3997

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

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions docs/content/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,14 @@ paths:
explode: true
schema:
type: boolean
- name: details
description: show the functions and events instead of summaries for all abi files
required: false
style: form
in: query
explode: true
schema:
type: boolean
- name: count
description: show the number of abis downloaded
required: false
Expand Down
1 change: 1 addition & 0 deletions docs/content/chifra/accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ Flags:
-k, --known load common 'known' ABIs from cache
-r, --proxy_for string redirects the query to this implementation
-l, --list a list of downloaded abi files
-d, --details show the functions and events instead of summaries for all abi files
-c, --count show the number of abis downloaded
-f, --find strings search for function or event declarations given a four- or 32-byte code(s)
-n, --hint strings for the --find option only, provide hints to speed up the search
Expand Down
2 changes: 1 addition & 1 deletion sdk
1 change: 1 addition & 0 deletions src/apps/chifra/cmd/abis.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func init() {
abisCmd.Flags().BoolVarP(&abisPkg.GetOptions().Known, "known", "k", false, `load common 'known' ABIs from cache`)
abisCmd.Flags().StringVarP(&abisPkg.GetOptions().ProxyFor, "proxy_for", "r", "", `redirects the query to this implementation`)
abisCmd.Flags().BoolVarP(&abisPkg.GetOptions().List, "list", "l", false, `a list of downloaded abi files`)
abisCmd.Flags().BoolVarP(&abisPkg.GetOptions().Details, "details", "d", false, `show the functions and events instead of summaries for all abi files`)
abisCmd.Flags().BoolVarP(&abisPkg.GetOptions().Count, "count", "c", false, `show the number of abis downloaded`)
abisCmd.Flags().StringSliceVarP(&abisPkg.GetOptions().Find, "find", "f", nil, `search for function or event declarations given a four- or 32-byte code(s)`)
abisCmd.Flags().StringSliceVarP(&abisPkg.GetOptions().Hint, "hint", "n", nil, `for the --find option only, provide hints to speed up the search`)
Expand Down
1 change: 1 addition & 0 deletions src/apps/chifra/internal/abis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Flags:
-k, --known load common 'known' ABIs from cache
-r, --proxy_for string redirects the query to this implementation
-l, --list a list of downloaded abi files
-d, --details show the functions and events instead of summaries for all abi files
-c, --count show the number of abis downloaded
-f, --find strings search for function or event declarations given a four- or 32-byte code(s)
-n, --hint strings for the --find option only, provide hints to speed up the search
Expand Down
55 changes: 55 additions & 0 deletions src/apps/chifra/internal/abis/handle_details.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package abisPkg

import (
"errors"
"fmt"
"path/filepath"
"strings"

"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
)

func (opts *AbisOptions) HandleDetails(rCtx *output.RenderCtx) (err error) {
if len(opts.Addrs) == 0 {
vFunc := func(fn string, vP any) (bool, error) {
_ = vP
_, name := filepath.Split(fn)
if strings.HasSuffix(name, ".json") {
if base.IsValidAddress(strings.TrimSuffix(name, ".json")) {
// silent ignore
opts.Addrs = append(opts.Addrs, strings.TrimSuffix(name, ".json"))
}
}
return true, nil
}
opts.ForEveryAbi(true, vFunc, nil)
}

fetchData := func(modelChan chan types.Modeler, errorChan chan error) {
for _, addr := range opts.Addrs {
functions, which, err := opts.LoadAbis([]string{addr}, false /* known */)
if err != nil {
if errors.Is(err, rpc.ErrNotAContract) {
msg := fmt.Errorf("address %s is not a smart contract", which)
errorChan <- msg
// Report but don't quit processing
} else {
// Cancel on all other errors
errorChan <- err
rCtx.Cancel()
// } else if len(opts.ProxyFor) > 0 {
// TODO: We need to copy the proxied-to ABI to the proxy (replacing)
}
}

for _, f := range functions {
modelChan <- f
}
}
}

return output.StreamMany(rCtx, fetchData, opts.Globals.OutputOpts())
}
7 changes: 6 additions & 1 deletion src/apps/chifra/internal/abis/handle_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@ func (opts *AbisOptions) HandleList(rCtx *output.RenderCtx) error {
abiArray := make([]types.Abi, 0, 100)
vFunc := func(fn string, vP any) (bool, error) {
_ = vP
isKnown := strings.Contains(fn, "known")
if opts.Known && !isKnown {
return true, nil
}

if strings.HasSuffix(fn, ".json") {
info, _ := os.Stat(fn)
abi := types.Abi{
FileSize: file.FileSize(fn),
LastModDate: info.ModTime().Format("2006-01-02 15:04:05"),
IsKnown: strings.Contains(fn, "known"),
IsKnown: isKnown,
}
abi.Path, abi.Name = filepath.Split(fn)
if len(abi.Name) > 0 {
Expand Down
4 changes: 4 additions & 0 deletions src/apps/chifra/internal/abis/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type AbisOptions struct {
Known bool `json:"known,omitempty"` // Load common 'known' ABIs from cache
ProxyFor string `json:"proxyFor,omitempty"` // Redirects the query to this implementation
List bool `json:"list,omitempty"` // A list of downloaded abi files
Details bool `json:"details,omitempty"` // Show the functions and events instead of summaries for all abi files
Count bool `json:"count,omitempty"` // Show the number of abis downloaded
Find []string `json:"find,omitempty"` // Search for function or event declarations given a four- or 32-byte code(s)
Hint []string `json:"hint,omitempty"` // For the --find option only, provide hints to speed up the search
Expand All @@ -52,6 +53,7 @@ func (opts *AbisOptions) testLog() {
logger.TestLog(opts.Known, "Known: ", opts.Known)
logger.TestLog(len(opts.ProxyFor) > 0, "ProxyFor: ", opts.ProxyFor)
logger.TestLog(opts.List, "List: ", opts.List)
logger.TestLog(opts.Details, "Details: ", opts.Details)
logger.TestLog(opts.Count, "Count: ", opts.Count)
logger.TestLog(len(opts.Find) > 0, "Find: ", opts.Find)
logger.TestLog(len(opts.Hint) > 0, "Hint: ", opts.Hint)
Expand Down Expand Up @@ -92,6 +94,8 @@ func AbisFinishParseInternal(w io.Writer, values url.Values) *AbisOptions {
opts.ProxyFor = value[0]
case "list":
opts.List = true
case "details":
opts.Details = true
case "count":
opts.Count = true
case "find":
Expand Down
2 changes: 2 additions & 0 deletions src/apps/chifra/internal/abis/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ func (opts *AbisOptions) AbisInternal(rCtx *output.RenderCtx) error {
err = opts.HandleFind(rCtx)
} else if opts.Count {
err = opts.HandleCount(rCtx)
} else if opts.Details {
err = opts.HandleDetails(rCtx)
} else if opts.List {
err = opts.HandleList(rCtx)
} else if len(opts.Encode) > 0 {
Expand Down
1 change: 1 addition & 0 deletions src/apps/chifra/internal/abis/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (opts *AbisOptions) validateAbis() error {
len(opts.Find) == 0 &&
!opts.Count &&
!opts.List &&
!opts.Details &&
!opts.Known &&
!opts.Globals.Decache {
// If we're not find and not known we better have at least one address
Expand Down
17 changes: 9 additions & 8 deletions src/dev_tools/goMaker/templates/cmd-line-options.csv
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ num,folder,group,route,tool,longName,hotKey,def_val,attributes,handler,option_ty
12150,apps,Accounts,list,acctExport,n2,,,,,note,,,,,,No other options are permitted when --silent is selected.
#
13000,apps,Accounts,export,acctExport,,,,visible|docs,,command,,,Export details,[flags] <address> [address...] [topics...] [fourbytes...],default|caching|ether|names|,Export full details of transactions for one or more addresses.
13020,apps,Accounts,export,acctExport,addrs,,,required|visible|docs,13,positional,list<addr>,transaction,,,,one or more addresses (0x...) to export
13020,apps,Accounts,export,acctExport,addrs,,,required|visible|docs,12,positional,list<addr>,transaction,,,,one or more addresses (0x...) to export
13030,apps,Accounts,export,acctExport,topics,,,visible|docs,,positional,list<topic>,,,,,filter by one or more log topics (only for --logs option)
13040,apps,Accounts,export,acctExport,fourbytes,,,visible|docs,,positional,list<fourbyte>,,,,,filter by one or more fourbytes (only for transactions and trace options)
13050,apps,Accounts,export,acctExport,appearances,p,,visible|docs,5,switch,<boolean>,appearance,,,,export a list of appearances
13060,apps,Accounts,export,acctExport,receipts,r,,visible|docs,2,switch,<boolean>,receipt,,,,export receipts instead of transactional data
13070,apps,Accounts,export,acctExport,logs,l,,visible|docs,3,switch,<boolean>,log,,,,export logs instead of transactional data
13080,apps,Accounts,export,acctExport,traces,t,,visible|docs,12,switch,<boolean>,trace,,,,export traces instead of transactional data
13080,apps,Accounts,export,acctExport,traces,t,,visible|docs,11,switch,<boolean>,trace,,,,export traces instead of transactional data
13090,apps,Accounts,export,acctExport,neighbors,n,,visible|docs,8,switch,<boolean>,message,,,,export the neighbors of the given address
13110,apps,Accounts,export,acctExport,statements,A,,visible|docs,9,switch,<boolean>,statement,,,,export only statements
13110,apps,Accounts,export,acctExport,transfers,X,,visible|docs,10,switch,<boolean>,transfer,,,,export only eth or token transfers
Expand Down Expand Up @@ -64,7 +64,7 @@ num,folder,group,route,tool,longName,hotKey,def_val,attributes,handler,option_ty
13430,apps,Accounts,export,acctExport,n12,,,,,note,,,,,,The --traces option requires your RPC to provide trace data. See the README for more information.
#
14000,apps,Accounts,monitors,acctExport,,,,visible|docs,,command,,,Manage monitors,[flags] <address> [address...],default|caching|names|,Add&#44; remove&#44; clean&#44; and list address monitors.
14020,apps,Accounts,monitors,acctExport,addrs,,,visible|docs,5,positional,list<addr>,message,,,,one or more addresses (0x...) to process
14020,apps,Accounts,monitors,acctExport,addrs,,,visible|docs,4,positional,list<addr>,message,,,,one or more addresses (0x...) to process
14030,apps,Accounts,monitors,acctExport,delete,,,visible|docs|crud,,switch,<boolean>,,,,,delete a monitor&#44; but do not remove it
14040,apps,Accounts,monitors,acctExport,undelete,,,visible|docs|crud,,switch,<boolean>,,,,,undelete a previously deleted monitor
14050,apps,Accounts,monitors,acctExport,remove,,,visible|docs|crud,,switch,<boolean>,,,,,remove a previously deleted monitor
Expand Down Expand Up @@ -97,14 +97,15 @@ num,folder,group,route,tool,longName,hotKey,def_val,attributes,handler,option_ty
15200,tools,Accounts,names,ethNames,n2,,,,,note,,,,,,The `--match_case` option enables case sensitive matching.
#
16000,tools,Accounts,abis,grabABI,,,,visible|docs,,command,,,Manage Abi files,[flags] <address> [address...],default|caching|names|,Fetches the ABI for a smart contract.
16020,tools,Accounts,abis,grabABI,addrs,,,required|visible|docs,5,positional,list<addr>,function,,,,a list of one or more smart contracts whose ABIs to display
16020,tools,Accounts,abis,grabABI,addrs,,,required|visible|docs,6,positional,list<addr>,function,,,,a list of one or more smart contracts whose ABIs to display
16030,tools,Accounts,abis,grabABI,known,k,,visible|docs,,switch,<boolean>,,,,,load common 'known' ABIs from cache
16040,tools,Accounts,abis,grabABI,proxy_for,r,,visible|docs,,flag,<address>,,,,,redirects the query to this implementation
16050,tools,Accounts,abis,grabABI,list,l,,visible|docs,3,switch,<boolean>,abi,,,,a list of downloaded abi files
16050,tools,Accounts,abis,grabABI,list,l,,visible|docs,4,switch,<boolean>,abi,,,,a list of downloaded abi files
16055,tools,Accounts,abis,grabABI,details,d,,visible|docs,3,switch,<boolean>,function,,,,show the functions and events instead of summaries for all abi files
16060,tools,Accounts,abis,grabABI,count,c,,visible|docs,2,switch,<boolean>,count,,,,show the number of abis downloaded
16070,tools,Accounts,abis,grabABI,find,f,,visible|docs,1,flag,list<string>,function,,,,search for function or event declarations given a four- or 32-byte code(s)
16080,tools,Accounts,abis,grabABI,hint,n,,visible|docs,,flag,list<string>,,,,,for the --find option only&#44; provide hints to speed up the search
16090,tools,Accounts,abis,grabABI,encode,e,,visible|docs,4,flag,<string>,function,,,,generate the 32-byte encoding for a given canonical function or event signature
16090,tools,Accounts,abis,grabABI,encode,e,,visible|docs,5,flag,<string>,function,,,,generate the 32-byte encoding for a given canonical function or event signature
16100,tools,Accounts,abis,grabABI,n1,,,,,note,,,,,,Search for either four byte signatures or event signatures with the --find option.
#
21000,,Chain Data,,,,,,,,group,,,,,,Access and cache blockchain-related data
Expand Down Expand Up @@ -135,10 +136,10 @@ num,folder,group,route,tool,longName,hotKey,def_val,attributes,handler,option_ty
22280,tools,Chain Data,blocks,getBlocks,n10,,,,,note,,,,,,The --traces option requires your RPC to provide trace data. See the README for more information.
#
23000,tools,Chain Data,transactions,getTrans,,,,visible|docs,,command,,,Get transactions,[flags] <tx_id> [tx_id...],default|caching|ether|names|,Retrieve one or more transactions from the chain or local cache.
23020,tools,Chain Data,transactions,getTrans,transactions,,,required|visible|docs,4,positional,list<tx_id>,transaction,,,,a space-separated list of one or more transaction identifiers
23020,tools,Chain Data,transactions,getTrans,transactions,,,required|visible|docs,3,positional,list<tx_id>,transaction,,,,a space-separated list of one or more transaction identifiers
23030,tools,Chain Data,transactions,getTrans,articulate,a,,visible|docs,,switch,<boolean>,,,,,articulate the retrieved data if ABIs can be found
23040,tools,Chain Data,transactions,getTrans,traces,t,,visible|docs,,switch,<boolean>,trace,,,,include the transaction's traces in the results
23050,tools,Chain Data,transactions,getTrans,uniq,u,,visible|docs,3,switch,<boolean>,appearance,,,,display a list of uniq addresses found in the transaction
23050,tools,Chain Data,transactions,getTrans,uniq,u,,visible|docs,2,switch,<boolean>,appearance,,,,display a list of uniq addresses found in the transaction
23060,tools,Chain Data,transactions,getTrans,flow,f,,visible|docs,,flag,enum[from|to],,,,,for the uniq option only&#44; export only from or to (including trace from or to)
23070,tools,Chain Data,transactions,getTrans,logs,l,,visible|docs,1,switch,<boolean>,log,,,,display only the logs found in the transaction(s)
23080,tools,Chain Data,transactions,getTrans,emitter,m,,visible|docs,,flag,list<addr>,,,,,for the --logs option only&#44; filter logs to show only those logs emitted by the given address(es)
Expand Down
56 changes: 56 additions & 0 deletions src/dev_tools/goMaker/types/types_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"path/filepath"
"sort"
"strings"
"unicode"

"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file"
"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger"
Expand Down Expand Up @@ -167,6 +168,61 @@ func (c *Command) Clean() {
}
}

// Validate LongName and Handler properties of each Option in cleaned
// Rule 1: LongName should not contain any capital letters.
// Rule 2: Handler (if present) must represent a sequence of integers
// starting from 1 without any gaps or duplicates.
handlerValues := make(map[int]bool)
maxHandler := 0

for _, op := range cleaned {
// Rule 1: Check for capital letters in LongName
if op.LongName != strings.ToLower(op.LongName) {
suggestion := ""
for i, char := range op.LongName {
if unicode.IsUpper(char) {
if i > 0 { // Only add underscore if not the first character
suggestion += "_"
}
suggestion += strings.ToLower(string(char))
} else {
suggestion += string(char)
}
}
logger.Warn(fmt.Sprintf("Option '%s' in command '%s': LongName '%s' should not contain capital letters. Suggestion: '%s'", op.LongName, c.Route, op.LongName, suggestion))
}

// Rule 2: Check Handler values
// Assuming 0.0 indicates that the handler is not set.
if op.Handler != 0.0 {
handlerVal := int(op.Handler) // Convert float64 to int

if handlerVal <= 0 { // Handlers should be positive integers
logger.Warn(fmt.Sprintf("Option '%s' in command '%s': Handler value '%f' must be a positive integer.", op.LongName, c.Route, op.Handler))
continue
}

if _, exists := handlerValues[handlerVal]; exists {
logger.Warn(fmt.Sprintf("Option '%s' in command '%s': Duplicate Handler value '%d'.", op.LongName, c.Route, handlerVal))
} else {
handlerValues[handlerVal] = true
}

if handlerVal > maxHandler {
maxHandler = handlerVal
}
}
}

// After collecting all handlers, check for gaps in the sequence from 1 to maxHandler
if maxHandler > 0 {
for i := 1; i <= maxHandler; i++ {
if _, exists := handlerValues[i]; !exists {
logger.Warn(fmt.Sprintf("Command '%s': Missing Handler value '%d' in the sequence.", c.Route, i))
}
}
}

c.Options = cleaned
}

Expand Down
7 changes: 6 additions & 1 deletion src/dev_tools/goMaker/types/types_sorts.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ if len(sortSpec.Fields) != len(sortSpec.Order) {

sorts := make([]func(p1, p2 types.{{.Class}}) bool, len(sortSpec.Fields))
for i, field := range sortSpec.Fields {
if field == "" {
continue
}
if !types.IsValid{{.Class}}Field(field) {
return fmt.Errorf("%s is not an {{.Class}} sort field", field)
}
sorts[i] = types.{{.Class}}By(types.{{.Class}}Field(field), types.SortOrder(sortSpec.Order[i]))
}

sort.Slice({{toLowerPlural .Class}}, types.{{.Class}}Cmp({{toLowerPlural .Class}}, sorts...))
if len(sorts) > 0 {
sort.SliceStable({{toLowerPlural .Class}}, types.{{.Class}}Cmp({{toLowerPlural .Class}}, sorts...))
}
return nil
}
`
Expand Down
10 changes: 10 additions & 0 deletions src/dev_tools/sdkFuzzer/abis.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ func TestAbis(which, value, fn string, opts *sdk.AbisOptions) {
ReportOkay(fn)
}
}
case "details":
if details, _, err := opts.AbisDetails(); err != nil {
ReportError(fn, opts, err)
} else {
if err := SaveToFile(fn, details); err != nil {
ReportError2(fn, err)
} else {
ReportOkay(fn)
}
}
case "count":
if count, _, err := opts.AbisCount(); err != nil {
ReportError(fn, opts, err)
Expand Down
3 changes: 3 additions & 0 deletions src/dev_tools/testRunner/testCases/abis.csv
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ on ,both ,fast ,abis ,tools ,grabABI ,no_abi_found_2 ,y ,addrs =
on ,both ,fast ,abis ,tools ,grabABI ,clean_alone ,y ,decache

on ,both ,fast ,abis ,tools ,grabABI ,list ,y ,list
on ,both ,fast ,abis ,tools ,grabABI ,list_known ,y ,list & known
on ,both ,fast ,abis ,tools ,grabABI ,list_verbose ,y ,list & verbose
on ,both ,fast ,abis ,tools ,grabABI ,list_funcs ,y ,list & details & addrs = 0xe94327d07fc17907b4db788e5adf2ed424addff6
on ,both ,fast ,abis ,tools ,grabABI ,list_events ,y ,list & details & addrs = 0xe94327d07fc17907b4db788e5adf2ed424addff6
on ,both ,fast ,abis ,tools ,grabABI ,count ,y ,count
on ,both ,fast ,abis ,tools ,grabABI ,count_v ,y ,count & no_header
on ,both ,fast ,abis ,tools ,grabABI ,count_list ,y ,count & list
Expand Down
4 changes: 2 additions & 2 deletions src/dev_tools/testRunner/testCases/daemon.csv
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
enabled ,mode ,speed ,route ,path ,tool ,filename ,post ,options
on ,cmd ,fast ,daemon ,apps ,daemon ,help ,n ,@h
on ,cmd ,fast ,daemon ,apps ,daemon ,help_long ,n ,help
on ,both ,fast ,daemon ,apps ,daemon ,bad_cmd ,n ,not-an-option
on ,both ,fast ,daemon ,apps ,daemon ,port ,n ,not-an-option & port = :8080
off ,both ,fast ,daemon ,apps ,daemon ,bad_cmd ,n ,not-an-option
off ,both ,fast ,daemon ,apps ,daemon ,port ,n ,not-an-option & port = :8080

# Capabilities
# chain & fmt & help & nocolor & noop & version & verbose & no_header & file & output & append & cache & ether
Expand Down
1 change: 1 addition & 0 deletions tests/gold/apps/chifra/chifra_help_abis.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Flags:
-k, --known load common 'known' ABIs from cache
-r, --proxy_for string redirects the query to this implementation
-l, --list a list of downloaded abi files
-d, --details show the functions and events instead of summaries for all abi files
-c, --count show the number of abis downloaded
-f, --find strings search for function or event declarations given a four- or 32-byte code(s)
-n, --hint strings for the --find option only, provide hints to speed up the search
Expand Down
Loading
Loading