From 91a50d5b37fd583beb2a7b983d9b2f42803f8ac4 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Mon, 8 Apr 2024 13:45:45 +0200 Subject: [PATCH 01/19] fix: Revert "fix: hardcode max vm cycles in keeper" (#1902) --- contribs/gnodev/pkg/dev/node.go | 7 ++++--- gno.land/cmd/gnoland/start.go | 10 +++++++++- gno.land/pkg/gnoland/app.go | 5 +++-- gno.land/pkg/gnoland/node_inmemory.go | 9 ++++++--- gno.land/pkg/sdk/vm/common_test.go | 2 +- gno.land/pkg/sdk/vm/keeper.go | 8 ++------ 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/contribs/gnodev/pkg/dev/node.go b/contribs/gnodev/pkg/dev/node.go index 5d5a4c5c5e6..23ac66a5f9a 100644 --- a/contribs/gnodev/pkg/dev/node.go +++ b/contribs/gnodev/pkg/dev/node.go @@ -410,8 +410,9 @@ func newNodeConfig(tmc *tmcfg.Config, chainid string, appstate gnoland.GnoGenesi } return &gnoland.InMemoryNodeConfig{ - PrivValidator: pv, - TMConfig: tmc, - Genesis: genesis, + PrivValidator: pv, + TMConfig: tmc, + Genesis: genesis, + GenesisMaxVMCycles: 10_000_000, } } diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 7fa7de32e5c..2b1757706f8 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -36,6 +36,7 @@ type startCfg struct { chainID string genesisRemote string dataDir string + genesisMaxVMCycles int64 config string txEventStoreType string @@ -124,6 +125,13 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { "replacement for '%%REMOTE%%' in genesis", ) + fs.Int64Var( + &c.genesisMaxVMCycles, + "genesis-max-vm-cycles", + 10_000_000, + "set maximum allowed vm cycles per operation. Zero means no limit.", + ) + fs.StringVar( &c.config, flagConfigFlag, @@ -246,7 +254,7 @@ func execStart(c *startCfg, io commands.IO) error { cfg.TxEventStore = txEventStoreCfg // Create application and node. - gnoApp, err := gnoland.NewApp(dataDir, c.skipFailingGenesisTxs, logger) + gnoApp, err := gnoland.NewApp(dataDir, c.skipFailingGenesisTxs, logger, c.genesisMaxVMCycles) if err != nil { return fmt.Errorf("error in creating new app: %w", err) } diff --git a/gno.land/pkg/gnoland/app.go b/gno.land/pkg/gnoland/app.go index 86fb6321386..cc15f74134e 100644 --- a/gno.land/pkg/gnoland/app.go +++ b/gno.land/pkg/gnoland/app.go @@ -31,6 +31,7 @@ type AppOptions struct { GnoRootDir string SkipFailingGenesisTxs bool Logger *slog.Logger + MaxCycles int64 } func NewAppOptions() *AppOptions { @@ -77,7 +78,7 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) { // XXX: Embed this ? stdlibsDir := filepath.Join(cfg.GnoRootDir, "gnovm", "stdlibs") - vmKpr := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, stdlibsDir) + vmKpr := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, stdlibsDir, cfg.MaxCycles) // Set InitChainer baseApp.SetInitChainer(InitChainer(baseApp, acctKpr, bankKpr, cfg.SkipFailingGenesisTxs)) @@ -122,7 +123,7 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) { } // NewApp creates the GnoLand application. -func NewApp(dataRootDir string, skipFailingGenesisTxs bool, logger *slog.Logger) (abci.Application, error) { +func NewApp(dataRootDir string, skipFailingGenesisTxs bool, logger *slog.Logger, maxCycles int64) (abci.Application, error) { var err error cfg := NewAppOptions() diff --git a/gno.land/pkg/gnoland/node_inmemory.go b/gno.land/pkg/gnoland/node_inmemory.go index d8dc3caa485..89f222738d0 100644 --- a/gno.land/pkg/gnoland/node_inmemory.go +++ b/gno.land/pkg/gnoland/node_inmemory.go @@ -25,6 +25,7 @@ type InMemoryNodeConfig struct { Genesis *bft.GenesisDoc TMConfig *tmcfg.Config SkipFailingGenesisTxs bool + GenesisMaxVMCycles int64 } // NewMockedPrivValidator generate a new key @@ -78,9 +79,10 @@ func NewDefaultInMemoryNodeConfig(rootdir string) *InMemoryNodeConfig { } return &InMemoryNodeConfig{ - PrivValidator: pv, - TMConfig: tm, - Genesis: genesis, + PrivValidator: pv, + TMConfig: tm, + Genesis: genesis, + GenesisMaxVMCycles: 10_000_000, } } @@ -113,6 +115,7 @@ func NewInMemoryNode(logger *slog.Logger, cfg *InMemoryNodeConfig) (*node.Node, Logger: logger, GnoRootDir: cfg.TMConfig.RootDir, SkipFailingGenesisTxs: cfg.SkipFailingGenesisTxs, + MaxCycles: cfg.GenesisMaxVMCycles, DB: memdb.NewMemDB(), }) if err != nil { diff --git a/gno.land/pkg/sdk/vm/common_test.go b/gno.land/pkg/sdk/vm/common_test.go index ec14ae8515b..b65757da403 100644 --- a/gno.land/pkg/sdk/vm/common_test.go +++ b/gno.land/pkg/sdk/vm/common_test.go @@ -39,7 +39,7 @@ func setupTestEnv() testEnv { acck := authm.NewAccountKeeper(iavlCapKey, std.ProtoBaseAccount) bank := bankm.NewBankKeeper(acck) stdlibsDir := filepath.Join("..", "..", "..", "..", "gnovm", "stdlibs") - vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, stdlibsDir) + vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, stdlibsDir, 10_000_000) vmk.Initialize(ms.MultiCacheWrap()) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index af794fb9b1f..67710be620c 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -22,11 +22,6 @@ import ( const ( maxAllocTx = 500 * 1000 * 1000 maxAllocQuery = 1500 * 1000 * 1000 // higher limit for queries - - // maxVMCycles is the maximum number of cycles allowed while executing a single VM - // message. Ideally this should not be needed, as execution should halt when out of - // gas. The worst case scenario is that this value is used as a fallback. - maxVMCycles = 10_000_000 ) // vm.VMKeeperI defines a module interface that supports Gno @@ -60,6 +55,7 @@ func NewVMKeeper( acck auth.AccountKeeper, bank bank.BankKeeper, stdlibsDir string, + maxCycles int64, ) *VMKeeper { // TODO: create an Options struct to avoid too many constructor parameters vmk := &VMKeeper{ @@ -68,7 +64,7 @@ func NewVMKeeper( acck: acck, bank: bank, stdlibsDir: stdlibsDir, - maxCycles: maxVMCycles, + maxCycles: maxCycles, } return vmk } From df0a53c47eff08eadfc68c958583d57da2b45058 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Mon, 8 Apr 2024 14:25:11 +0200 Subject: [PATCH 02/19] fix: labels error handling (#1877) fixes [this](https://github.com/gnolang/gno/issues/1749) Added error handling on `TRANS_LEAVE` during preprocessing, for break and continue statements that have labels. --- gnovm/pkg/gnolang/gno_test.go | 86 +++++++++++++++++++++++++++++++++ gnovm/pkg/gnolang/preprocess.go | 64 ++++++++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/gnovm/pkg/gnolang/gno_test.go b/gnovm/pkg/gnolang/gno_test.go index e67d4a7024d..7881ddd1601 100644 --- a/gnovm/pkg/gnolang/gno_test.go +++ b/gnovm/pkg/gnolang/gno_test.go @@ -17,6 +17,92 @@ import ( "github.com/jaekwon/testify/require" ) +func TestRunInvalidLabels(t *testing.T) { + tests := []struct { + code string + output string + }{ + { + code: ` + package test + func main(){} + func invalidLabel() { + FirstLoop: + for i := 0; i < 10; i++ { + } + for i := 0; i < 10; i++ { + break FirstLoop + } + } +`, + output: `cannot find branch label "FirstLoop"`, + }, + { + code: ` + package test + func main(){} + + func undefinedLabel() { + for i := 0; i < 10; i++ { + break UndefinedLabel + } + } +`, + output: `label UndefinedLabel undefined`, + }, + { + code: ` + package test + func main(){} + + func labelOutsideScope() { + for i := 0; i < 10; i++ { + continue FirstLoop + } + FirstLoop: + for i := 0; i < 10; i++ { + } + } +`, + output: `cannot find branch label "FirstLoop"`, + }, + { + code: ` + package test + func main(){} + + func invalidLabelStatement() { + if true { + break InvalidLabel + } + } +`, + output: `label InvalidLabel undefined`, + }, + } + + for n, s := range tests { + n := n + t.Run(fmt.Sprintf("%v\n", n), func(t *testing.T) { + defer func() { + if r := recover(); r != nil { + es := fmt.Sprintf("%v\n", r) + if !strings.Contains(es, s.output) { + t.Fatalf("invalid label test: `%v` missing expected error: %+v got: %v\n", n, s.output, es) + } + } else { + t.Fatalf("invalid label test: `%v` should have failed but didn't\n", n) + } + }() + + m := NewMachine("test", nil) + nn := MustParseFile("main.go", s.code) + m.RunFiles(nn) + m.RunMain() + }) + } +} + func TestBuiltinIdentifiersShadowing(t *testing.T) { t.Parallel() tests := map[string]string{} diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index dcb1b0856ca..13cc2a57333 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -1659,7 +1659,14 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { case *BranchStmt: switch n.Op { case BREAK: + if !isSwitchLabel(ns, n.Label) { + findBranchLabel(last, n.Label) + } case CONTINUE: + if isSwitchLabel(ns, n.Label) { + panic(fmt.Sprintf("invalid continue label %q\n", n.Label)) + } + findBranchLabel(last, n.Label) case GOTO: _, depth, index := findGotoLabel(last, n.Label) n.Depth = depth @@ -1977,6 +1984,23 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { return nn } +func isSwitchLabel(ns []Node, label Name) bool { + for { + swch := lastSwitch(ns) + if swch == nil { + break + } + + if swch.GetLabel() == label && label != "" { + return true + } + + ns = ns[:len(ns)-1] + } + + return false +} + func pushInitBlock(bn BlockNode, last *BlockNode, stack *[]BlockNode) { if !bn.IsInitialized() { bn.InitStaticBlock(bn, *last) @@ -2245,6 +2269,46 @@ func funcOf(last BlockNode) (BlockNode, *FuncTypeExpr) { } } +func findBranchLabel(last BlockNode, label Name) ( + bn BlockNode, depth uint8, bodyIdx int, +) { + for { + switch cbn := last.(type) { + case *BlockStmt, *ForStmt, *IfCaseStmt, *RangeStmt, *SelectCaseStmt, *SwitchClauseStmt, *SwitchStmt: + lbl := cbn.GetLabel() + if label == lbl { + bn = cbn + return + } + last = cbn.GetParentNode(nil) + depth += 1 + case *IfStmt: + // These are faux blocks -- shouldn't happen. + panic("unexpected faux blocknode") + case *FileNode: + panic("unexpected file blocknode") + case *PackageNode: + panic("unexpected package blocknode") + case *FuncLitExpr: + body := cbn.GetBody() + _, bodyIdx = body.GetLabeledStmt(label) + if bodyIdx != -1 { + bn = cbn + return + } + panic(fmt.Sprintf( + "cannot find branch label %q", + label)) + case *FuncDecl: + panic(fmt.Sprintf( + "cannot find branch label %q", + label)) + default: + panic("unexpected block node") + } + } +} + func findGotoLabel(last BlockNode, label Name) ( bn BlockNode, depth uint8, bodyIdx int, ) { From 59c6d3e3bbc16d4cafbff08823955d5d465af836 Mon Sep 17 00:00:00 2001 From: Kemal Bekir Date: Mon, 8 Apr 2024 18:59:23 +0100 Subject: [PATCH 03/19] feat: Terminating analysis (#1750) This PR solves: [This issue](https://github.com/gnolang/gno/issues/1086) - Added test for positive and negative outcomes - Implements the terminating description from the [Go spec:](https://go.dev/ref/spec#Terminating_statements) - Analysis performed during preprocessing --------- Co-authored-by: Petar Dambovaliev --- gnovm/pkg/gnolang/preprocess.go | 9 +- gnovm/pkg/gnolang/static_analysis.go | 230 ++++++++++++ gnovm/pkg/gnolang/static_analysis_test.go | 417 ++++++++++++++++++++++ 3 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 gnovm/pkg/gnolang/static_analysis.go create mode 100644 gnovm/pkg/gnolang/static_analysis_test.go diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 13cc2a57333..f98ed899cfc 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -492,7 +492,14 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { last.Define(Name(rn), anyValue(rf.Type)) } } - + // functions that don't return a value do not need termination analysis + // functions that are externally defined or builtin implemented in the vm can't be analysed + if len(ft.Results) > 0 && lastpn.PkgPath != uversePkgPath && n.Body != nil { + errs := Analyze(n) + if len(errs) > 0 { + panic(fmt.Sprintf("%+v\n", errs)) + } + } // TRANS_BLOCK ----------------------- case *FileNode: // only for imports. diff --git a/gnovm/pkg/gnolang/static_analysis.go b/gnovm/pkg/gnolang/static_analysis.go new file mode 100644 index 00000000000..311a0d42feb --- /dev/null +++ b/gnovm/pkg/gnolang/static_analysis.go @@ -0,0 +1,230 @@ +package gnolang + +import ( + "fmt" +) + +type staticAnalysis struct { + // contexts for switch, for, functions, and lambdas + contexts []interface{} + + // here we accumulate errors + // from lambdas defined in the function declaration + errs []error +} + +func newStaticAnalysis() *staticAnalysis { + return &staticAnalysis{ + contexts: make([]interface{}, 0), + errs: make([]error, 0), + } +} + +func Analyze(f *FuncDecl) []error { + s := newStaticAnalysis() + s.push(&FuncDeclContext{ + hasRet: false, + f: f, + }) + term := s.staticAnalysisBlockStmt(f.Body) + + errs := make([]error, 0) + if !term { + errs = append(errs, fmt.Errorf("function %q does not terminate", f.Name)) + } + + errs = append(errs, s.errs...) + + return errs +} + +func (s *staticAnalysis) push(ctx interface{}) { + s.contexts = append(s.contexts, ctx) +} + +func (s *staticAnalysis) pop() interface{} { + if len(s.contexts) == 0 { + return nil + } + last := s.contexts[len(s.contexts)-1] + s.contexts = s.contexts[:len(s.contexts)-1] + return last +} + +// findCtxByLabel returns the last context if the label is empty +// otherwise it returns the context that matches the label +// if it doesn't exist, it returns nil +func (s *staticAnalysis) findCtxByLabel(label string) interface{} { + if len(label) == 0 { + if len(s.contexts) > 0 { + return s.contexts[len(s.contexts)-1] + } + return nil + } + + for i := len(s.contexts) - 1; i >= 0; i-- { + if ctx, ok := s.contexts[i].(contextLabeler); ok && ctx.label() == label { + return s.contexts[i] + } + } + + return nil +} + +func (s *staticAnalysis) staticAnalysisBlockStmt(stmts []Stmt) bool { + if len(stmts) == 0 { + return false + } + return s.staticAnalysisStmt(stmts[len(stmts)-1]) +} + +func (s *staticAnalysis) staticAnalysisExpr(expr Expr) bool { + switch n := expr.(type) { + case *CallExpr: + for _, arg := range n.Args { + term := s.staticAnalysisExpr(arg) + if !term { + return false + } + } + case *FuncLitExpr: + s.push(&FuncLitContext{ + hasRet: false, + f: n, + }) + term := s.staticAnalysisBlockStmt(n.Body) + if !term { + ctx := s.pop().(*FuncLitContext) + s.errs = append(s.errs, fmt.Errorf("lambda at %v does not terminate", ctx.f.Loc)) + } + return false + case *NameExpr: + return false + } + return false +} + +// staticAnalysisStmt returns a boolean value, +// indicating whether a statement is terminating or not +func (s *staticAnalysis) staticAnalysisStmt(stmt Stmt) bool { + switch n := stmt.(type) { + case *BranchStmt: + switch n.Op { + case BREAK: + ctx := s.findCtxByLabel(string(n.Label)) + if ctx != nil { + if c, ok := ctx.(breakPusher); ok { + c.pushBreak(n) + } + } + case CONTINUE: + // + case DEFAULT: + // + case FALLTHROUGH: + return true + } + case *IfStmt: + terminates := s.staticAnalysisBlockStmt(n.Then.Body) + + var elseTerminates bool + if len(n.Else.Body) > 0 { + elseTerminates = s.staticAnalysisBlockStmt(n.Else.Body) + } + + return terminates && elseTerminates + case *ForStmt: + s.push(&ForContext{forstmt: n}) + _ = s.staticAnalysisBlockStmt(n.Body) + ctx := s.pop().(*ForContext) + // there are no "break" statements referring to the "for" statement + hasNoBreaks := len(ctx.breakstmts) == 0 + // the loop condition is absent + hasNoCond := n.Cond == nil + terminates := hasNoBreaks && hasNoCond + return terminates + case *ReturnStmt: + return true + case *AssignStmt: + for _, rh := range n.Rhs { + term := s.staticAnalysisExpr(rh) + if !term { + return false + } + } + return false + case *SwitchStmt: + // there is a default case, and + var hasDefault bool + for _, clause := range n.Clauses { + // nil case means default + if clause.Cases == nil { + hasDefault = true + break + } + } + s.push(&SwitchContext{switchStmt: n}) + + // the statement lists in each case, + // including the default + // end in a terminating statement, + // or a possibly labeled "fallthrough" statement. + casesTerm := true + for _, clause := range n.Clauses { + ct := s.staticAnalysisBlockStmt(clause.Body) + casesTerm = ct + } + ctx := s.pop().(*SwitchContext) + // there are no "break" statements referring to the "switch" statement + hasNoBreaks := len(ctx.breakstmts) == 0 + terminates := hasNoBreaks && hasDefault && casesTerm + return terminates + case *PanicStmt: + return true + } + return false +} + +type contextLabeler interface { + label() string +} + +type breakPusher interface { + pushBreak(breakstmt *BranchStmt) +} + +type FuncLitContext struct { + hasRet bool + f *FuncLitExpr +} + +type FuncDeclContext struct { + hasRet bool + f *FuncDecl +} + +type ForContext struct { + forstmt *ForStmt + breakstmts []*BranchStmt +} + +func (fc *ForContext) label() string { + return string(fc.forstmt.Label) +} + +func (fc *ForContext) pushBreak(breakstmt *BranchStmt) { + fc.breakstmts = append(fc.breakstmts, breakstmt) +} + +type SwitchContext struct { + switchStmt *SwitchStmt + breakstmts []*BranchStmt +} + +func (sc *SwitchContext) label() string { + return string(sc.switchStmt.Label) +} + +func (sc *SwitchContext) pushBreak(breakstmt *BranchStmt) { + sc.breakstmts = append(sc.breakstmts, breakstmt) +} diff --git a/gnovm/pkg/gnolang/static_analysis_test.go b/gnovm/pkg/gnolang/static_analysis_test.go new file mode 100644 index 00000000000..00c3d4febc6 --- /dev/null +++ b/gnovm/pkg/gnolang/static_analysis_test.go @@ -0,0 +1,417 @@ +package gnolang + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStaticAnalysisShouldPanic(t *testing.T) { + cases := []struct { + name string + code string + }{ + { + name: "Test Case 1", + code: `package test + func main() { + invalidSwitch() + } + func invalidSwitch() int { + mockVar := map[string]int{ + "apple": 10, + "banana": 20, + "orange": 30, + "mango": 5, + "watermelon": 15, + } + + for k, v := range mockVar { + switch k { + case "apple": + if v < 50 { + return v + } else { + return 50 + } + case "banana": + if v > 10 { + return v + } else { + return 10 + } + case "orange": + if v > 30 { + } else { + return 30 + } + case "mango": + if v == 5 { + return v + } else { + return 5 + } + case "watermelon": + if v == 15 { + return v + } else { + return 15 + } + default: + return 0 + } + } + } + `, + }, + { + name: "Test Case 2", + code: `package test + func main() { + + } + + func invalidLabel() int{ + Outer: + for { + for { + break Outer + } + } + } + `, + }, + { + name: "Test Case 3", + code: `package test + func main() { + oddOrEven(3) + } + + func oddOrEven(x int) bool { + for i := 0; i < x; i++ { + if x%2 == 0 { + + } else { + return false + } + } + } + `, + }, + { + name: "Test Case 4", + code: `package test + func main() { + sumArr([]int{1,1,1}) + } + + func sumArr(x []int) int { + sum := 0 + for _, s := range x { + sum = sum + s + } + } + `, + }, + { + name: "Test Case 5", + code: `package test + func main() { + invalidSwitch(3) + } + + func invalidSwitch(x int) int { + switch x { + case 1: + return 1 + case 2: + return 2 + } + } + `, + }, + { + name: "Test Case 6", + code: `package test + func main() { + invalidCompareBool(4,5) + } + + func invalidCompareBool(a, b int) bool { + if a > b { + return true + } else { + } + } + `, + }, + { + name: "Test Case 7", + code: `package test + func main() { + invalidIfStatement(6) + } + + func invalidIfStatement(x int) int { + if x > 5 { + + } else { + return x + } + } + `, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + testFunc := func() { + m := NewMachine("test", nil) + + n := MustParseFile("main.go", tc.code) + m.RunFiles(n) + m.RunMain() + } + + assert.Panics(t, testFunc, "The code did not panic") + }) + } +} + +func TestStaticAnalysisShouldPass(t *testing.T) { + testCases := []struct { + name string + code string + }{ + { + name: "Test Case 1", + code: `package test + func main() { + first := a() + } + + func a() int { + x := 9 + return 9 + } + `, + }, + { + name: "Test Case 2", + code: `package test + func main() { + validLabel() + } + + func validLabel() int{ + OuterLoop: + for i := 0; i < 10; i++ { + for j := 0; j < 10; j++ { + break OuterLoop + } + } + return 0 + } + `, + }, + { + name: "Test Case 3", + code: `package test + func main() { + fruitStall() + + } + + func fruitStall() int { + mockVar := map[string]int{ + "apple": 10, + "banana": 20, + "orange": 30, + "mango": 5, + "watermelon": 15, + } + + for k, v := range mockVar { + switch k { + case "apple": + if v < 50 { + return(v) + } else { + return(50) + } + case "banana": + if v > 10 { + return(v) + } else { + return(10) + } + case "orange": + if v > 30 { + return(v) + } else { + return(30) + } + case "mango": + if v == 5 { + return(v) + } else { + return(5) + } + case "watermelon": + if v == 15 { + return(v) + } else { + return(15) + } + default: + return 0 + } + } + return 0 + } + `, + }, + { + name: "Test Case 4", + code: ` + package test + func main() { + whichDay() + } + func whichDay() string{ + dayOfWeek := 3 + + switch dayOfWeek { + + case 1: + return "Sunday" + + case 2: + return "Monday" + + case 3: + return "Tuesday" + + case 4: + return "Wednesday" + + case 5: + return "Thursday" + + case 6: + return "Friday" + + case 7: + return "Saturday" + + default: + return "Invalid day" + } + return "Not a day" + } + + `, + }, + { + name: "Test Case 5", + code: `package test + func main() { + switchLabel() + } + + func switchLabel() int{ + SwitchStatement: + switch 1 { + case 1: + return 1 + for i := 0; i < 10; i++ { + break SwitchStatement + } + return 2 + } + return 3 + } + `, + }, + { + name: "Test Case 6", + code: ` + package test + func main() { + add(1,1) + } + func add(a, b int) int { + return a + b + }`, + }, + { + name: "Test Case 7", + code: `package test + func main() { + z := y() + } + + func y() int{ + x := 9 + return 9 + } + `, + }, + { + name: "Test Case 8", + code: `package test + func main() { + isEqual(2,2) + } + func isEqual(a, b int) bool { + if a == b { + return true + } + return false + } + `, + }, + { + name: "Test Case 9", + code: ` + package test + func main() { + f(2) + } + func f(a int) int { + switch a { + case 1: + return 1 + default: + return 0 + } + } + `, + }, + { + name: "Test Case 10", + code: ` + package test + func main() { + f(0) + } + func f(a int) int { + if a > 0 { + return 1 + } else { + return 0 + } + } + `, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + m := NewMachine("test", nil) + n := MustParseFile("main.go", tc.code) + m.RunFiles(n) + m.RunMain() + }) + } +} From 60c09b9ee6edb678018ad95b3ce64d2a8b09afea Mon Sep 17 00:00:00 2001 From: Leon Hudak <33522493+leohhhn@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:54:10 +0900 Subject: [PATCH 04/19] feat(gnoclient): add support for `MsgAddPackage` (#1892) ## Description This PR adds gnoclient support for `MsgAddPackage`, and updates the docs to match the functionality. Docs preview: https://www.loom.com/share/0dfa38e6e95e4e1195d686c8cbffa453?sid=4af29ee0-d065-442c-977e-ce9577796688 Closes #1840
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [x] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- docs/reference/gnoclient/client.md | 27 ++- gno.land/pkg/gnoclient/client_test.go | 191 +++++++++++++++++++++ gno.land/pkg/gnoclient/client_txs.go | 83 ++++++++- gno.land/pkg/gnoclient/integration_test.go | 175 +++++++++++++++++++ gno.land/pkg/gnoclient/util.go | 12 +- 5 files changed, 475 insertions(+), 13 deletions(-) diff --git a/docs/reference/gnoclient/client.md b/docs/reference/gnoclient/client.md index c4d9affffd5..3f258fa683e 100644 --- a/docs/reference/gnoclient/client.md +++ b/docs/reference/gnoclient/client.md @@ -17,7 +17,15 @@ type Client struct { } ``` -### func \(\*Client\) [Call]() +### func \(\*Client\) [AddPackage]() + +```go +func (c *Client) AddPackage(cfg BaseTxCfg, msgs ...MsgAddPackage) (*ctypes.ResultBroadcastTxCommit, error) +``` + +`AddPackage` executes one or more [AddPackage](#type-msgaddpackage) calls on the blockchain. + +### func \(\*Client\) [Call]() ```go func (c *Client) Call(cfg BaseTxCfg, msgs ...MsgCall) (*ctypes.ResultBroadcastTxCommit, error) @@ -25,7 +33,7 @@ func (c *Client) Call(cfg BaseTxCfg, msgs ...MsgCall) (*ctypes.ResultBroadcastTx `Call` executes a one or more [MsgCall](#type-msgcall) calls on the blockchain. -### func \(\*Client\) [Send]() +### func \(\*Client\) [Send]() ```go func (c *Client) Send(cfg BaseTxCfg, msgs ...MsgSend) (*ctypes.ResultBroadcastTxCommit, error) @@ -33,7 +41,7 @@ func (c *Client) Send(cfg BaseTxCfg, msgs ...MsgSend) (*ctypes.ResultBroadcastTx `Send` executes one or more [MsgSend](#type-msgsend) calls on the blockchain. -### func \(\*Client\) [Run]() +### func \(\*Client\) [Run]() ```go func (c *Client) Run(cfg BaseTxCfg, msgs ...MsgRun) (*ctypes.ResultBroadcastTxCommit, error) @@ -41,7 +49,7 @@ func (c *Client) Run(cfg BaseTxCfg, msgs ...MsgRun) (*ctypes.ResultBroadcastTxCo `Run` executes a one or more MsgRun calls on the blockchain. -### func \(*Client\) [QEval]() +### func \(\*Client\) [QEval]() ```go func (c *Client) QEval(pkgPath string, expression string) (string, *ctypes.ResultABCIQuery, error) @@ -101,6 +109,17 @@ type BaseTxCfg struct { } ``` +## type [MsgAddPackage]() + +`MsgAddPackage` \- syntax sugar for `vm.MsgAddPackage`. + +```go +type MsgAddPackage struct { + Package *std.MemPackage // Package to add + Deposit string // Coin deposit +} +``` + ## type [MsgCall]() `MsgCall` \- syntax sugar for `vm.MsgCall`. diff --git a/gno.land/pkg/gnoclient/client_test.go b/gno.land/pkg/gnoclient/client_test.go index 044919173e8..d68a209dd26 100644 --- a/gno.land/pkg/gnoclient/client_test.go +++ b/gno.land/pkg/gnoclient/client_test.go @@ -888,3 +888,194 @@ func TestRunErrors(t *testing.T) { }) } } + +// AddPackage tests +func TestAddPackageErrors(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + client Client + cfg BaseTxCfg + msgs []MsgAddPackage + expectedError error + }{ + { + name: "Invalid Signer", + client: Client{ + Signer: nil, + RPCClient: &mockRPCClient{}, + }, + cfg: BaseTxCfg{ + GasWanted: 100000, + GasFee: "10000ugnot", + AccountNumber: 1, + SequenceNumber: 1, + Memo: "Test memo", + }, + msgs: []MsgAddPackage{ + { + Package: &std.MemPackage{ + Name: "", + Path: "", + Files: []*std.MemFile{ + { + Name: "file1.gno", + Body: "", + }, + }, + }, + Deposit: "", + }, + }, + expectedError: ErrMissingSigner, + }, + { + name: "Invalid RPCClient", + client: Client{ + &mockSigner{}, + nil, + }, + cfg: BaseTxCfg{ + GasWanted: 100000, + GasFee: "10000ugnot", + AccountNumber: 1, + SequenceNumber: 1, + Memo: "Test memo", + }, + msgs: []MsgAddPackage{}, + expectedError: ErrMissingRPCClient, + }, + { + name: "Invalid Gas Fee", + client: Client{ + Signer: &mockSigner{}, + RPCClient: &mockRPCClient{}, + }, + cfg: BaseTxCfg{ + GasWanted: 100000, + GasFee: "", + AccountNumber: 1, + SequenceNumber: 1, + Memo: "Test memo", + }, + msgs: []MsgAddPackage{ + { + Package: &std.MemPackage{ + Name: "", + Path: "", + Files: []*std.MemFile{ + { + Name: "file1.gno", + Body: "", + }, + }, + }, + Deposit: "", + }, + }, + expectedError: ErrInvalidGasFee, + }, + { + name: "Negative Gas Wanted", + client: Client{ + Signer: &mockSigner{}, + RPCClient: &mockRPCClient{}, + }, + cfg: BaseTxCfg{ + GasWanted: -1, + GasFee: "10000ugnot", + AccountNumber: 1, + SequenceNumber: 1, + Memo: "Test memo", + }, + msgs: []MsgAddPackage{ + { + Package: &std.MemPackage{ + Name: "", + Path: "", + Files: []*std.MemFile{ + { + Name: "file1.gno", + Body: "", + }, + }, + }, + Deposit: "", + }, + }, + expectedError: ErrInvalidGasWanted, + }, + { + name: "0 Gas Wanted", + client: Client{ + Signer: &mockSigner{}, + RPCClient: &mockRPCClient{}, + }, + cfg: BaseTxCfg{ + GasWanted: 0, + GasFee: "10000ugnot", + AccountNumber: 1, + SequenceNumber: 1, + Memo: "Test memo", + }, + msgs: []MsgAddPackage{ + { + Package: &std.MemPackage{ + Name: "", + Path: "", + Files: []*std.MemFile{ + { + Name: "file1.gno", + Body: "", + }, + }, + }, + Deposit: "", + }, + }, + expectedError: ErrInvalidGasWanted, + }, + { + name: "Invalid Empty Package", + client: Client{ + Signer: &mockSigner{ + info: func() keys.Info { + return &mockKeysInfo{ + getAddress: func() crypto.Address { + adr, _ := crypto.AddressFromBech32("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") + return adr + }, + } + }, + }, + RPCClient: &mockRPCClient{}, + }, + cfg: BaseTxCfg{ + GasWanted: 100000, + GasFee: "10000ugnot", + AccountNumber: 1, + SequenceNumber: 1, + Memo: "Test memo", + }, + msgs: []MsgAddPackage{ + { + Package: nil, + Deposit: "", + }, + }, + expectedError: ErrEmptyPackage, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + res, err := tc.client.AddPackage(tc.cfg, tc.msgs...) + assert.Nil(t, res) + assert.ErrorIs(t, err, tc.expectedError) + }) + } +} diff --git a/gno.land/pkg/gnoclient/client_txs.go b/gno.land/pkg/gnoclient/client_txs.go index eda34c82b07..a61fa9a892d 100644 --- a/gno.land/pkg/gnoclient/client_txs.go +++ b/gno.land/pkg/gnoclient/client_txs.go @@ -23,7 +23,7 @@ var ( ErrInvalidSendAmount = errors.New("invalid send amount") ) -// BaseTxCfg defines the base transaction configuration, shared by all message types. +// BaseTxCfg defines the base transaction configuration, shared by all message types type BaseTxCfg struct { GasFee string // Gas fee GasWanted int64 // Gas wanted @@ -32,7 +32,7 @@ type BaseTxCfg struct { Memo string // Memo } -// MsgCall - syntax sugar for vm.MsgCall. +// MsgCall - syntax sugar for vm.MsgCall type MsgCall struct { PkgPath string // Package path FuncName string // Function name @@ -40,19 +40,25 @@ type MsgCall struct { Send string // Send amount } -// MsgSend - syntax sugar for bank.MsgSend. +// MsgSend - syntax sugar for bank.MsgSend type MsgSend struct { ToAddress crypto.Address // Send to address Send string // Send amount } -// MsgRun - syntax sugar for vm.MsgRun. +// MsgRun - syntax sugar for vm.MsgRun type MsgRun struct { Package *std.MemPackage // Package to run Send string // Send amount } -// Call executes a one or more MsgCall calls on the blockchain. +// MsgAddPackage - syntax sugar for vm.MsgAddPackage +type MsgAddPackage struct { + Package *std.MemPackage // Package to add + Deposit string // Coin deposit +} + +// Call executes one or more MsgCall calls on the blockchain func (c *Client) Call(cfg BaseTxCfg, msgs ...MsgCall) (*ctypes.ResultBroadcastTxCommit, error) { // Validate required client fields. if err := c.validateSigner(); err != nil { @@ -108,7 +114,7 @@ func (c *Client) Call(cfg BaseTxCfg, msgs ...MsgCall) (*ctypes.ResultBroadcastTx return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber) } -// Run executes a one or more MsgRun calls on the blockchain. +// Run executes one or more MsgRun calls on the blockchain func (c *Client) Run(cfg BaseTxCfg, msgs ...MsgRun) (*ctypes.ResultBroadcastTxCommit, error) { // Validate required client fields. if err := c.validateSigner(); err != nil { @@ -172,7 +178,7 @@ func (c *Client) Run(cfg BaseTxCfg, msgs ...MsgRun) (*ctypes.ResultBroadcastTxCo return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber) } -// Send executes one or more MsgSend calls on the blockchain. +// Send executes one or more MsgSend calls on the blockchain func (c *Client) Send(cfg BaseTxCfg, msgs ...MsgSend) (*ctypes.ResultBroadcastTxCommit, error) { // Validate required client fields. if err := c.validateSigner(); err != nil { @@ -226,7 +232,68 @@ func (c *Client) Send(cfg BaseTxCfg, msgs ...MsgSend) (*ctypes.ResultBroadcastTx return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber) } -// signAndBroadcastTxCommit signs a transaction and broadcasts it, returning the result. +// AddPackage executes one or more AddPackage calls on the blockchain +func (c *Client) AddPackage(cfg BaseTxCfg, msgs ...MsgAddPackage) (*ctypes.ResultBroadcastTxCommit, error) { + // Validate required client fields. + if err := c.validateSigner(); err != nil { + return nil, err + } + if err := c.validateRPCClient(); err != nil { + return nil, err + } + + // Validate base transaction config + if err := cfg.validateBaseTxConfig(); err != nil { + return nil, err + } + + // Parse MsgRun slice + vmMsgs := make([]std.Msg, 0, len(msgs)) + for _, msg := range msgs { + // Validate MsgCall fields + if err := msg.validateMsgAddPackage(); err != nil { + return nil, err + } + + // Parse deposit coins + deposit, err := std.ParseCoins(msg.Deposit) + if err != nil { + return nil, err + } + + caller := c.Signer.Info().GetAddress() + + // Transpile and validate Gno syntax + if err = transpiler.TranspileAndCheckMempkg(msg.Package); err != nil { + return nil, err + } + + // Unwrap syntax sugar to vm.MsgCall slice + vmMsgs = append(vmMsgs, std.Msg(vm.MsgAddPackage{ + Creator: caller, + Package: msg.Package, + Deposit: deposit, + })) + } + + // Parse gas fee + gasFeeCoins, err := std.ParseCoin(cfg.GasFee) + if err != nil { + return nil, err + } + + // Pack transaction + tx := std.Tx{ + Msgs: vmMsgs, + Fee: std.NewFee(cfg.GasWanted, gasFeeCoins), + Signatures: nil, + Memo: cfg.Memo, + } + + return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber) +} + +// signAndBroadcastTxCommit signs a transaction and broadcasts it, returning the result func (c *Client) signAndBroadcastTxCommit(tx std.Tx, accountNumber, sequenceNumber uint64) (*ctypes.ResultBroadcastTxCommit, error) { caller := c.Signer.Info().GetAddress() diff --git a/gno.land/pkg/gnoclient/integration_test.go b/gno.land/pkg/gnoclient/integration_test.go index 554cba8ecf2..3244b32af3f 100644 --- a/gno.land/pkg/gnoclient/integration_test.go +++ b/gno.land/pkg/gnoclient/integration_test.go @@ -3,6 +3,8 @@ package gnoclient import ( "testing" + "github.com/gnolang/gno/gnovm/pkg/gnolang" + "github.com/gnolang/gno/tm2/pkg/std" "github.com/gnolang/gno/gno.land/pkg/integration" @@ -351,6 +353,179 @@ func main() { assert.Equal(t, expected, string(res.DeliverTx.Data)) } +func TestAddPackageSingle_Integration(t *testing.T) { + // Set up in-memory node + config, _ := integration.TestingNodeConfig(t, gnoenv.RootDir()) + node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNoopLogger(), config) + defer node.Stop() + + // Init Signer & RPCClient + signer := newInMemorySigner(t, "tendermint_test") + rpcClient := rpcclient.NewHTTP(remoteAddr, "/websocket") + + // Setup Client + client := Client{ + Signer: signer, + RPCClient: rpcClient, + } + + // Make Tx config + baseCfg := BaseTxCfg{ + GasFee: "10000ugnot", + GasWanted: 8000000, + AccountNumber: 0, + SequenceNumber: 0, + Memo: "", + } + + body := `package echo + +func Echo(str string) string { + return str +}` + + fileName := "echo.gno" + deploymentPath := "gno.land/p/demo/integration/test/echo" + deposit := "100ugnot" + + // Make Msg config + msg := MsgAddPackage{ + Package: &std.MemPackage{ + Name: "echo", + Path: deploymentPath, + Files: []*std.MemFile{ + { + Name: fileName, + Body: body, + }, + }, + }, + Deposit: deposit, + } + + // Execute AddPackage + _, err := client.AddPackage(baseCfg, msg) + assert.Nil(t, err) + + // Check for deployed file on the node + query, err := client.Query(QueryCfg{ + Path: "vm/qfile", + Data: []byte(deploymentPath), + }) + require.NoError(t, err) + assert.Equal(t, string(query.Response.Data), fileName) + + // Query balance to validate deposit + baseAcc, _, err := client.QueryAccount(gnolang.DerivePkgAddr(deploymentPath)) + require.NoError(t, err) + assert.Equal(t, baseAcc.GetCoins().String(), deposit) +} + +func TestAddPackageMultiple_Integration(t *testing.T) { + // Set up in-memory node + config, _ := integration.TestingNodeConfig(t, gnoenv.RootDir()) + node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNoopLogger(), config) + defer node.Stop() + + // Init Signer & RPCClient + signer := newInMemorySigner(t, "tendermint_test") + rpcClient := rpcclient.NewHTTP(remoteAddr, "/websocket") + + // Setup Client + client := Client{ + Signer: signer, + RPCClient: rpcClient, + } + + // Make Tx config + baseCfg := BaseTxCfg{ + GasFee: "10000ugnot", + GasWanted: 8000000, + AccountNumber: 0, + SequenceNumber: 0, + Memo: "", + } + + deposit := "100ugnot" + deploymentPath1 := "gno.land/p/demo/integration/test/echo" + + body1 := `package echo + +func Echo(str string) string { + return str +}` + + deploymentPath2 := "gno.land/p/demo/integration/test/hello" + body2 := `package hello + +func Hello(str string) string { + return "Hello " + str + "!" +}` + + msg1 := MsgAddPackage{ + Package: &std.MemPackage{ + Name: "echo", + Path: deploymentPath1, + Files: []*std.MemFile{ + { + Name: "echo.gno", + Body: body1, + }, + }, + }, + Deposit: "", + } + + msg2 := MsgAddPackage{ + Package: &std.MemPackage{ + Name: "hello", + Path: deploymentPath2, + Files: []*std.MemFile{ + { + Name: "gno.mod", + Body: "module gno.land/p/demo/integration/test/hello", + }, + { + Name: "hello.gno", + Body: body2, + }, + }, + }, + Deposit: deposit, + } + + // Execute AddPackage + _, err := client.AddPackage(baseCfg, msg1, msg2) + assert.Nil(t, err) + + // Check Package #1 + query, err := client.Query(QueryCfg{ + Path: "vm/qfile", + Data: []byte(deploymentPath1), + }) + require.NoError(t, err) + assert.Equal(t, string(query.Response.Data), "echo.gno") + + // Query balance to validate deposit + baseAcc, _, err := client.QueryAccount(gnolang.DerivePkgAddr(deploymentPath1)) + require.NoError(t, err) + assert.Equal(t, baseAcc.GetCoins().String(), "") + + // Check Package #2 + query, err = client.Query(QueryCfg{ + Path: "vm/qfile", + Data: []byte(deploymentPath2), + }) + require.NoError(t, err) + assert.Contains(t, string(query.Response.Data), "hello.gno") + assert.Contains(t, string(query.Response.Data), "gno.mod") + + // Query balance to validate deposit + baseAcc, _, err = client.QueryAccount(gnolang.DerivePkgAddr(deploymentPath2)) + require.NoError(t, err) + assert.Equal(t, baseAcc.GetCoins().String(), deposit) +} + // todo add more integration tests: // MsgCall with Send field populated (single/multiple) // MsgRun with Send field populated (single/multiple) diff --git a/gno.land/pkg/gnoclient/util.go b/gno.land/pkg/gnoclient/util.go index 9860d567f1e..177e6d92906 100644 --- a/gno.land/pkg/gnoclient/util.go +++ b/gno.land/pkg/gnoclient/util.go @@ -20,6 +20,7 @@ func (msg MsgCall) validateMsgCall() error { if msg.FuncName == "" { return ErrEmptyFuncName } + return nil } @@ -31,13 +32,22 @@ func (msg MsgSend) validateMsgSend() error { if err != nil { return ErrInvalidSendAmount } + return nil } func (msg MsgRun) validateMsgRun() error { - // todo replace with msg.ValidateBasic() after PR #1646 is merged. if msg.Package == nil || len(msg.Package.Files) == 0 { return ErrEmptyPackage } + + return nil +} + +func (msg MsgAddPackage) validateMsgAddPackage() error { + if msg.Package == nil || len(msg.Package.Files) == 0 { + return ErrEmptyPackage + } + return nil } From 3b954861ad1c15a268304b6179e6e56bc74dae90 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Tue, 9 Apr 2024 13:56:28 +0200 Subject: [PATCH 05/19] fix: top sort var/const globals (#1854) This PR fixes [this](https://github.com/gnolang/gno/issues/1849) and [this](https://github.com/gnolang/gno/issues/1463). Before preprocessing, a dependency graph is created and edges between the nodes which represent the relationship between global `var` and `const` declarations. Then, a new slice of declarations is created that is topologically sorted. This enables the rest of the preprocessing code to work the way it is now. Small scale refactoring is included by removing unnecessary else statements in `PredefineFileSet`. --- gnovm/pkg/gnolang/nodes.go | 19 +- gnovm/pkg/gnolang/preprocess.go | 35 ++-- gnovm/pkg/gnolang/value_decl_dep_graph.go | 245 ++++++++++++++++++++++ gnovm/tests/files/var18.gno | 14 ++ gnovm/tests/files/var19.gno | 14 ++ gnovm/tests/files/var20.gno | 17 ++ gnovm/tests/files/var21.gno | 17 ++ 7 files changed, 341 insertions(+), 20 deletions(-) create mode 100644 gnovm/pkg/gnolang/value_decl_dep_graph.go create mode 100644 gnovm/tests/files/var18.gno create mode 100644 gnovm/tests/files/var19.gno create mode 100644 gnovm/tests/files/var20.gno create mode 100644 gnovm/tests/files/var21.gno diff --git a/gnovm/pkg/gnolang/nodes.go b/gnovm/pkg/gnolang/nodes.go index 8f2c5054a8a..5d430a8bcde 100644 --- a/gnovm/pkg/gnolang/nodes.go +++ b/gnovm/pkg/gnolang/nodes.go @@ -158,6 +158,23 @@ type Attributes struct { data map[interface{}]interface{} // not persisted } +func (attr *Attributes) Copy() Attributes { + if attr == nil { + return Attributes{} + } + + data := make(map[interface{}]interface{}) + for k, v := range attr.data { + data[k] = v + } + + return Attributes{ + Line: attr.Line, + Label: attr.Label, + data: data, + } +} + func (attr *Attributes) GetLine() int { return attr.Line } @@ -1614,7 +1631,7 @@ func (sb *StaticBlock) GetPathForName(store Store, n Name) ValuePath { bp = bp.GetParentNode(store) gen++ if 0xff < gen { - panic("value path depth overflow") + panic("GetPathForName: value path depth overflow") } } } diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index f98ed899cfc..fba01750a20 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -13,11 +13,21 @@ import ( // Anything predefined or preprocessed here get skipped during the Preprocess // phase. func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { + for _, fn := range fset.Files { + decls, err := sortValueDeps(fn.Decls) + if err != nil { + panic(err) + } + + fn.Decls = decls + } + // First, initialize all file nodes and connect to package node. for _, fn := range fset.Files { SetNodeLocations(pn.PkgPath, string(fn.Name), fn) fn.InitStaticBlock(fn, pn) } + // NOTE: much of what follows is duplicated for a single *FileNode // in the main Preprocess translation function. Keep synced. @@ -29,11 +39,7 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { d := fn.Decls[i] switch d.(type) { case *ImportDecl: - if d.GetAttribute(ATTR_PREDEFINED) == true { - // skip declarations already predefined - // (e.g. through recursion for a - // dependent) - } else { + if d.GetAttribute(ATTR_PREDEFINED) != true { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 @@ -41,17 +47,14 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { } } } + // Predefine all type decls decls. for _, fn := range fset.Files { for i := 0; i < len(fn.Decls); i++ { d := fn.Decls[i] switch d.(type) { case *TypeDecl: - if d.GetAttribute(ATTR_PREDEFINED) == true { - // skip declarations already predefined - // (e.g. through recursion for a - // dependent) - } else { + if d.GetAttribute(ATTR_PREDEFINED) != true { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 @@ -65,11 +68,7 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { d := fn.Decls[i] switch d.(type) { case *FuncDecl: - if d.GetAttribute(ATTR_PREDEFINED) == true { - // skip declarations already predefined - // (e.g. through recursion for a - // dependent) - } else { + if d.GetAttribute(ATTR_PREDEFINED) != true { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 @@ -77,15 +76,13 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { } } } + // Finally, predefine other decls and // preprocess ValueDecls.. for _, fn := range fset.Files { for i := 0; i < len(fn.Decls); i++ { d := fn.Decls[i] - if d.GetAttribute(ATTR_PREDEFINED) == true { - // skip declarations already predefined (e.g. - // through recursion for a dependent) - } else { + if d.GetAttribute(ATTR_PREDEFINED) != true { // recursively predefine dependencies. d2, _ := predefineNow(store, fn, d) fn.Decls[i] = d2 diff --git a/gnovm/pkg/gnolang/value_decl_dep_graph.go b/gnovm/pkg/gnolang/value_decl_dep_graph.go new file mode 100644 index 00000000000..fe130dbf43a --- /dev/null +++ b/gnovm/pkg/gnolang/value_decl_dep_graph.go @@ -0,0 +1,245 @@ +package gnolang + +import ( + "fmt" + "slices" + "strings" +) + +// sortValueDeps creates a new topologically sorted +// decl slice ready for processing in order +func sortValueDeps(decls Decls) (Decls, error) { + graph := &graph{ + edges: make(map[string][]string), + vertices: make([]string, 0), + } + + otherDecls := make(Decls, 0) + + for i := 0; i < len(decls); i++ { + d := decls[i] + vd, ok := d.(*ValueDecl) + + if !ok { + otherDecls = append(otherDecls, d) + continue + } + + if isTuple(vd) { + _, ok := vd.Values[0].(*CallExpr) + if ok { + graph.addVertex(vd.NameExprs.String()) + continue + } + } + + for j := 0; j < len(vd.NameExprs); j++ { + graph.addVertex(string(vd.NameExprs[j].Name)) + } + } + + for i := 0; i < len(decls); i++ { + d := decls[i] + vd, ok := d.(*ValueDecl) + + if !ok { + continue + } + + if isTuple(vd) { + ce, ok := vd.Values[0].(*CallExpr) + if ok { + addDepFromExpr(graph, vd.NameExprs.String(), ce) + continue + } + } + + for j := 0; j < len(vd.NameExprs); j++ { + if len(vd.Values) > j { + addDepFromExpr(graph, string(vd.NameExprs[j].Name), vd.Values[j]) + } + } + } + + sorted := make(Decls, 0) + + for _, node := range graph.topologicalSort() { + var dd Decl + + for _, decl := range decls { + vd, ok := decl.(*ValueDecl) + + if !ok { + continue + } + + if isCompoundNode(node) { + dd = processCompound(node, vd, decl) + break + } + + for i, nameExpr := range vd.NameExprs { + if string(nameExpr.Name) == node { + if len(vd.Values) > i { + dd = &ValueDecl{ + Attributes: vd.Attributes.Copy(), + NameExprs: []NameExpr{nameExpr}, + Type: vd.Type, + Values: []Expr{vd.Values[i]}, + Const: vd.Const, + } + break + } else { + dd = vd + break + } + } + } + } + + if dd == nil { + continue + } + + sorted = append(sorted, dd) + } + + slices.Reverse(sorted) + + otherDecls = append(otherDecls, sorted...) + + return otherDecls, nil +} + +func addDepFromExpr(dg *graph, fromNode string, expr Expr) { + switch e := expr.(type) { + case *FuncLitExpr: + for _, stmt := range e.Body { + addDepFromExprStmt(dg, fromNode, stmt) + } + case *CallExpr: + addDepFromExpr(dg, fromNode, e.Func) + + for _, arg := range e.Args { + addDepFromExpr(dg, fromNode, arg) + } + case *NameExpr: + if isUverseName(e.Name) { + break + } + + toNode := string(e.Name) + dg.addEdge(fromNode, toNode) + } +} + +func addDepFromExprStmt(dg *graph, fromNode string, stmt Stmt) { + switch e := stmt.(type) { + case *ExprStmt: + addDepFromExpr(dg, fromNode, e.X) + case *IfStmt: + addDepFromExprStmt(dg, fromNode, e.Init) + addDepFromExpr(dg, fromNode, e.Cond) + + for _, stm := range e.Then.Body { + addDepFromExprStmt(dg, fromNode, stm) + } + for _, stm := range e.Else.Body { + addDepFromExprStmt(dg, fromNode, stm) + } + case *ReturnStmt: + for _, stm := range e.Results { + addDepFromExpr(dg, fromNode, stm) + } + case *AssignStmt: + for _, stm := range e.Rhs { + addDepFromExpr(dg, fromNode, stm) + } + case *SwitchStmt: + addDepFromExpr(dg, fromNode, e.X) + for _, clause := range e.Clauses { + addDepFromExpr(dg, fromNode, clause.bodyStmt.Cond) + for _, s := range clause.bodyStmt.Body { + addDepFromExprStmt(dg, fromNode, s) + } + } + case *ForStmt: + addDepFromExpr(dg, fromNode, e.Cond) + for _, s := range e.bodyStmt.Body { + addDepFromExprStmt(dg, fromNode, s) + } + case *BlockStmt: + for _, s := range e.Block.bodyStmt.Body { + addDepFromExprStmt(dg, fromNode, s) + } + } +} + +type graph struct { + edges map[string][]string + vertices []string +} + +func (g *graph) addEdge(u, v string) { + g.edges[u] = append(g.edges[u], v) +} + +func (g *graph) addVertex(v string) { + g.vertices = append(g.vertices, v) +} + +func (g *graph) topologicalSortUtil(v string, visited map[string]bool, stack *[]string) { + visited[v] = true + + for _, u := range g.edges[v] { + if !visited[u] { + g.topologicalSortUtil(u, visited, stack) + } + } + + *stack = append([]string{v}, *stack...) +} + +func (g *graph) topologicalSort() []string { + stack := make([]string, 0) + visited := make(map[string]bool) + + for _, v := range g.vertices { + if !visited[v] { + g.topologicalSortUtil(v, visited, &stack) + } + } + + return stack +} + +func isTuple(vd *ValueDecl) bool { + return len(vd.NameExprs) > len(vd.Values) && len(vd.Values) > 0 +} + +func isCompoundNode(node string) bool { + return strings.Contains(node, ", ") +} + +func processCompound(node string, vd *ValueDecl, decl Decl) Decl { + names := strings.Split(node, ", ") + + if len(names) != len(vd.NameExprs) { + panic("should not happen") + } + + equal := true + + for i, name := range names { + if vd.NameExprs[i].String() != name { + equal = false + break + } + } + + if !equal { + panic(fmt.Sprintf("names: %+v != nameExprs: %+v\n", names, vd.NameExprs)) + } + + return decl +} diff --git a/gnovm/tests/files/var18.gno b/gnovm/tests/files/var18.gno new file mode 100644 index 00000000000..619aedef779 --- /dev/null +++ b/gnovm/tests/files/var18.gno @@ -0,0 +1,14 @@ +package main + +func main() { + println(a) + println(b) +} + +func r2() (int, int) { return 1, 2 } + +var a, b int = r2() + +// Output: +// 1 +// 2 diff --git a/gnovm/tests/files/var19.gno b/gnovm/tests/files/var19.gno new file mode 100644 index 00000000000..f26c230de0d --- /dev/null +++ b/gnovm/tests/files/var19.gno @@ -0,0 +1,14 @@ +package main + +func main() { + println(a) + println(b) + println(c) +} + +var a, b, c = 1, a + 1, b + 1 + +// Output: +// 1 +// 2 +// 3 diff --git a/gnovm/tests/files/var20.gno b/gnovm/tests/files/var20.gno new file mode 100644 index 00000000000..1aec4792fcb --- /dev/null +++ b/gnovm/tests/files/var20.gno @@ -0,0 +1,17 @@ +package main + +func main() { + println(a) + println(b) + println(c) + println(d) +} + +var a, b, c = 1, a + d, 3 +var d = a + +// Output: +// 1 +// 2 +// 3 +// 1 diff --git a/gnovm/tests/files/var21.gno b/gnovm/tests/files/var21.gno new file mode 100644 index 00000000000..7ec32e1ebfa --- /dev/null +++ b/gnovm/tests/files/var21.gno @@ -0,0 +1,17 @@ +package main + +func main() { + myDep = "123" + myVar() +} + +func hello(s string) { + println(s) +} + +var myVar = func() { hello(myDep) } + +var myDep string + +// Output: +// 123 From ae37e84606586613d7115eff6a871a898a0da0bb Mon Sep 17 00:00:00 2001 From: ltzmaxwell Date: Tue, 9 Apr 2024 19:58:51 +0800 Subject: [PATCH 06/19] fix: incorrect pointer value comparison (#1601) This is a fix to #1569 . Thanks to @thehowl for identifying this issue and providing a thorough and insightful analysis. Here is an further analysis based on #1569 : ```go package main func main() { { b := []byte("ABCDEFGHIJKL") a := b println(&a[0] == &a[0]) } } ``` this comparison would be false too. The root cause for this is the way pointer values is obtained and compared, e.g. ```go package main func main() { c := []byte{'A'} a := c println(&c[0]) println(&c[0] == &a[0]) } ``` in this code snippet, the address of the c[0], (&c[0]) is obtained from this: ```go ev := fillValueTV(store, &av.List[ii]) // by reference ``` that is a reference to the element of the underlying list of arrayValue, in case like this: ```go package main func main() { { b := []byte("ABCDEFGHIJKL") a := b println(&a[0] == &a[0]) } } ``` the address is obtained by ```go bv := &TypedValue{ // heap alloc, so need to compare value rather than pointer in isEql(), line 482 T: DataByteType, V: DataByteValue{ Base: av, Index: ii, ElemType: et, }, } ``` that is a new allocated *TV, which implies the value of it would not be same within the first and second & operation. So we should actually compare the concrete value rather than the pointers for this case. --- gnovm/pkg/gnolang/op_binary.go | 8 +++++++- gnovm/pkg/gnolang/values.go | 3 ++- gnovm/pkg/gnolang/values_string.go | 4 +++- gnovm/tests/files/a47.gno | 5 ++++- gnovm/tests/files/a47a.gno | 24 +++++++++++++++++++++++ gnovm/tests/files/a47b.gno | 13 +++++++++++++ gnovm/tests/files/a48.gno | 31 ++++++++++++++++++++++++++++++ gnovm/tests/files/a48a.gno | 12 ++++++++++++ gnovm/tests/files/a49.gno | 12 ++++++++++++ 9 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 gnovm/tests/files/a47a.gno create mode 100644 gnovm/tests/files/a47b.gno create mode 100644 gnovm/tests/files/a48.gno create mode 100644 gnovm/tests/files/a48a.gno create mode 100644 gnovm/tests/files/a49.gno diff --git a/gnovm/pkg/gnolang/op_binary.go b/gnovm/pkg/gnolang/op_binary.go index 9162a710d7d..99b56c18a06 100644 --- a/gnovm/pkg/gnolang/op_binary.go +++ b/gnovm/pkg/gnolang/op_binary.go @@ -475,7 +475,13 @@ func isEql(store Store, lv, rv *TypedValue) bool { rfv.GetClosure(store) } case PointerKind: - // TODO: assumes runtime instance normalization. + if lv.V != nil && rv.V != nil { + lpv := lv.V.(PointerValue) + rpv := rv.V.(PointerValue) + if lpv.TV.T == DataByteType && rpv.TV.T == DataByteType { + return *(lpv.TV) == *(rpv.TV) && lpv.Base == rpv.Base && lpv.Index == rpv.Index && lpv.Key == rpv.Key + } + } return lv.V == rv.V default: panic(fmt.Sprintf( diff --git a/gnovm/pkg/gnolang/values.go b/gnovm/pkg/gnolang/values.go index 85e6562eca6..ae5ac7fd40b 100644 --- a/gnovm/pkg/gnolang/values.go +++ b/gnovm/pkg/gnolang/values.go @@ -361,7 +361,7 @@ func (av *ArrayValue) GetPointerAtIndexInt2(store Store, ii int, et Type) Pointe Index: ii, } } - bv := &TypedValue{ // heap alloc + bv := &TypedValue{ // heap alloc, so need to compare value rather than pointer T: DataByteType, V: DataByteValue{ Base: av, @@ -369,6 +369,7 @@ func (av *ArrayValue) GetPointerAtIndexInt2(store Store, ii int, et Type) Pointe ElemType: et, }, } + return PointerValue{ TV: bv, Base: av, diff --git a/gnovm/pkg/gnolang/values_string.go b/gnovm/pkg/gnolang/values_string.go index 34187e32879..b334addc1c3 100644 --- a/gnovm/pkg/gnolang/values_string.go +++ b/gnovm/pkg/gnolang/values_string.go @@ -11,7 +11,7 @@ type protectedStringer interface { ProtectedString(*seenValues) string } -// This indicates the maximum ancticipated depth of the stack when printing a Value type. +// This indicates the maximum anticipated depth of the stack when printing a Value type. const defaultSeenValuesSize = 32 type seenValues struct { @@ -322,6 +322,8 @@ func (tv *TypedValue) ProtectedSprint(seen *seenValues, considerDeclaredType boo return fmt.Sprintf("%d", tv.GetUint()) case Uint8Type: return fmt.Sprintf("%d", tv.GetUint8()) + case DataByteType: + return fmt.Sprintf("%d", tv.GetDataByte()) case Uint16Type: return fmt.Sprintf("%d", tv.GetUint16()) case Uint32Type: diff --git a/gnovm/tests/files/a47.gno b/gnovm/tests/files/a47.gno index 2775547a3e8..1749968eac1 100644 --- a/gnovm/tests/files/a47.gno +++ b/gnovm/tests/files/a47.gno @@ -20,7 +20,9 @@ func main() { println(newArr[0].i, newArr[1].i) // The struct should have been copied, not referenced. - println(&sArr[2] != &newArr[1]) + println(&sArr[2] == &newArr[1]) + // share same underlying array, and same index + println(&sArr[1] == &newArr[1]) } // Output: @@ -29,4 +31,5 @@ func main() { // 2 3 3 // true // 2 3 +// false // true diff --git a/gnovm/tests/files/a47a.gno b/gnovm/tests/files/a47a.gno new file mode 100644 index 00000000000..a613482efda --- /dev/null +++ b/gnovm/tests/files/a47a.gno @@ -0,0 +1,24 @@ +package main + +type S struct { + i int +} + +func main() { + sArr := make([]S, 0, 4) + sArr = append(sArr, S{1}, S{2}, S{3}) + + newArr := append(sArr[:0], sArr[0:]...) + + // share same underlying array + println(&sArr[0] == &newArr[0]) + + println(&sArr[1] == &newArr[1]) + + println(&sArr[2] == &newArr[2]) +} + +// Output: +// true +// true +// true diff --git a/gnovm/tests/files/a47b.gno b/gnovm/tests/files/a47b.gno new file mode 100644 index 00000000000..89385a6f562 --- /dev/null +++ b/gnovm/tests/files/a47b.gno @@ -0,0 +1,13 @@ +package main + +func main() { + s1 := []int{1, 2} + i0 := &s1[0] + // new array allocated, so they have different base array + s1 = append(s1, 3) + ii0 := &s1[0] + println(i0 == ii0) +} + +// Output: +// false diff --git a/gnovm/tests/files/a48.gno b/gnovm/tests/files/a48.gno new file mode 100644 index 00000000000..be6e9c064ce --- /dev/null +++ b/gnovm/tests/files/a48.gno @@ -0,0 +1,31 @@ +package main + +func main() { + { + b := []byte("ABCDEFGHIJKL") + a := b + println(&b[0] == &a[0], b[0], a[0]) + + // modifying the underlying array modifies both a[0] and b[0], + // as it should + a[0] = 11 + println(a[0], b[0]) + } + + { + b := []byte{1, 2, 3} + a := b + println(&b[0] == &a[0], b[0], a[0]) + + // modifying the underlying array modifies both a[0] and b[0], + // as it should + a[0] = 11 + println(a[0], b[0]) + } +} + +// Output: +// true 65 65 +// 11 11 +// true 1 1 +// 11 11 diff --git a/gnovm/tests/files/a48a.gno b/gnovm/tests/files/a48a.gno new file mode 100644 index 00000000000..b17fdff515d --- /dev/null +++ b/gnovm/tests/files/a48a.gno @@ -0,0 +1,12 @@ +package main + +func main() { + { + b := []byte("ABCDEFGHIJKL") + a := b + println(&a[0] == &a[0]) + } +} + +// Output: +// true diff --git a/gnovm/tests/files/a49.gno b/gnovm/tests/files/a49.gno new file mode 100644 index 00000000000..ee39a484eb7 --- /dev/null +++ b/gnovm/tests/files/a49.gno @@ -0,0 +1,12 @@ +package main + +func main() { + c := []byte{'A'} + a := c + println(&c[0]) + println(&c[0] == &a[0]) +} + +// Output: +// &(65 uint8) +// true From 7286ca72312e9c0f500fb4347e2eaa4b46d0674b Mon Sep 17 00:00:00 2001 From: deelawn Date: Tue, 9 Apr 2024 20:02:47 +0100 Subject: [PATCH 07/19] feat: Add support for metrics collection (#1762) This PR introduces a package for instrumenting the code for metrics collection. The new README details the environment variables that need to be set and includes an example of how one might configure their local pipeline to export metrics to Grafana Cloud. I've added a few metrics in the `tm2` package; I _think_ they are in the correct spots. You may notice that the `metrics` subfolder in the `telemetry` package is unnecessarily modular. This is because this package originally include code for gathering traces as well. There is an existing issue with this and have decide to presently exclude it from this PR until it is fixed and/or requested -- this is a feature we would almost certainly not want to enable in a production environment. Metrics collection is more likely to be enabled in prod because they can be set to be exported to a local collector application that handles more complex batching, retry requests, and publishing to the end data store, in this case Grafana.
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [x] Provided any useful hints for running manual tests - [x] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- contribs/gnodev/go.mod | 19 ++++++++-- contribs/gnodev/go.sum | 49 ++++++++++++++++++------ contribs/gnokeykc/go.mod | 19 ++++++++-- contribs/gnokeykc/go.sum | 54 +++++++++++++++++++------- gno.land/cmd/gnoland/start.go | 24 ++++++++++++ go.mod | 22 +++++++++-- go.sum | 49 ++++++++++++++++++------ telemetry/README.md | 43 +++++++++++++++++++++ telemetry/exporter/error.go | 5 +++ telemetry/init.go | 40 ++++++++++++++++++++ telemetry/metrics/init.go | 69 ++++++++++++++++++++++++++++++++++ telemetry/options.go | 35 +++++++++++++++++ telemetry/options/config.go | 8 ++++ tm2/pkg/bft/consensus/state.go | 10 +++++ tm2/pkg/p2p/switch.go | 7 ++++ 15 files changed, 404 insertions(+), 49 deletions(-) create mode 100644 telemetry/README.md create mode 100644 telemetry/exporter/error.go create mode 100644 telemetry/init.go create mode 100644 telemetry/metrics/init.go create mode 100644 telemetry/options.go create mode 100644 telemetry/options/config.go diff --git a/contribs/gnodev/go.mod b/contribs/gnodev/go.mod index 4ec6a63d59c..2f74709f360 100644 --- a/contribs/gnodev/go.mod +++ b/contribs/gnodev/go.mod @@ -16,19 +16,22 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/sessions v1.2.1 // indirect github.com/gotuna/gotuna v0.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/jaekwon/testify v1.6.1 // indirect - github.com/kr/pretty v0.2.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/peterbourgon/ff/v3 v3.4.0 // indirect @@ -40,17 +43,25 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect + go.opentelemetry.io/otel v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 // indirect + go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/otel/sdk v1.25.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.25.0 // indirect + go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/proto/otlp v1.1.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/mod v0.16.0 // indirect - golang.org/x/net v0.22.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.19.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect - google.golang.org/grpc v1.58.3 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/grpc v1.63.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/contribs/gnodev/go.sum b/contribs/gnodev/go.sum index a20a723cc14..57943aa60ee 100644 --- a/contribs/gnodev/go.sum +++ b/contribs/gnodev/go.sum @@ -26,6 +26,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= @@ -49,6 +51,11 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 h1:GKvsK3oLWG9B1GL7WP/VqwM6C92j5tIvB844oggL9Lk= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:xJhtEL7ahjM1WJipt89gel8tHzfIl/LyMY+lCYh38d8= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -63,8 +70,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA= @@ -80,6 +87,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gotuna/gotuna v0.6.0 h1:N1lQKXEi/lwRp8u3sccTYLhzOffA4QasExz/1M5Riws= github.com/gotuna/gotuna v0.6.0/go.mod h1:F/ecRt29ChB6Ycy1AFIBpBiMNK0j7Heq+gFbLWquhjc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jaekwon/testify v1.6.1 h1:4AtAJcR9GzXN5W4DdY7ie74iCPiJV1JJUJL90t2ZUyw= github.com/jaekwon/testify v1.6.1/go.mod h1:Oun0RXIHI7osufabQ60i4Lqkj0GXLbqI1I7kgzBNm1U= @@ -89,10 +98,8 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= @@ -139,6 +146,20 @@ github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfU github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 h1:hDKnobznDpcdTlNzO0S/owRB8tyVr1OoeZZhDoqY+Cs= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0/go.mod h1:kUDQaUs1h8iTIHbQTk+iJRiUvSfJYMMKTtMCaiVu7B0= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= +go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= +go.opentelemetry.io/otel/sdk/metric v1.25.0 h1:7CiHOy08LbrxMAp4vWpbiPcklunUshVpAvGBrdDRlGw= +go.opentelemetry.io/otel/sdk/metric v1.25.0/go.mod h1:LzwoKptdbBBdYfvtGCzGwk6GWMA3aUzBOwtQpR6Nz7o= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= +go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -161,8 +182,8 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -188,10 +209,14 @@ golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= +google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/contribs/gnokeykc/go.mod b/contribs/gnokeykc/go.mod index 66a3c750633..b66d9ddd0b5 100644 --- a/contribs/gnokeykc/go.mod +++ b/contribs/gnokeykc/go.mod @@ -13,17 +13,20 @@ require ( github.com/alessio/shellescape v1.4.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gorilla/websocket v1.5.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/jaekwon/testify v1.6.1 // indirect - github.com/kr/pretty v0.1.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/peterbourgon/ff/v3 v3.4.0 // indirect @@ -33,15 +36,23 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect + go.opentelemetry.io/otel v1.25.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 // indirect + go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/otel/sdk v1.25.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.25.0 // indirect + go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/proto/otlp v1.1.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/mod v0.16.0 // indirect - golang.org/x/net v0.22.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect - google.golang.org/grpc v1.58.3 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/grpc v1.63.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/contribs/gnokeykc/go.sum b/contribs/gnokeykc/go.sum index 1bc8ea08a57..3eb03548817 100644 --- a/contribs/gnokeykc/go.sum +++ b/contribs/gnokeykc/go.sum @@ -28,6 +28,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= @@ -50,6 +52,11 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 h1:GKvsK3oLWG9B1GL7WP/VqwM6C92j5tIvB844oggL9Lk= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:xJhtEL7ahjM1WJipt89gel8tHzfIl/LyMY+lCYh38d8= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -66,13 +73,15 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jaekwon/testify v1.6.1 h1:4AtAJcR9GzXN5W4DdY7ie74iCPiJV1JJUJL90t2ZUyw= github.com/jaekwon/testify v1.6.1/go.mod h1:Oun0RXIHI7osufabQ60i4Lqkj0GXLbqI1I7kgzBNm1U= @@ -82,11 +91,10 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/linxGnu/grocksdb v1.6.20 h1:C0SNv12/OBr/zOdGw6reXS+mKpIdQGb/AkZWjHYnO64= @@ -112,6 +120,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -131,6 +141,20 @@ github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfU github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 h1:hDKnobznDpcdTlNzO0S/owRB8tyVr1OoeZZhDoqY+Cs= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0/go.mod h1:kUDQaUs1h8iTIHbQTk+iJRiUvSfJYMMKTtMCaiVu7B0= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= +go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= +go.opentelemetry.io/otel/sdk/metric v1.25.0 h1:7CiHOy08LbrxMAp4vWpbiPcklunUshVpAvGBrdDRlGw= +go.opentelemetry.io/otel/sdk/metric v1.25.0/go.mod h1:LzwoKptdbBBdYfvtGCzGwk6GWMA3aUzBOwtQpR6Nz7o= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= +go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -145,8 +169,8 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -170,10 +194,14 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= +google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 2b1757706f8..921fcc89640 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -5,6 +5,7 @@ import ( "errors" "flag" "fmt" + "os" "path/filepath" "strings" "time" @@ -12,6 +13,7 @@ import ( "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/gno.land/pkg/log" "github.com/gnolang/gno/gnovm/pkg/gnoenv" + "github.com/gnolang/gno/telemetry" abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" "github.com/gnolang/gno/tm2/pkg/bft/config" "github.com/gnolang/gno/tm2/pkg/bft/node" @@ -200,6 +202,12 @@ func execStart(c *startCfg, io commands.IO) error { loadCfgErr error ) + // Attempt to initialize telemetry. If the environment variables required to initialize + // telemetry are not set, then the initialization will do nothing. + if err := initTelemetry(); err != nil { + return fmt.Errorf("error initializing telemetry: %w", err) + } + // Set the node configuration if c.nodeConfigPath != "" { // Load the node configuration @@ -372,3 +380,19 @@ func getTxEventStoreConfig(c *startCfg) (*eventstorecfg.Config, error) { return cfg, nil } + +func initTelemetry() error { + var options []telemetry.Option + + if os.Getenv("TELEM_METRICS_ENABLED") == "true" { + options = append(options, telemetry.WithOptionMetricsEnabled()) + } + + // The string options can be added by default. Their absence would yield the same result + // as if the option were excluded altogether. + options = append(options, telemetry.WithOptionMeterName(os.Getenv("TELEM_METER_NAME"))) + options = append(options, telemetry.WithOptionExporterEndpoint(os.Getenv("TELEM_EXPORTER_ENDPOINT"))) + options = append(options, telemetry.WithOptionServiceName(os.Getenv("TELEM_SERVICE_NAME"))) + + return telemetry.Init(options...) +} diff --git a/go.mod b/go.mod index c6983d10b4f..cdbd51d67da 100644 --- a/go.mod +++ b/go.mod @@ -31,13 +31,18 @@ require ( github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 go.etcd.io/bbolt v1.3.9 + go.opentelemetry.io/otel v1.25.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 + go.opentelemetry.io/otel/metric v1.25.0 + go.opentelemetry.io/otel/sdk v1.25.0 + go.opentelemetry.io/otel/sdk/metric v1.25.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 go.uber.org/zap/exp v0.2.0 golang.org/x/crypto v0.21.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/mod v0.16.0 - golang.org/x/net v0.22.0 + golang.org/x/net v0.23.0 golang.org/x/term v0.18.0 golang.org/x/time v0.5.0 golang.org/x/tools v0.19.0 @@ -45,6 +50,16 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/proto/otlp v1.1.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect +) + require ( github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/gdamore/encoding v1.0.0 // indirect @@ -61,7 +76,6 @@ require ( golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect - google.golang.org/grpc v1.58.3 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/grpc v1.63.0 // indirect ) diff --git a/go.sum b/go.sum index b71747f5d32..12bad5b3d35 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= @@ -63,6 +65,11 @@ github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 h1:GKvsK3oLWG9B1G github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:xJhtEL7ahjM1WJipt89gel8tHzfIl/LyMY+lCYh38d8= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -77,8 +84,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA= @@ -94,6 +101,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gotuna/gotuna v0.6.0 h1:N1lQKXEi/lwRp8u3sccTYLhzOffA4QasExz/1M5Riws= github.com/gotuna/gotuna v0.6.0/go.mod h1:F/ecRt29ChB6Ycy1AFIBpBiMNK0j7Heq+gFbLWquhjc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jaekwon/testify v1.6.1 h1:4AtAJcR9GzXN5W4DdY7ie74iCPiJV1JJUJL90t2ZUyw= github.com/jaekwon/testify v1.6.1/go.mod h1:Oun0RXIHI7osufabQ60i4Lqkj0GXLbqI1I7kgzBNm1U= @@ -103,10 +112,8 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= @@ -162,6 +169,20 @@ github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfU github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 h1:hDKnobznDpcdTlNzO0S/owRB8tyVr1OoeZZhDoqY+Cs= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0/go.mod h1:kUDQaUs1h8iTIHbQTk+iJRiUvSfJYMMKTtMCaiVu7B0= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= +go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= +go.opentelemetry.io/otel/sdk/metric v1.25.0 h1:7CiHOy08LbrxMAp4vWpbiPcklunUshVpAvGBrdDRlGw= +go.opentelemetry.io/otel/sdk/metric v1.25.0/go.mod h1:LzwoKptdbBBdYfvtGCzGwk6GWMA3aUzBOwtQpR6Nz7o= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= +go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -191,8 +212,8 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -242,10 +263,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= +google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/telemetry/README.md b/telemetry/README.md new file mode 100644 index 00000000000..f0cbf26c5e4 --- /dev/null +++ b/telemetry/README.md @@ -0,0 +1,43 @@ +# Telemetry + +The purpose of this package is to provide a way to easily integrate OpenTelemetry Protocol (OTLP) metrics collection into our codebase. + +## Configure environment variables +Metrics can be enabled using environment variables. The following variables are supported: +- `TELEM_METRICS_ENABLED`: setting to `true` will enable metrics collection +- `TELEM_METER_NAME`: optionally set the meter name; the default is `gno.land` +- `TELEM_SERVICE_NAME`: optionally set the service name; the default is `gno.land` +- `TELEM_EXPORTER_ENDPOINT`: required; this is the endpoint to export metrics to, like a local OTEL collector + +## OTEL configuration +There are many ways configure the OTEL pipeline for exporting metrics. Here is an example of how a local OTEL collector can be configured to send metrics to Grafana Cloud. This is an optional step and can be highly customized. + +### OTEL collector +The latest collector releases can be found [here](https://github.com/open-telemetry/opentelemetry-collector-releases/releases). This is an example of the config that can be used to receive metrics from gno.land and publish them to Grafana Cloud. +```yaml +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 # should be the same as the TELEM_EXPORTER_ENDPOINT variable + +processors: + batch: + +exporters: + otlphttp: + endpoint: https://otlp-gateway-prod-us-east-0.grafana.net/otlp + +service: + pipelines: + metrics: + receivers: [otlp] + processors: [batch] + exporters: [otlphttp] +``` + +Collector exporter environment variables, including those for authentication, can be found [here](https://opentelemetry.io/docs/specs/otel/protocol/exporter/). + +## Resources +- https://opentelemetry.io/docs/collector/ +- https://grafana.com/docs/grafana-cloud/monitor-applications/application-observability/setup/collector/ \ No newline at end of file diff --git a/telemetry/exporter/error.go b/telemetry/exporter/error.go new file mode 100644 index 00000000000..5df14f0dba3 --- /dev/null +++ b/telemetry/exporter/error.go @@ -0,0 +1,5 @@ +package exporter + +import "errors" + +var ErrEndpointNotSet = errors.New("telemetry exporter endpoint not set") diff --git a/telemetry/init.go b/telemetry/init.go new file mode 100644 index 00000000000..30ea3ede66f --- /dev/null +++ b/telemetry/init.go @@ -0,0 +1,40 @@ +package telemetry + +// Inspired by the example here: +// https://github.com/open-telemetry/opentelemetry-go/blob/main/example/prometheus/main.go + +import ( + "github.com/gnolang/gno/telemetry/metrics" + "github.com/gnolang/gno/telemetry/options" +) + +const ( + defaultMeterName = "gno.land" + defaultServiceName = "gno.land" +) + +var config options.Config + +// MetricsEnabled returns true if metrics have been initialized. +func MetricsEnabled() bool { + return config.MetricsEnabled +} + +// Init will initialize metrics with the options provided. This function may also initialize tracing when +// this is something that we want to support. +func Init(options ...Option) error { + config.MeterName = defaultMeterName + config.ServiceName = defaultServiceName + for _, opt := range options { + opt(&config) + } + + // Initialize metrics to be collected. + if config.MetricsEnabled { + if err := metrics.Init(config); err != nil { + return err + } + } + + return nil +} diff --git a/telemetry/metrics/init.go b/telemetry/metrics/init.go new file mode 100644 index 00000000000..41903f88d77 --- /dev/null +++ b/telemetry/metrics/init.go @@ -0,0 +1,69 @@ +package metrics + +import ( + "context" + + "github.com/gnolang/gno/telemetry/exporter" + "github.com/gnolang/gno/telemetry/options" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + "go.opentelemetry.io/otel/metric" + sdkMetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" +) + +var ( + // Metrics. + BroadcastTxTimer metric.Int64Histogram + BuildBlockTimer metric.Int64Histogram +) + +func Init(config options.Config) error { + if config.ExporterEndpoint == "" { + return exporter.ErrEndpointNotSet + } + + // Use oltp metric exporter. + exporter, err := otlpmetricgrpc.New( + context.Background(), + otlpmetricgrpc.WithEndpoint(config.ExporterEndpoint), + otlpmetricgrpc.WithInsecure(), // TODO: enable security + ) + if err != nil { + return err + } + + provider := sdkMetric.NewMeterProvider( + // Default period is 1m. + sdkMetric.WithReader(sdkMetric.NewPeriodicReader(exporter)), + sdkMetric.WithResource( + resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String(config.ServiceName), + semconv.ServiceVersionKey.String("1.0.0"), + semconv.ServiceInstanceIDKey.String("gno-node-1"), + ), + ), + ) + otel.SetMeterProvider(provider) + meter := provider.Meter(config.MeterName) + + if BroadcastTxTimer, err = meter.Int64Histogram( + "broadcast_tx_hist", + metric.WithDescription("broadcast tx duration"), + metric.WithUnit("ms"), + ); err != nil { + return err + } + + if BuildBlockTimer, err = meter.Int64Histogram( + "build_block_hist", + metric.WithDescription("block build duration"), + metric.WithUnit("ms"), + ); err != nil { + return err + } + + return nil +} diff --git a/telemetry/options.go b/telemetry/options.go new file mode 100644 index 00000000000..1d299261caf --- /dev/null +++ b/telemetry/options.go @@ -0,0 +1,35 @@ +package telemetry + +import "github.com/gnolang/gno/telemetry/options" + +type Option func(*options.Config) + +func WithOptionMetricsEnabled() Option { + return func(c *options.Config) { + c.MetricsEnabled = true + } +} + +func WithOptionMeterName(meterName string) Option { + return func(c *options.Config) { + if meterName != "" { + c.MeterName = meterName + } + } +} + +func WithOptionExporterEndpoint(exporterEndpoint string) Option { + return func(c *options.Config) { + if exporterEndpoint != "" { + c.ExporterEndpoint = exporterEndpoint + } + } +} + +func WithOptionServiceName(serviceName string) Option { + return func(c *options.Config) { + if serviceName != "" { + c.ServiceName = serviceName + } + } +} diff --git a/telemetry/options/config.go b/telemetry/options/config.go new file mode 100644 index 00000000000..80d07e588aa --- /dev/null +++ b/telemetry/options/config.go @@ -0,0 +1,8 @@ +package options + +type Config struct { + MetricsEnabled bool + MeterName string + ServiceName string + ExporterEndpoint string +} diff --git a/tm2/pkg/bft/consensus/state.go b/tm2/pkg/bft/consensus/state.go index fcacb57e229..4e64418f6ac 100644 --- a/tm2/pkg/bft/consensus/state.go +++ b/tm2/pkg/bft/consensus/state.go @@ -2,6 +2,7 @@ package consensus import ( "bytes" + "context" goerrors "errors" "fmt" "log/slog" @@ -10,6 +11,8 @@ import ( "sync" "time" + "github.com/gnolang/gno/telemetry" + "github.com/gnolang/gno/telemetry/metrics" "github.com/gnolang/gno/tm2/pkg/amino" cnscfg "github.com/gnolang/gno/tm2/pkg/bft/consensus/config" cstypes "github.com/gnolang/gno/tm2/pkg/bft/consensus/types" @@ -987,6 +990,13 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts return } + if telemetry.MetricsEnabled() { + startTime := time.Now() + defer func(t time.Time) { + metrics.BuildBlockTimer.Record(context.Background(), time.Since(t).Milliseconds()) + }(startTime) + } + proposerAddr := cs.privValidator.GetPubKey().Address() return cs.blockExec.CreateProposalBlock(cs.Height, cs.state, commit, proposerAddr) } diff --git a/tm2/pkg/p2p/switch.go b/tm2/pkg/p2p/switch.go index 368de659fb1..9d013b42ad1 100644 --- a/tm2/pkg/p2p/switch.go +++ b/tm2/pkg/p2p/switch.go @@ -1,11 +1,14 @@ package p2p import ( + "context" "fmt" "math" "sync" "time" + "github.com/gnolang/gno/telemetry" + "github.com/gnolang/gno/telemetry/metrics" "github.com/gnolang/gno/tm2/pkg/cmap" "github.com/gnolang/gno/tm2/pkg/errors" "github.com/gnolang/gno/tm2/pkg/p2p/config" @@ -242,6 +245,7 @@ func (sw *Switch) OnStop() { // // NOTE: Broadcast uses goroutines, so order of broadcast may not be preserved. func (sw *Switch) Broadcast(chID byte, msgBytes []byte) chan bool { + startTime := time.Now() sw.Logger.Debug("Broadcast", "channel", chID, "msgBytes", fmt.Sprintf("%X", msgBytes)) peers := sw.peers.List() @@ -260,6 +264,9 @@ func (sw *Switch) Broadcast(chID byte, msgBytes []byte) chan bool { go func() { wg.Wait() close(successChan) + if telemetry.MetricsEnabled() { + metrics.BroadcastTxTimer.Record(context.Background(), time.Since(startTime).Milliseconds()) + } }() return successChan From 2a9a8f5fd72aae66a1f694066ac2250e001fde84 Mon Sep 17 00:00:00 2001 From: Albert Le Batteux Date: Wed, 10 Apr 2024 10:14:14 +0100 Subject: [PATCH 08/19] chore(misc/autocounterd): init autocounterd (#1612) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A demo is currently running on the portal loop you can check https://portal.gnoteam.com/r/portal/counter close: https://github.com/gnolang/gno/issues/1443
Contributors' checklist... - [ ] Added new tests, or not needed, or not feasible - [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Co-authored-by: Miloš Živković Co-authored-by: Hariom Verma --- .github/workflows/autocounterd.yml | 47 +++ misc/autocounterd/Dockerfile | 16 + misc/autocounterd/README.md | 13 + misc/autocounterd/cmd/cmd_start.go | 100 ++++++ misc/autocounterd/cmd/main.go | 14 + misc/autocounterd/docker-compose.yml | 13 + misc/autocounterd/go.mod | 52 +++ misc/autocounterd/go.sum | 314 ++++++++++++++++++ .../r/autocounterd/autocounder.gno | 17 + 9 files changed, 586 insertions(+) create mode 100644 .github/workflows/autocounterd.yml create mode 100644 misc/autocounterd/Dockerfile create mode 100644 misc/autocounterd/README.md create mode 100644 misc/autocounterd/cmd/cmd_start.go create mode 100644 misc/autocounterd/cmd/main.go create mode 100644 misc/autocounterd/docker-compose.yml create mode 100644 misc/autocounterd/go.mod create mode 100644 misc/autocounterd/go.sum create mode 100644 misc/autocounterd/r/autocounterd/autocounder.gno diff --git a/.github/workflows/autocounterd.yml b/.github/workflows/autocounterd.yml new file mode 100644 index 00000000000..3c1812a3ba1 --- /dev/null +++ b/.github/workflows/autocounterd.yml @@ -0,0 +1,47 @@ +name: autocounterd + +on: + push: + paths: + - misc/autocounterd + - .github/workflows/autocounterd.yml + branches: + - "master" + - "misc/autocounterd" + tags: + - "v*" + +permissions: + contents: read + packages: write + +jobs: + autocounterd: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker metadata autcounterd + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }}/autcounterd + tags: | + type=raw,value=latest + type=semver,pattern=v{{version}} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + context: ./misc/autocounterd + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/misc/autocounterd/Dockerfile b/misc/autocounterd/Dockerfile new file mode 100644 index 00000000000..d860fc5f37f --- /dev/null +++ b/misc/autocounterd/Dockerfile @@ -0,0 +1,16 @@ +FROM golang:alpine AS builder + +COPY . /go/src/github.com/gnolang/gno/misc/autocounterd + +WORKDIR /go/src/github.com/gnolang/gno/misc/autocounterd + +RUN go build -o /build/autocounterd ./cmd + +# Final image for autocounterd +FROM alpine AS autocounterd + +COPY --from=builder /build/autocounterd /usr/bin/autocounterd + +ENTRYPOINT [ "/usr/bin/autocounterd" ] +CMD [ "start" ] + diff --git a/misc/autocounterd/README.md b/misc/autocounterd/README.md new file mode 100644 index 00000000000..28b44312f25 --- /dev/null +++ b/misc/autocounterd/README.md @@ -0,0 +1,13 @@ +# Autocounterd + +## What is it? + +`autcounterd` is a simple binary that increments a simple counter every x seconds to analyse and test a network. + +## How to use + +Start it with: + +``` sh +$ docker compose up -d +``` diff --git a/misc/autocounterd/cmd/cmd_start.go b/misc/autocounterd/cmd/cmd_start.go new file mode 100644 index 00000000000..2e120b1c86d --- /dev/null +++ b/misc/autocounterd/cmd/cmd_start.go @@ -0,0 +1,100 @@ +package main + +import ( + "context" + "flag" + "fmt" + "time" + + "github.com/gnolang/gno/gno.land/pkg/gnoclient" + rpcclient "github.com/gnolang/gno/tm2/pkg/bft/rpc/client" + "github.com/gnolang/gno/tm2/pkg/commands" +) + +type startCfg struct { + rpcURL string + chainID string + mnemonic string + realmPath string + incrementInterval time.Duration +} + +func (cfg *startCfg) Validate() error { + switch { + case cfg.rpcURL == "": + return fmt.Errorf("rpc url cannot be empty") + case cfg.chainID == "": + return fmt.Errorf("chainID cannot be empty") + case cfg.mnemonic == "": + return fmt.Errorf("mnemonic cannot be empty") + case cfg.realmPath == "": + return fmt.Errorf("realmPath cannot be empty") + case cfg.incrementInterval == 0: + return fmt.Errorf("interval cannot be empty") + } + + return nil +} + +func NewStartCmd(io commands.IO) *commands.Command { + cfg := &startCfg{} + + return commands.NewCommand( + commands.Metadata{ + Name: "start", + ShortUsage: "start [flags]", + ShortHelp: "Runs the linter for the specified packages", + }, + cfg, + func(_ context.Context, args []string) error { + return execStart(cfg, args, io) + }, + ) +} + +func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { + fs.StringVar(&c.rpcURL, "rpc", "127.0.0.1:26657", "rpc url endpoint") + fs.StringVar(&c.chainID, "chain-id", "dev", "chain-id") + fs.StringVar(&c.mnemonic, "mnemonic", "", "mnemonic") + fs.StringVar(&c.realmPath, "realm", "gno.land/r/portal/counter", "realm path") + fs.DurationVar(&c.incrementInterval, "interval", 15*time.Second, "Increment counter interval") +} + +func execStart(cfg *startCfg, args []string, io commands.IO) error { + if err := cfg.Validate(); err != nil { + return err + } + + signer, err := gnoclient.SignerFromBip39(cfg.mnemonic, cfg.chainID, "", uint32(0), uint32(0)) + if err != nil { + return err + } + if err := signer.Validate(); err != nil { + return err + } + + rpcClient := rpcclient.NewHTTP(cfg.rpcURL, "/websocket") + + client := gnoclient.Client{ + Signer: signer, + RPCClient: rpcClient, + } + + for { + res, err := client.Call(gnoclient.CallCfg{ + PkgPath: cfg.realmPath, + FuncName: "Incr", + GasFee: "10000000ugnot", + GasWanted: 800000, + Args: nil, + }) + _ = res + + if err != nil { + fmt.Printf("[ERROR] Failed to call Incr on %s, %+v\n", cfg.realmPath, err.Error()) + } else { + fmt.Println("[INFO] Counter incremented with success") + } + time.Sleep(cfg.incrementInterval) + } +} diff --git a/misc/autocounterd/cmd/main.go b/misc/autocounterd/cmd/main.go new file mode 100644 index 00000000000..74c78ff8fdd --- /dev/null +++ b/misc/autocounterd/cmd/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "context" + "os" + + "github.com/gnolang/gno/tm2/pkg/commands" +) + +func main() { + cmd := NewStartCmd(commands.NewDefaultIO()) + + cmd.Execute(context.Background(), os.Args[1:]) +} diff --git a/misc/autocounterd/docker-compose.yml b/misc/autocounterd/docker-compose.yml new file mode 100644 index 00000000000..d71e6997b51 --- /dev/null +++ b/misc/autocounterd/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3" +services: + autocounterd: + image: ghcr.io/gnolang/gno/autocounterd + build: + context: . + restart: unless-stopped + environment: + COUNTER_MNEMONIC: "source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast" + COUNTER_RPC: "http://127.0.0.1:26657" + COUNTER_CHAIN_ID: "dev" + COUNTER_INTERVAL: "5s" + COUNTER_REALM: "gno.land/r/portal/counter" diff --git a/misc/autocounterd/go.mod b/misc/autocounterd/go.mod new file mode 100644 index 00000000000..d9d26eab37a --- /dev/null +++ b/misc/autocounterd/go.mod @@ -0,0 +1,52 @@ +module loop + +go 1.21 + +require github.com/gnolang/gno v0.0.0-20240125181217-b6193518e278 + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcutil v1.1.3 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/cockroachdb/apd/v3 v3.2.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/dgraph-io/badger/v3 v3.2103.5 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/gnolang/goleveldb v0.0.9 // indirect + github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/flatbuffers v1.12.1 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/jaekwon/testify v1.6.1 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/klauspost/compress v1.12.3 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/linxGnu/grocksdb v1.8.11 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/peterbourgon/ff/v3 v3.4.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rs/cors v1.10.1 // indirect + github.com/stretchr/testify v1.8.4 // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect + go.etcd.io/bbolt v1.3.8 // indirect + go.opencensus.io v0.22.5 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect + golang.org/x/tools v0.17.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/misc/autocounterd/go.sum b/misc/autocounterd/go.sum new file mode 100644 index 00000000000..905c884857e --- /dev/null +++ b/misc/autocounterd/go.sum @@ -0,0 +1,314 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.0 h1:V2/ZgjfDFIygAX3ZapeigkVBoVUtOJKSwrhZdlpSvaA= +github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= +github.com/btcsuite/btcd/btcutil v1.1.3/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= +github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= +github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gnolang/gno v0.0.0-20240125181217-b6193518e278 h1:CxF7gG3iqSeYVygTSYsB7Beg+Fpvka06TuTI2a0p+6s= +github.com/gnolang/gno v0.0.0-20240125181217-b6193518e278/go.mod h1:mOhpUTFaKk5CQj90qmjWfI9po2eapqziEu4D+fAtisc= +github.com/gnolang/goleveldb v0.0.9 h1:Q7rGko9oXMKtQA+Apeeed5a3sjba/mcDhzJGoTVLCKE= +github.com/gnolang/goleveldb v0.0.9/go.mod h1:Dz6p9bmpy/FBESTgduiThZt5mToVDipcHGzj/zUOo8E= +github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 h1:GKvsK3oLWG9B1GL7WP/VqwM6C92j5tIvB844oggL9Lk= +github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:xJhtEL7ahjM1WJipt89gel8tHzfIl/LyMY+lCYh38d8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jaekwon/testify v1.6.1 h1:4AtAJcR9GzXN5W4DdY7ie74iCPiJV1JJUJL90t2ZUyw= +github.com/jaekwon/testify v1.6.1/go.mod h1:Oun0RXIHI7osufabQ60i4Lqkj0GXLbqI1I7kgzBNm1U= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/linxGnu/grocksdb v1.8.11 h1:BGol9e5gB1BrsTvOxloC88pe70TCqgrfLNwkyWW0kD8= +github.com/linxGnu/grocksdb v1.8.11/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc= +github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap/exp v0.1.0 h1:Ol9zQNvAEAgFHSBiR5LlwS9Xq8u5QF+7HBwNHUB8rcI= +go.uber.org/zap/exp v0.1.0/go.mod h1:z/0T3As39ttolxZGOsvk1OEvQfwwfTZpmV9YTp+VAkc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/misc/autocounterd/r/autocounterd/autocounder.gno b/misc/autocounterd/r/autocounterd/autocounder.gno new file mode 100644 index 00000000000..8bdf15736d0 --- /dev/null +++ b/misc/autocounterd/r/autocounterd/autocounder.gno @@ -0,0 +1,17 @@ +package counter + +import "gno.land/p/demo/ufmt" + +var counter int = 0 + +func Incr() { + counter += 1 +} + +func Reset() { + counter = 0 +} + +func Render() string { + return ufmt.Sprintf("Counter: %d", counter) +} From 518a15fec2cb93e10ee87b708c9e53c771c2f900 Mon Sep 17 00:00:00 2001 From: Leon Hudak <33522493+leohhhn@users.noreply.github.com> Date: Wed, 10 Apr 2024 20:00:54 +0900 Subject: [PATCH 09/19] docs: add missing index pages (#1893) ## Description This PR adds reformats "Overview" pages into section index pages. Important changes are in `sidebars.js`.
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [x] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- docs/concepts/effective-gno.md | 2 +- docs/concepts/gno-test.md | 2 +- .../{standard-library => stdlibs}/banker.md | 2 +- .../{standard-library => stdlibs}/coin.md | 2 +- .../gnopher-hole.md | 0 .../overview.md => stdlibs/stdlibs.md} | 7 +++--- docs/how-to-guides/testing-gno.md | 2 +- .../std/address.md | 0 .../std/banker.md | 2 +- .../std/chain.md | 0 .../{standard-library => stdlibs}/std/coin.md | 2 +- .../std/coins.md | 0 .../std/testing.md | 0 .../overview.md => stdlibs/stdlibs.md} | 4 ++-- misc/docusaurus/sidebars.js | 22 +++++++++---------- 15 files changed, 23 insertions(+), 24 deletions(-) rename docs/concepts/{standard-library => stdlibs}/banker.md (93%) rename docs/concepts/{standard-library => stdlibs}/coin.md (95%) rename docs/concepts/{standard-library => stdlibs}/gnopher-hole.md (100%) rename docs/concepts/{standard-library/overview.md => stdlibs/stdlibs.md} (96%) rename docs/reference/{standard-library => stdlibs}/std/address.md (100%) rename docs/reference/{standard-library => stdlibs}/std/banker.md (96%) rename docs/reference/{standard-library => stdlibs}/std/chain.md (100%) rename docs/reference/{standard-library => stdlibs}/std/coin.md (91%) rename docs/reference/{standard-library => stdlibs}/std/coins.md (100%) rename docs/reference/{standard-library => stdlibs}/std/testing.md (100%) rename docs/reference/{standard-library/overview.md => stdlibs/stdlibs.md} (92%) diff --git a/docs/concepts/effective-gno.md b/docs/concepts/effective-gno.md index 72f3081556d..17e4ba28de6 100644 --- a/docs/concepts/effective-gno.md +++ b/docs/concepts/effective-gno.md @@ -612,7 +612,7 @@ For example, if you're creating a coin for cross-chain transfers, Coins are your best bet. They're IBC-ready and their strict rules offer top-notch security. -Read about how to use the Banker module [here](../concepts/standard-library/banker). +Read about how to use the Banker module [here](stdlibs/banker). #### GRC20 tokens diff --git a/docs/concepts/gno-test.md b/docs/concepts/gno-test.md index e05d2db7ed5..754dfad43c8 100644 --- a/docs/concepts/gno-test.md +++ b/docs/concepts/gno-test.md @@ -88,4 +88,4 @@ Internally, a GnoVM instance is initialized to run the test, and, at that moment a blockchain-related context is injected into the GnoVM. Utilizing this context, the transaction sender, coins, block height, etc. can be mocked. -For detailed information on these functions, refer to their [reference page](../reference/standard-library/std/testing.md). +For detailed information on these functions, refer to their [reference page](../reference/stdlibs/std/testing.md). diff --git a/docs/concepts/standard-library/banker.md b/docs/concepts/stdlibs/banker.md similarity index 93% rename from docs/concepts/standard-library/banker.md rename to docs/concepts/stdlibs/banker.md index a4a1104859c..873fac7c418 100644 --- a/docs/concepts/standard-library/banker.md +++ b/docs/concepts/stdlibs/banker.md @@ -15,4 +15,4 @@ The Banker module can be cast into 4 subtypes of bankers that expose different f 3. `BankerTypeRealmSend` - full access to coins that the realm itself owns, including the ones sent with the transaction 4. `BankerTypeRealmIssue` - able to issue new coins -The Banker API can be found under the `std` package [reference](../../reference/standard-library/std/banker.md). +The Banker API can be found under the `std` package [reference](../../reference/stdlibs/std/banker.md). diff --git a/docs/concepts/standard-library/coin.md b/docs/concepts/stdlibs/coin.md similarity index 95% rename from docs/concepts/standard-library/coin.md rename to docs/concepts/stdlibs/coin.md index db1618ef3f7..7a610866fd2 100644 --- a/docs/concepts/standard-library/coin.md +++ b/docs/concepts/stdlibs/coin.md @@ -33,4 +33,4 @@ which can manipulate them depending on access rights. [//]: # (TODO ADD LINK TO Effective GNO) Read more about coins in the [Effective Gno](https://docs.gno.land/concepts/effective-gno/#native-tokens) section. -The Coin(s) API can be found in under the `std` package [reference](../../reference/standard-library/std/coin.md). +The Coin(s) API can be found in under the `std` package [reference](../../reference/stdlibs/std/coin.md). diff --git a/docs/concepts/standard-library/gnopher-hole.md b/docs/concepts/stdlibs/gnopher-hole.md similarity index 100% rename from docs/concepts/standard-library/gnopher-hole.md rename to docs/concepts/stdlibs/gnopher-hole.md diff --git a/docs/concepts/standard-library/overview.md b/docs/concepts/stdlibs/stdlibs.md similarity index 96% rename from docs/concepts/standard-library/overview.md rename to docs/concepts/stdlibs/stdlibs.md index 6068de83f0f..ae0bb5b55bb 100644 --- a/docs/concepts/standard-library/overview.md +++ b/docs/concepts/stdlibs/stdlibs.md @@ -1,21 +1,20 @@ --- -id: overview +id: stdlibs --- -# Overview +# Standard Libraries Gno comes with a set of standard libraries which are included to ease development and provide extended functionality to the language. These include: - standard libraries as we know them in classic Go, i.e. `encoding/binary`, `strings`, `testing`, etc. - a special `std` package, which contains types, interfaces, and APIs created to handle blockchain-related functionality. - Standard libraries differ from on-chain packages in terms of their import path structure. Unlike on-chain [packages](../packages.md), standard libraries do not incorporate a domain-like format at the beginning of their import path. For example: - `import "encoding/binary"` refers to a standard library - `import "gno.land/p/demo/avl"` refers to an on-chain package. -To see concrete implementation details & API references, see the [reference](../../reference/standard-library/overview.md) section. +To see concrete implementation details & API references, see the [reference](../../reference/stdlibs/stdlibs.md) section. ## Accessing documentation diff --git a/docs/how-to-guides/testing-gno.md b/docs/how-to-guides/testing-gno.md index d517a8c9e24..35ad0618bf4 100644 --- a/docs/how-to-guides/testing-gno.md +++ b/docs/how-to-guides/testing-gno.md @@ -177,7 +177,7 @@ Luckily, the Gno standard library provides ample support for functionality such time, such as the request caller address, or the calling package address. You can learn more about these methods, that are importable using the `std` import declaration, -in the [Standard Library](../concepts/standard-library/overview.md) reference section. +in the [Standard Library](../concepts/stdlibs/overview.md) reference section. ## Conclusion diff --git a/docs/reference/standard-library/std/address.md b/docs/reference/stdlibs/std/address.md similarity index 100% rename from docs/reference/standard-library/std/address.md rename to docs/reference/stdlibs/std/address.md diff --git a/docs/reference/standard-library/std/banker.md b/docs/reference/stdlibs/std/banker.md similarity index 96% rename from docs/reference/standard-library/std/banker.md rename to docs/reference/stdlibs/std/banker.md index 621a447ab84..71eb3709ea2 100644 --- a/docs/reference/standard-library/std/banker.md +++ b/docs/reference/stdlibs/std/banker.md @@ -3,7 +3,7 @@ id: banker --- # Banker -View concept page [here](../../../concepts/standard-library/banker.md). +View concept page [here](../../../concepts/stdlibs/banker.md). ```go type BankerType uint8 diff --git a/docs/reference/standard-library/std/chain.md b/docs/reference/stdlibs/std/chain.md similarity index 100% rename from docs/reference/standard-library/std/chain.md rename to docs/reference/stdlibs/std/chain.md diff --git a/docs/reference/standard-library/std/coin.md b/docs/reference/stdlibs/std/coin.md similarity index 91% rename from docs/reference/standard-library/std/coin.md rename to docs/reference/stdlibs/std/coin.md index a59e0781724..f2e1cf694b4 100644 --- a/docs/reference/standard-library/std/coin.md +++ b/docs/reference/stdlibs/std/coin.md @@ -3,7 +3,7 @@ id: coin --- # Coin -View concept page [here](../../../concepts/standard-library/coin.md). +View concept page [here](../../../concepts/stdlibs/coin.md). ```go type Coin struct { diff --git a/docs/reference/standard-library/std/coins.md b/docs/reference/stdlibs/std/coins.md similarity index 100% rename from docs/reference/standard-library/std/coins.md rename to docs/reference/stdlibs/std/coins.md diff --git a/docs/reference/standard-library/std/testing.md b/docs/reference/stdlibs/std/testing.md similarity index 100% rename from docs/reference/standard-library/std/testing.md rename to docs/reference/stdlibs/std/testing.md diff --git a/docs/reference/standard-library/overview.md b/docs/reference/stdlibs/stdlibs.md similarity index 92% rename from docs/reference/standard-library/overview.md rename to docs/reference/stdlibs/stdlibs.md index ddf921e74a0..edcd9b7b7be 100644 --- a/docs/reference/standard-library/overview.md +++ b/docs/reference/stdlibs/stdlibs.md @@ -1,8 +1,8 @@ --- -id: overview +id: stdlibs --- -# Overview +# Standard Libraries This section serves as a reference to the standard libraries available in Gno. diff --git a/misc/docusaurus/sidebars.js b/misc/docusaurus/sidebars.js index f4858e22755..dcb737eed01 100644 --- a/misc/docusaurus/sidebars.js +++ b/misc/docusaurus/sidebars.js @@ -48,11 +48,11 @@ const sidebars = { { type: 'category', label: 'Standard Libraries', + link: {type: 'doc', id: 'concepts/stdlibs/stdlibs'}, items: [ - 'concepts/standard-library/overview', - 'concepts/standard-library/banker', - 'concepts/standard-library/coin', - 'concepts/standard-library/gnopher-hole-stdlib', + 'concepts/stdlibs/banker', + 'concepts/stdlibs/coin', + 'concepts/stdlibs/gnopher-hole-stdlib', ] }, 'concepts/gnovm', @@ -96,18 +96,18 @@ const sidebars = { { type: 'category', label: 'Standard Libraries', + link: {type: 'doc', id: 'reference/stdlibs/stdlibs'}, items: [ - 'reference/standard-library/overview', { type: 'category', label: 'std', items: [ - 'reference/standard-library/std/address', - 'reference/standard-library/std/banker', - 'reference/standard-library/std/coin', - 'reference/standard-library/std/coins', - 'reference/standard-library/std/chain', - 'reference/standard-library/std/testing', + 'reference/stdlibs/std/address', + 'reference/stdlibs/std/banker', + 'reference/stdlibs/std/coin', + 'reference/stdlibs/std/coins', + 'reference/stdlibs/std/chain', + 'reference/stdlibs/std/testing', ] } ] From 327d30e79a1190616905de2d3ba8eccf0c8d2ad9 Mon Sep 17 00:00:00 2001 From: Leon Hudak <33522493+leohhhn@users.noreply.github.com> Date: Wed, 10 Apr 2024 21:25:10 +0900 Subject: [PATCH 10/19] fix(docs): broken links (#1911) ## Description This PR fixes two broken links in the docs. Docusaurus build works as shown below: ![Screenshot 2024-04-10 at 20 33 24](https://github.com/gnolang/gno/assets/33522493/727b1265-c6fe-4439-9f0b-cc5b608a0882)
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- docs/how-to-guides/simple-library.md | 2 +- docs/how-to-guides/testing-gno.md | 2 +- misc/docusaurus/sidebars.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/how-to-guides/simple-library.md b/docs/how-to-guides/simple-library.md index 2846117df45..1ae231251d0 100644 --- a/docs/how-to-guides/simple-library.md +++ b/docs/how-to-guides/simple-library.md @@ -141,7 +141,7 @@ There are a few things happening here, so let's dissect them: - We defined the logic of our library into a package called `tapas`. - The package imports `std`, which -is the [Gno standard library](../concepts/standard-library/overview.md) +is the [Gno standard library](../concepts/stdlibs/stdlibs.md) - We use the imported package inside of `GetTapaSuggestion` to generate a random index value for a tapa diff --git a/docs/how-to-guides/testing-gno.md b/docs/how-to-guides/testing-gno.md index 35ad0618bf4..3ba734abba4 100644 --- a/docs/how-to-guides/testing-gno.md +++ b/docs/how-to-guides/testing-gno.md @@ -177,7 +177,7 @@ Luckily, the Gno standard library provides ample support for functionality such time, such as the request caller address, or the calling package address. You can learn more about these methods, that are importable using the `std` import declaration, -in the [Standard Library](../concepts/stdlibs/overview.md) reference section. +in the [Standard Library](../concepts/stdlibs/stdlibs.md) reference section. ## Conclusion diff --git a/misc/docusaurus/sidebars.js b/misc/docusaurus/sidebars.js index dcb737eed01..5a2533d7a44 100644 --- a/misc/docusaurus/sidebars.js +++ b/misc/docusaurus/sidebars.js @@ -11,7 +11,7 @@ const sidebars = { items: [ 'getting-started/playground-start', { - type: "category", + type: 'category', label: 'Local Setup', items: [ 'getting-started/local-setup/local-setup', From ca6566fdb2373d4fe0d88b5f79186160e5d9b082 Mon Sep 17 00:00:00 2001 From: ltzmaxwell Date: Wed, 10 Apr 2024 22:17:00 +0800 Subject: [PATCH 11/19] feat: add support for type declarations on pointer types (#1733) support type decl upon pointer type: ```go package main import "fmt" // Define a base type type Base int // Declare a new type that is a pointer to the base type type PtrToBase *Base func main() { var b Base = 42 // Initialize a variable of the base type var p PtrToBase = &b // Initialize a variable of the new pointer type with the address of b fmt.Printf("The value of b is: %d\n", b) // Using the new pointer type fmt.Printf("The value pointed to by p is: %d\n", *p) // Modifying the value pointed to by p *p = 100 fmt.Printf("The new value of b after modification through p is: %d\n", b) } // Output: // The value of b is: 42 // The value pointed to by p is: 42 // The new value of b after modification through p is: 100 ``` --- gnovm/pkg/gnolang/op_expressions.go | 2 +- gnovm/pkg/gnolang/op_types.go | 4 ++-- gnovm/pkg/gnolang/preprocess.go | 29 ++++++++++++++++++++++++++--- gnovm/tests/files/type33.gno | 28 ++++++++++++++++++++++++++++ gnovm/tests/files/type34.gno | 12 ++++++++++++ gnovm/tests/files/type35.gno | 15 +++++++++++++++ gnovm/tests/files/type36.gno | 17 +++++++++++++++++ gnovm/tests/files/type37.gno | 20 ++++++++++++++++++++ gnovm/tests/files/type37a.gno | 19 +++++++++++++++++++ gnovm/tests/files/type37b.gno | 22 ++++++++++++++++++++++ gnovm/tests/files/type37c.gno | 20 ++++++++++++++++++++ gnovm/tests/files/type37d.gno | 16 ++++++++++++++++ gnovm/tests/files/type37e.gno | 17 +++++++++++++++++ gnovm/tests/files/type37f.gno | 16 ++++++++++++++++ gnovm/tests/files/type38.gno | 26 ++++++++++++++++++++++++++ gnovm/tests/files/type39.gno | 22 ++++++++++++++++++++++ gnovm/tests/files/type39a.gno | 24 ++++++++++++++++++++++++ gnovm/tests/files/type39b.gno | 22 ++++++++++++++++++++++ 18 files changed, 325 insertions(+), 6 deletions(-) create mode 100644 gnovm/tests/files/type33.gno create mode 100644 gnovm/tests/files/type34.gno create mode 100644 gnovm/tests/files/type35.gno create mode 100644 gnovm/tests/files/type36.gno create mode 100644 gnovm/tests/files/type37.gno create mode 100644 gnovm/tests/files/type37a.gno create mode 100644 gnovm/tests/files/type37b.gno create mode 100644 gnovm/tests/files/type37c.gno create mode 100644 gnovm/tests/files/type37d.gno create mode 100644 gnovm/tests/files/type37e.gno create mode 100644 gnovm/tests/files/type37f.gno create mode 100644 gnovm/tests/files/type38.gno create mode 100644 gnovm/tests/files/type39.gno create mode 100644 gnovm/tests/files/type39a.gno create mode 100644 gnovm/tests/files/type39b.gno diff --git a/gnovm/pkg/gnolang/op_expressions.go b/gnovm/pkg/gnolang/op_expressions.go index b3bf240aea1..bc21850bb8c 100644 --- a/gnovm/pkg/gnolang/op_expressions.go +++ b/gnovm/pkg/gnolang/op_expressions.go @@ -147,7 +147,7 @@ func (m *Machine) doOpStar() { case *PointerType: pv := xv.V.(PointerValue) if pv.TV.T == DataByteType { - tv := TypedValue{T: xv.T.(*PointerType).Elt} + tv := TypedValue{T: bt.Elt} dbv := pv.TV.V.(DataByteValue) tv.SetUint8(dbv.GetByte()) m.PushValue(tv) diff --git a/gnovm/pkg/gnolang/op_types.go b/gnovm/pkg/gnolang/op_types.go index a38010bac4e..850aa7a6e64 100644 --- a/gnovm/pkg/gnolang/op_types.go +++ b/gnovm/pkg/gnolang/op_types.go @@ -467,7 +467,7 @@ func (m *Machine) doOpStaticTypeOf() { m.PushOp(OpStaticTypeOf) m.Run() // XXX replace xt := m.ReapValues(start)[0].V.(TypeValue).Type - if pt, ok := xt.(*PointerType); ok { + if pt, ok := baseOf(xt).(*PointerType); ok { m.PushValue(asValue(&SliceType{ Elt: pt.Elt.Elem(), })) @@ -485,7 +485,7 @@ func (m *Machine) doOpStaticTypeOf() { m.PushOp(OpStaticTypeOf) m.Run() // XXX replace xt := m.ReapValues(start)[0].GetType() - if pt, ok := xt.(*PointerType); ok { + if pt, ok := baseOf(xt).(*PointerType); ok { m.PushValue(asValue(pt.Elt)) } else if _, ok := xt.(*TypeType); ok { m.PushValue(asValue(gTypeType)) diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index fba01750a20..a09419637cf 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -2542,7 +2542,7 @@ func checkType(xt Type, dt Type, autoNative bool) { // Special case if xt or dt is *PointerType to *NativeType, // convert to *NativeType of pointer kind. if pxt, ok := xt.(*PointerType); ok { - // *gonative{x} is gonative{*x} + // *gonative{x} is(to) gonative{*x} //nolint:misspell if enxt, ok := pxt.Elt.(*NativeType); ok { xt = &NativeType{ @@ -3025,11 +3025,32 @@ func predefineNow2(store Store, last BlockNode, d Decl, m map[Name]struct{}) (De ft := evalStaticType(store, last, &cd.Type).(*FuncType) ft = ft.UnboundType(rft) dt := (*DeclaredType)(nil) + + // check base type of receiver type, should not be pointer type or interface type + assertValidReceiverType := func(t Type) { + if _, ok := t.(*PointerType); ok { + panic(fmt.Sprintf("invalid receiver type %v (base type is pointer type)\n", rt)) + } + if _, ok := t.(*InterfaceType); ok { + panic(fmt.Sprintf("invalid receiver type %v (base type is interface type)\n", rt)) + } + } + if pt, ok := rt.(*PointerType); ok { - dt = pt.Elem().(*DeclaredType) + assertValidReceiverType(pt.Elem()) + if ddt, ok := pt.Elem().(*DeclaredType); ok { + assertValidReceiverType(baseOf(ddt)) + dt = ddt + } else { + panic("should not happen") + } + } else if ddt, ok := rt.(*DeclaredType); ok { + assertValidReceiverType(baseOf(ddt)) + dt = ddt } else { - dt = rt.(*DeclaredType) + panic("should not happen") } + if !dt.TryDefineMethod(&FuncValue{ Type: ft, IsMethod: true, @@ -3168,6 +3189,8 @@ func tryPredefine(store Store, last BlockNode, d Decl) (un Name) { t = &MapType{} case *StructTypeExpr: t = &StructType{} + case *StarExpr: + t = &PointerType{} case *NameExpr: if tv := last.GetValueRef(store, tx.Name); tv != nil { // (file) block name diff --git a/gnovm/tests/files/type33.gno b/gnovm/tests/files/type33.gno new file mode 100644 index 00000000000..62d6696fafa --- /dev/null +++ b/gnovm/tests/files/type33.gno @@ -0,0 +1,28 @@ +package main + +import "fmt" + +// Define a base type +type Base int + +// Declare a new type that is a pointer to the base type +type PtrToBase *Base + +func main() { + var b Base = 42 // Initialize a variable of the base type + var p PtrToBase = &b // Initialize a variable of the new pointer type with the address of b + + fmt.Printf("The value of b is: %d\n", b) + + // Using the new pointer type + fmt.Printf("The value pointed to by p is: %d\n", *p) + + // Modifying the value pointed to by p + *p = 100 + fmt.Printf("The new value of b after modification through p is: %d\n", b) +} + +// Output: +// The value of b is: 42 +// The value pointed to by p is: 42 +// The new value of b after modification through p is: 100 diff --git a/gnovm/tests/files/type34.gno b/gnovm/tests/files/type34.gno new file mode 100644 index 00000000000..20f53b78cd6 --- /dev/null +++ b/gnovm/tests/files/type34.gno @@ -0,0 +1,12 @@ +package main + +type BytePtr *byte + +func main() { + bs := []byte("hello") + var p BytePtr = &bs[0] + println(*p) +} + +// Output: +// 104 diff --git a/gnovm/tests/files/type35.gno b/gnovm/tests/files/type35.gno new file mode 100644 index 00000000000..9ade96ee9c8 --- /dev/null +++ b/gnovm/tests/files/type35.gno @@ -0,0 +1,15 @@ +package main + +type IntPtr *int + +func main() { + var a, b int + a = 1 // Set a to 104 + s := []IntPtr{} + s = append(s, &a) + s = append(s, &b) + println(*s[0]) +} + +// Output: +// 1 diff --git a/gnovm/tests/files/type36.gno b/gnovm/tests/files/type36.gno new file mode 100644 index 00000000000..8bb64118036 --- /dev/null +++ b/gnovm/tests/files/type36.gno @@ -0,0 +1,17 @@ +package main + +type Arr [2]int +type Ptr *Arr + +func main() { + var arr Arr + arr[0] = 0 + arr[1] = 1 + + p := Ptr(&arr) + + println(p[:]) +} + +// Output: +// slice[(0 int),(1 int)] diff --git a/gnovm/tests/files/type37.gno b/gnovm/tests/files/type37.gno new file mode 100644 index 00000000000..1bc157b44ff --- /dev/null +++ b/gnovm/tests/files/type37.gno @@ -0,0 +1,20 @@ +package main + +import "fmt" + +type IntArray []int +type Arr *IntArray + +func (a Arr) Add(x int) { // receiver is val, not ptr + *a = append(*a, x) +} + +func main() { + a := new(IntArray) + Arr(a).Add(4) + + fmt.Println(*a) +} + +// Error: +// main/files/type37.gno:8: invalid receiver type main.Arr (base type is pointer type) diff --git a/gnovm/tests/files/type37a.gno b/gnovm/tests/files/type37a.gno new file mode 100644 index 00000000000..16db1cc4dc2 --- /dev/null +++ b/gnovm/tests/files/type37a.gno @@ -0,0 +1,19 @@ +package main + +import "fmt" + +type IntArray []int + +func (a *IntArray) Add(x int) { // receiver is val, not ptr + *a = append(*a, x) +} + +func main() { + a := new(IntArray) + a.Add(4) + + fmt.Println(*a) +} + +// Output: +// [4] diff --git a/gnovm/tests/files/type37b.gno b/gnovm/tests/files/type37b.gno new file mode 100644 index 00000000000..aea1b445ca1 --- /dev/null +++ b/gnovm/tests/files/type37b.gno @@ -0,0 +1,22 @@ +package main + +import "fmt" + +type Integer int + +func (i **Integer) Add(x int) { + **i += Integer(x) // Dereference twice to get to the actual Integer value and modify it +} + +func main() { + a := new(Integer) // a is a pointer to Integer + b := &a // b is a pointer to a pointer to Integer + + // Since Add is defined on **Integer, you need to pass b + b.Add(4) // Adds 4 to the value **b points to + + fmt.Println(**b) // Should print 4, as **b is the same as *a +} + +// Error: +// main/files/type37b.gno:7: invalid receiver type **main.Integer (base type is pointer type) diff --git a/gnovm/tests/files/type37c.gno b/gnovm/tests/files/type37c.gno new file mode 100644 index 00000000000..7cd8ac7367e --- /dev/null +++ b/gnovm/tests/files/type37c.gno @@ -0,0 +1,20 @@ +package main + +import "fmt" + +type Integer int + +func (i *Integer) Add(x int) { // receiver is val, not ptr + println(int(*i) + x) +} + +func main() { + a := new(Integer) + a.Add(4) + + fmt.Println(*a) +} + +// Output: +// 4 +// 0 diff --git a/gnovm/tests/files/type37d.gno b/gnovm/tests/files/type37d.gno new file mode 100644 index 00000000000..ada9541e64e --- /dev/null +++ b/gnovm/tests/files/type37d.gno @@ -0,0 +1,16 @@ +package main + +type IntPtr *int + +var ip IntPtr = new(int) + +func (p IntPtr) Int() int { + return *p +} + +func main() { + println(ip.Int()) +} + +// Error: +// main/files/type37d.gno:7: invalid receiver type main.IntPtr (base type is pointer type) diff --git a/gnovm/tests/files/type37e.gno b/gnovm/tests/files/type37e.gno new file mode 100644 index 00000000000..a2537c9cb8d --- /dev/null +++ b/gnovm/tests/files/type37e.gno @@ -0,0 +1,17 @@ +package main + +type IntPtr *int +type Int2 IntPtr + +var ip IntPtr = new(int) + +func (i2 Int2) Int() int { + return *i2 +} + +func main() { + println(Int2(ip).Int()) +} + +// Error: +// main/files/type37e.gno:8: invalid receiver type main.Int2 (base type is pointer type) diff --git a/gnovm/tests/files/type37f.gno b/gnovm/tests/files/type37f.gno new file mode 100644 index 00000000000..7bffa748314 --- /dev/null +++ b/gnovm/tests/files/type37f.gno @@ -0,0 +1,16 @@ +package main + +type IntPtr *int + +var ip IntPtr = new(int) + +func (p *IntPtr) Int() int { + return **p +} + +func main() { + println((&ip).Int()) +} + +// Error: +// main/files/type37f.gno:7: invalid receiver type *main.IntPtr (base type is pointer type) diff --git a/gnovm/tests/files/type38.gno b/gnovm/tests/files/type38.gno new file mode 100644 index 00000000000..a3a03f1e248 --- /dev/null +++ b/gnovm/tests/files/type38.gno @@ -0,0 +1,26 @@ +package main + +import "fmt" + +type IntArray []int +type Arr *IntArray + +func add(arr Arr) { // receiver is val, not ptr + *arr = append(*arr, 1) +} + +func main() { + a := new(IntArray) + add(a) + + fmt.Println(a) + fmt.Println(*a) + fmt.Println(len(*a)) + fmt.Println((*a)[0]) +} + +// Output: +// &[1] +// [1] +// 1 +// 1 diff --git a/gnovm/tests/files/type39.gno b/gnovm/tests/files/type39.gno new file mode 100644 index 00000000000..aebcc226385 --- /dev/null +++ b/gnovm/tests/files/type39.gno @@ -0,0 +1,22 @@ +package main + +type foo interface { + say() +} + +func (f foo) echo() int { + return 1 +} + +type Bar struct{} + +func (b *Bar) say() {} + +func main() { + var f foo + f = &Bar{} + println(f.echo()) +} + +// Error: +// main/files/type39.gno:7: invalid receiver type main.foo (base type is interface type) diff --git a/gnovm/tests/files/type39a.gno b/gnovm/tests/files/type39a.gno new file mode 100644 index 00000000000..06f41897f93 --- /dev/null +++ b/gnovm/tests/files/type39a.gno @@ -0,0 +1,24 @@ +package main + +type foo interface { + say() +} + +type FF foo + +func (f FF) echo() int { + return 1 +} + +type Bar struct{} + +func (b *Bar) say() {} + +func main() { + var f foo + f = &Bar{} + println(f.echo()) +} + +// Error: +// main/files/type39a.gno:9: invalid receiver type main.FF (base type is interface type) diff --git a/gnovm/tests/files/type39b.gno b/gnovm/tests/files/type39b.gno new file mode 100644 index 00000000000..dbf5312a825 --- /dev/null +++ b/gnovm/tests/files/type39b.gno @@ -0,0 +1,22 @@ +package main + +type foo interface { + say() +} + +func (f *foo) echo() int { + return 1 +} + +type Bar struct{} + +func (b *Bar) say() {} + +func main() { + var f *foo + *f = &Bar{} + println(f.echo()) +} + +// Error: +// main/files/type39b.gno:7: invalid receiver type *main.foo (base type is interface type) From aab9f4fd767137f005f2bc126d8b29b4237e32ca Mon Sep 17 00:00:00 2001 From: Malek Lahbib <111009238+MalekLahbib@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:40:25 +0200 Subject: [PATCH 12/19] feat(examples): add todolist package & realm (#1811)
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- examples/gno.land/p/demo/todolist/gno.mod | 3 + .../gno.land/p/demo/todolist/todolist.gno | 63 +++++++ .../p/demo/todolist/todolist_test.gno | 81 ++++++++ examples/gno.land/r/demo/todolist/gno.mod | 8 + .../gno.land/r/demo/todolist/todolist.gno | 176 ++++++++++++++++++ .../r/demo/todolist/todolist_test.gno | 86 +++++++++ 6 files changed, 417 insertions(+) create mode 100644 examples/gno.land/p/demo/todolist/gno.mod create mode 100644 examples/gno.land/p/demo/todolist/todolist.gno create mode 100644 examples/gno.land/p/demo/todolist/todolist_test.gno create mode 100644 examples/gno.land/r/demo/todolist/gno.mod create mode 100644 examples/gno.land/r/demo/todolist/todolist.gno create mode 100644 examples/gno.land/r/demo/todolist/todolist_test.gno diff --git a/examples/gno.land/p/demo/todolist/gno.mod b/examples/gno.land/p/demo/todolist/gno.mod new file mode 100644 index 00000000000..a51528b9500 --- /dev/null +++ b/examples/gno.land/p/demo/todolist/gno.mod @@ -0,0 +1,3 @@ +module gno.land/p/demo/todolist + +require gno.land/p/demo/avl v0.0.0-latest diff --git a/examples/gno.land/p/demo/todolist/todolist.gno b/examples/gno.land/p/demo/todolist/todolist.gno new file mode 100644 index 00000000000..a675344655f --- /dev/null +++ b/examples/gno.land/p/demo/todolist/todolist.gno @@ -0,0 +1,63 @@ +package todolist + +import ( + "std" + "strconv" + + "gno.land/p/demo/avl" +) + +type TodoList struct { + Title string + Tasks *avl.Tree + Owner std.Address +} + +type Task struct { + Title string + Done bool +} + +func NewTodoList(title string) *TodoList { + return &TodoList{ + Title: title, + Tasks: avl.NewTree(), + Owner: std.GetOrigCaller(), + } +} + +func NewTask(title string) *Task { + return &Task{ + Title: title, + Done: false, + } +} + +func (tl *TodoList) AddTask(id int, task *Task) { + tl.Tasks.Set(strconv.Itoa(id), task) +} + +func ToggleTaskStatus(task *Task) { + task.Done = !task.Done +} + +func (tl *TodoList) RemoveTask(taskId string) { + tl.Tasks.Remove(taskId) +} + +func (tl *TodoList) GetTasks() []*Task { + tasks := make([]*Task, 0, tl.Tasks.Size()) + tl.Tasks.Iterate("", "", func(key string, value interface{}) bool { + tasks = append(tasks, value.(*Task)) + return false + }) + return tasks +} + +func (tl *TodoList) GetTodolistOwner() std.Address { + return tl.Owner +} + +func (tl *TodoList) GetTodolistTitle() string { + return tl.Title +} diff --git a/examples/gno.land/p/demo/todolist/todolist_test.gno b/examples/gno.land/p/demo/todolist/todolist_test.gno new file mode 100644 index 00000000000..5b2bb361881 --- /dev/null +++ b/examples/gno.land/p/demo/todolist/todolist_test.gno @@ -0,0 +1,81 @@ +package todolist + +import ( + "std" + "testing" +) + +func TestNewTodoList(t *testing.T) { + title := "My Todo List" + todoList := NewTodoList(title) + + if todoList.GetTodolistTitle() != title { + t.Errorf("Expected title %q, got %q", title, todoList.GetTodolistTitle()) + } + + if len(todoList.GetTasks()) != 0 { + t.Errorf("Expected 0 tasks, got %d", len(todoList.GetTasks())) + } + + if todoList.GetTodolistOwner() != std.GetOrigCaller() { + t.Errorf("Expected owner %v, got %v", std.GetOrigCaller(), todoList.GetTodolistOwner()) + } +} + +func TestNewTask(t *testing.T) { + title := "My Task" + task := NewTask(title) + + if task.Title != title { + t.Errorf("Expected title %q, got %q", title, task.Title) + } + + if task.Done { + t.Errorf("Expected task to be not done, but it is done") + } +} + +func TestAddTask(t *testing.T) { + todoList := NewTodoList("My Todo List") + task := NewTask("My Task") + + todoList.AddTask(1, task) + + tasks := todoList.GetTasks() + if len(tasks) != 1 { + t.Errorf("Expected 1 task, got %d", len(tasks)) + } + + if tasks[0] != task { + t.Errorf("Expected task %v, got %v", task, tasks[0]) + } +} + +func TestToggleTaskStatus(t *testing.T) { + task := NewTask("My Task") + + ToggleTaskStatus(task) + + if !task.Done { + t.Errorf("Expected task to be done, but it is not done") + } + + ToggleTaskStatus(task) + + if task.Done { + t.Errorf("Expected task to be not done, but it is done") + } +} + +func TestRemoveTask(t *testing.T) { + todoList := NewTodoList("My Todo List") + task := NewTask("My Task") + todoList.AddTask(1, task) + + todoList.RemoveTask("1") + + tasks := todoList.GetTasks() + if len(tasks) != 0 { + t.Errorf("Expected 0 tasks, got %d", len(tasks)) + } +} diff --git a/examples/gno.land/r/demo/todolist/gno.mod b/examples/gno.land/r/demo/todolist/gno.mod new file mode 100644 index 00000000000..563bab74ad5 --- /dev/null +++ b/examples/gno.land/r/demo/todolist/gno.mod @@ -0,0 +1,8 @@ +module gno.land/r/demo/todolist + +require ( + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/seqid v0.0.0-latest + gno.land/p/demo/todolist v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest +) diff --git a/examples/gno.land/r/demo/todolist/todolist.gno b/examples/gno.land/r/demo/todolist/todolist.gno new file mode 100644 index 00000000000..5790aac630a --- /dev/null +++ b/examples/gno.land/r/demo/todolist/todolist.gno @@ -0,0 +1,176 @@ +package todolistrealm + +import ( + "bytes" + "strconv" + + "gno.land/p/demo/avl" + "gno.land/p/demo/seqid" + "gno.land/p/demo/todolist" + "gno.land/p/demo/ufmt" +) + +// State variables +var ( + todolistTree *avl.Tree + tlid seqid.ID +) + +// Constructor +func init() { + todolistTree = avl.NewTree() +} + +func NewTodoList(title string) (int, string) { + // Create new Todolist + tl := todolist.NewTodoList(title) + // Update AVL tree with new state + tlid.Next() + todolistTree.Set(strconv.Itoa(int(tlid)), tl) + return int(tlid), "created successfully" +} + +func AddTask(todolistID int, title string) string { + // Get Todolist from AVL tree + tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + panic("Todolist not found") + } + + // get the number of tasks in the todolist + id := tl.(*todolist.TodoList).Tasks.Size() + + // create the task + task := todolist.NewTask(title) + + // Cast raw data from tree into Todolist struct + tl.(*todolist.TodoList).AddTask(id, task) + + return "task added successfully" +} + +func ToggleTaskStatus(todolistID int, taskID int) string { + // Get Todolist from AVL tree + tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + panic("Todolist not found") + } + + // Get the task from the todolist + task, found := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) + if !found { + panic("Task not found") + } + + // Change the status of the task + todolist.ToggleTaskStatus(task.(*todolist.Task)) + + return "task status changed successfully" +} + +func RemoveTask(todolistID int, taskID int) string { + // Get Todolist from AVL tree + tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + panic("Todolist not found") + } + + // Get the task from the todolist + _, ok = tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) + if !ok { + panic("Task not found") + } + + // Change the status of the task + tl.(*todolist.TodoList).RemoveTask(strconv.Itoa(taskID)) + + return "task status changed successfully" +} + +func RemoveTodoList(todolistID int) string { + // Get Todolist from AVL tree + _, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + panic("Todolist not found") + } + + // Remove the todolist + todolistTree.Remove(strconv.Itoa(todolistID)) + + return "Todolist removed successfully" +} + +func Render(path string) string { + if path == "" { + return renderHomepage() + } + + return "unknown page" +} + +func renderHomepage() string { + // Define empty buffer + var b bytes.Buffer + + b.WriteString("# Welcome to ToDolist\n\n") + + // If no todolists have been created + if todolistTree.Size() == 0 { + b.WriteString("### No todolists available currently!") + return b.String() + } + + // Iterate through AVL tree + todolistTree.Iterate("", "", func(key string, value interface{}) bool { + // cast raw data from tree into Todolist struct + tl := value.(*todolist.TodoList) + + // Add Todolist name + b.WriteString( + ufmt.Sprintf( + "## Todolist #%s: %s\n", + key, // Todolist ID + tl.GetTodolistTitle(), + ), + ) + + // Add Todolist owner + b.WriteString( + ufmt.Sprintf( + "#### Todolist owner : %s\n", + tl.GetTodolistOwner(), + ), + ) + + // List all todos that are currently Todolisted + if todos := tl.GetTasks(); len(todos) > 0 { + b.WriteString( + ufmt.Sprintf("Currently Todo tasks: %d\n\n", len(todos)), + ) + + for index, todo := range todos { + b.WriteString( + ufmt.Sprintf("#%d - %s ", index, todo.Title), + ) + // displays a checked box if task is marked as done, an empty box if not + if todo.Done { + b.WriteString( + "☑\n\n", + ) + continue + } + + b.WriteString( + "☐\n\n", + ) + } + } else { + b.WriteString("No tasks in this list currently\n") + } + + b.WriteString("\n") + return false + }) + + return b.String() +} diff --git a/examples/gno.land/r/demo/todolist/todolist_test.gno b/examples/gno.land/r/demo/todolist/todolist_test.gno new file mode 100644 index 00000000000..db55110851e --- /dev/null +++ b/examples/gno.land/r/demo/todolist/todolist_test.gno @@ -0,0 +1,86 @@ +package todolistrealm + +import ( + "std" + "strconv" + "testing" + + "gno.land/p/demo/todolist" +) + +var ( + node interface{} + tdl *todolist.TodoList +) + +func TestNewTodoList(t *testing.T) { + title := "My Todo List" + tlid, _ := NewTodoList(title) + if tlid != 1 { + t.Errorf("Expected tlid to be 1, but got %d", tlid) + } + + // get the todolist node from the tree + node, _ = todolistTree.Get(strconv.Itoa(tlid)) + // convert the node to a TodoList struct + tdl = node.(*todolist.TodoList) + + if tdl.Title != title { + t.Errorf("Expected title to be %s, but got %s", title, tdl.Title) + } + if tdl.Owner != std.GetOrigCaller() { + t.Errorf("Expected owner to be %s, but got %s", std.GetOrigCaller(), tdl.Owner) + } + if len(tdl.GetTasks()) != 0 { + t.Errorf("Expected no tasks in the todo list, but got %d tasks", len(tdl.GetTasks())) + } +} + +func TestAddTask(t *testing.T) { + AddTask(1, "Task 1") + + tasks := tdl.GetTasks() + if len(tasks) != 1 { + t.Errorf("Expected 1 task in the todo list, but got %d tasks", len(tasks)) + } + + if tasks[0].Title != "Task 1" { + t.Errorf("Expected task title to be 'Task 1', but got '%s'", tasks[0].Title) + } + + if tasks[0].Done { + t.Errorf("Expected task to be not done, but it is marked as done") + } +} + +func TestToggleTaskStatus(t *testing.T) { + ToggleTaskStatus(1, 0) + task := tdl.GetTasks()[0] + + if !task.Done { + t.Errorf("Expected task to be done, but it is not marked as done") + } + + ToggleTaskStatus(1, 0) + + if task.Done { + t.Errorf("Expected task to be not done, but it is marked as done") + } +} + +func TestRemoveTask(t *testing.T) { + RemoveTask(1, 0) + tasks := tdl.GetTasks() + + if len(tasks) != 0 { + t.Errorf("Expected no tasks in the todo list, but got %d tasks", len(tasks)) + } +} + +func TestRemoveTodoList(t *testing.T) { + RemoveTodoList(1) + + if todolistTree.Size() != 0 { + t.Errorf("Expected no tasks in the todo list, but got %d tasks", todolistTree.Size()) + } +} From 9f99972c7e46b6f776d46087334a55e4ea5e8414 Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Thu, 11 Apr 2024 22:20:58 +0900 Subject: [PATCH 13/19] chore(gnovm, tm2): changed `reflect.PtrTo` to `reflect.PointerTo` (#1894) # Description The `reflect.PtrTo` function has been deprecated, so I changed this method to `reflect.PointerTo`. These two functions have exactly the same behavior. ref: https://pkg.go.dev/reflect#PtrTo --- gnovm/pkg/gnolang/gonative.go | 4 ++-- gnovm/pkg/gnolang/op_expressions.go | 2 +- gnovm/pkg/gnolang/op_types.go | 6 +++--- gnovm/pkg/gnolang/preprocess.go | 6 +++--- gnovm/pkg/gnolang/types.go | 2 +- tm2/pkg/amino/codec.go | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gnovm/pkg/gnolang/gonative.go b/gnovm/pkg/gnolang/gonative.go index 4cd39858300..f73a5c58962 100644 --- a/gnovm/pkg/gnolang/gonative.go +++ b/gnovm/pkg/gnolang/gonative.go @@ -129,7 +129,7 @@ func (ds *defaultStore) Go2GnoType(rt reflect.Type) (t Type) { // for methods with ptr receivers, // whereas gno methods are all // declared on the *DeclaredType. - prt = reflect.PtrTo(rt) + prt = reflect.PointerTo(rt) } nm := prt.NumMethod() mtvs = make([]TypedValue, nm) @@ -825,7 +825,7 @@ func gno2GoType(t Type) reflect.Type { } case *PointerType: et := gno2GoType(ct.Elem()) - return reflect.PtrTo(et) + return reflect.PointerTo(et) case *ArrayType: ne := ct.Len et := gno2GoType(ct.Elem()) diff --git a/gnovm/pkg/gnolang/op_expressions.go b/gnovm/pkg/gnolang/op_expressions.go index bc21850bb8c..2efcc41fdce 100644 --- a/gnovm/pkg/gnolang/op_expressions.go +++ b/gnovm/pkg/gnolang/op_expressions.go @@ -163,7 +163,7 @@ func (m *Machine) doOpStar() { t := xv.GetType() var pt Type if nt, ok := t.(*NativeType); ok { - pt = &NativeType{Type: reflect.PtrTo(nt.Type)} + pt = &NativeType{Type: reflect.PointerTo(nt.Type)} } else { pt = &PointerType{Elt: t} } diff --git a/gnovm/pkg/gnolang/op_types.go b/gnovm/pkg/gnolang/op_types.go index 850aa7a6e64..904b74fd1a9 100644 --- a/gnovm/pkg/gnolang/op_types.go +++ b/gnovm/pkg/gnolang/op_types.go @@ -405,7 +405,7 @@ func (m *Machine) doOpStaticTypeOf() { "VPNative access on pointer to non-native value %v", pt.Elt)) } dxt = &NativeType{ - Type: reflect.PtrTo(net.Type), + Type: reflect.PointerTo(net.Type), } } // switch on type and maybe match field. @@ -431,10 +431,10 @@ func (m *Machine) doOpStaticTypeOf() { return } // make rt ptr. - rt = reflect.PtrTo(rt) + rt = reflect.PointerTo(rt) } else { // make rt ptr. - rt = reflect.PtrTo(rt) + rt = reflect.PointerTo(rt) } // match method. rmt, ok := rt.MethodByName(string(x.Sel)) diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index a09419637cf..029641f2507 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -2521,7 +2521,7 @@ func checkType(xt Type, dt Type, autoNative bool) { nidt.String())) } // if xt has native base, do the naive native. - if reflect.PtrTo(nxt.Type).AssignableTo(nidt) { + if reflect.PointerTo(nxt.Type).AssignableTo(nidt) { return // ok } else { panic(fmt.Sprintf( @@ -2546,7 +2546,7 @@ func checkType(xt Type, dt Type, autoNative bool) { //nolint:misspell if enxt, ok := pxt.Elt.(*NativeType); ok { xt = &NativeType{ - Type: reflect.PtrTo(enxt.Type), + Type: reflect.PointerTo(enxt.Type), } } } @@ -2554,7 +2554,7 @@ func checkType(xt Type, dt Type, autoNative bool) { // *gonative{x} is gonative{*x} if endt, ok := pdt.Elt.(*NativeType); ok { dt = &NativeType{ - Type: reflect.PtrTo(endt.Type), + Type: reflect.PointerTo(endt.Type), } } } diff --git a/gnovm/pkg/gnolang/types.go b/gnovm/pkg/gnolang/types.go index 34565b7a1b6..e1814e8f243 100644 --- a/gnovm/pkg/gnolang/types.go +++ b/gnovm/pkg/gnolang/types.go @@ -696,7 +696,7 @@ func (pt *PointerType) FindEmbeddedFieldType(callerPath string, n Name, m map[Ty } case *NativeType: npt := &NativeType{ - Type: reflect.PtrTo(cet.Type), + Type: reflect.PointerTo(cet.Type), } return npt.FindEmbeddedFieldType(n, m) default: diff --git a/tm2/pkg/amino/codec.go b/tm2/pkg/amino/codec.go index 602c7090d91..3fa7634e3ad 100644 --- a/tm2/pkg/amino/codec.go +++ b/tm2/pkg/amino/codec.go @@ -594,7 +594,7 @@ func (cdc *Codec) newTypeInfoUnregisteredWLocked(rt reflect.Type) *TypeInfo { cdc.typeInfos[rt] = info info.Type = rt - info.PtrToType = reflect.PtrTo(rt) + info.PtrToType = reflect.PointerTo(rt) info.ZeroValue = reflect.Zero(rt) var isAminoMarshaler bool var reprType reflect.Type @@ -602,7 +602,7 @@ func (cdc *Codec) newTypeInfoUnregisteredWLocked(rt reflect.Type) *TypeInfo { isAminoMarshaler = true reprType = marshalAminoReprType(rm) } - if rm, ok := reflect.PtrTo(rt).MethodByName("UnmarshalAmino"); ok { + if rm, ok := reflect.PointerTo(rt).MethodByName("UnmarshalAmino"); ok { if !isAminoMarshaler { panic("Must implement both (o).MarshalAmino and (*o).UnmarshalAmino") } From f962c7187faac3d032c62e34c58b9d0a29410f85 Mon Sep 17 00:00:00 2001 From: Guilhem Fanton <8671905+gfanton@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:35:05 +0200 Subject: [PATCH 14/19] ci: use docker buildx to support multiple arch (#1912) Cleanup and upgrade CI docker build jobs to use Docker Buildx for multi-architecture support
Contributors' checklist... - [ ] Added new tests, or not needed, or not feasible - [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- .github/workflows/docker.yml | 99 ++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f2d1896a61c..fe0c068fbc2 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -14,69 +14,70 @@ concurrency: cancel-in-progress: true jobs: - build-push: + build-main: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - name: Build main Docker image - env: - owner: ${{ github.repository_owner }} - reponame: ${{ github.event.repository.name }} - run: | - docker build -t ghcr.io/${owner}/${reponame} . - docker tag ghcr.io/${owner}/${reponame}:latest ghcr.io/${owner}/${reponame}:${GITHUB_SHA::8} + - name: Get commit SHA + id: commit + run: echo "sha=${GITHUB_SHA::8}" >> "$GITHUB_OUTPUT" - - name: Build slim Docker images - env: - owner: ${{ github.repository_owner }} - reponame: ${{ github.event.repository.name }} - run: | - docker build --target=gnoland-slim -t ghcr.io/${owner}/${reponame}/gnoland-slim . - docker build --target=gnokey-slim -t ghcr.io/${owner}/${reponame}/gnokey-slim . - docker build --target=gno-slim -t ghcr.io/${owner}/${reponame}/gno-slim . - docker build --target=gnofaucet-slim -t ghcr.io/${owner}/${reponame}/gnofaucet-slim . - docker build --target=gnoweb-slim -t ghcr.io/${owner}/${reponame}/gnoweb-slim . + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - docker tag ghcr.io/${owner}/${reponame}/gnoland-slim:latest ghcr.io/${owner}/${reponame}/gnoland-slim:${GITHUB_SHA::8} - docker tag ghcr.io/${owner}/${reponame}/gnokey-slim:latest ghcr.io/${owner}/${reponame}/gnokey-slim:${GITHUB_SHA::8} - docker tag ghcr.io/${owner}/${reponame}/gno-slim:latest ghcr.io/${owner}/${reponame}/gno-slim:${GITHUB_SHA::8} - docker tag ghcr.io/${owner}/${reponame}/gnofaucet-slim:latest ghcr.io/${owner}/${reponame}/gnofaucet-slim:${GITHUB_SHA::8} - docker tag ghcr.io/${owner}/${reponame}/gnoweb-slim:latest ghcr.io/${owner}/${reponame}/gnoweb-slim:${GITHUB_SHA::8} - - - name: List docker images - run: | - docker images | grep ghcr - - - name: Log in to GitHub Container Registry - if: (github.event_name != 'pull_request') + - name: Login to GitHub Container Registry uses: docker/login-action@v3 + if: (github.event_name != 'pull_request') with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: | + ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest + ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ steps.commit.outputs.sha }} - - name: Publish images - if: (github.event_name != 'pull_request') - env: - owner: ${{ github.repository_owner }} - reponame: ${{ github.event.repository.name }} - run: | - docker push ghcr.io/${owner}/${reponame}:latest - docker push ghcr.io/${owner}/${reponame}:${GITHUB_SHA::8} - - docker push ghcr.io/${owner}/${reponame}/gnoland-slim:latest - docker push ghcr.io/${owner}/${reponame}/gnoland-slim:${GITHUB_SHA::8} + build-slim: + runs-on: ubuntu-latest + strategy: + matrix: + target: [gnoland, gnoland-slim, gnokey-slim, gno-slim, gnofaucet-slim, gnoweb-slim] + steps: + - name: Checkout + uses: actions/checkout@v4 - docker push ghcr.io/${owner}/${reponame}/gnokey-slim:latest - docker push ghcr.io/${owner}/${reponame}/gnokey-slim:${GITHUB_SHA::8} + - name: Get commit SHA + id: commit + run: echo "sha=${GITHUB_SHA::8}" >> "$GITHUB_OUTPUT" - docker push ghcr.io/${owner}/${reponame}/gno-slim:latest - docker push ghcr.io/${owner}/${reponame}/gno-slim:${GITHUB_SHA::8} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - docker push ghcr.io/${owner}/${reponame}/gnofaucet-slim:latest - docker push ghcr.io/${owner}/${reponame}/gnofaucet-slim:${GITHUB_SHA::8} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - docker push ghcr.io/${owner}/${reponame}/gnoweb-slim:latest - docker push ghcr.io/${owner}/${reponame}/gnoweb-slim:${GITHUB_SHA::8} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + if: (github.event_name != 'pull_request') + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: | + ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/${{ matrix.target }}:latest + ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/${{ matrix.target }}:${{ steps.commit.outputs.sha }} From 35a29a5479f0f9e916ba4fbd49bea7e7f7a5dfde Mon Sep 17 00:00:00 2001 From: Guilhem Fanton <8671905+gfanton@users.noreply.github.com> Date: Thu, 11 Apr 2024 23:11:39 +0200 Subject: [PATCH 15/19] fix(docker): fix docker action by adding build target (#1920) --- .github/workflows/docker.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index fe0c068fbc2..0b4def650c0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -49,7 +49,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: [gnoland, gnoland-slim, gnokey-slim, gno-slim, gnofaucet-slim, gnoweb-slim] + target: [gnoland-slim, gnokey-slim, gno-slim, gnofaucet-slim, gnoweb-slim] steps: - name: Checkout uses: actions/checkout@v4 @@ -77,6 +77,7 @@ jobs: with: context: . platforms: linux/amd64,linux/arm64 + target: ${{ matrix.target }} push: ${{ github.event_name != 'pull_request' }} tags: | ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/${{ matrix.target }}:latest From 6cb2ab89cd534517e4baf98a84d9d427f53c076b Mon Sep 17 00:00:00 2001 From: Hariom Verma Date: Fri, 12 Apr 2024 14:06:56 +0530 Subject: [PATCH 16/19] fix(stdlibs/io): handle potential overflow in `NewSectionReader` (#1905) `NewSectionReader` sets `remaining` to `maxInt64` (i.e `1<<63 - 1`) in case of overflow, but it remained unused. `SectionReader.limit` is always set to `n+off`. Utilize `remaining` to handle overflow. --- gnovm/stdlibs/io/io.gno | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnovm/stdlibs/io/io.gno b/gnovm/stdlibs/io/io.gno index 6ee52cfe293..e1c8de731b6 100644 --- a/gnovm/stdlibs/io/io.gno +++ b/gnovm/stdlibs/io/io.gno @@ -488,7 +488,7 @@ func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader { // Assume we can read up to an offset of `1<<63 - 1` bytes in this case. remaining = maxInt64 } - return &SectionReader{r, off, off, off + n} + return &SectionReader{r, off, off, remaining} } // SectionReader implements Read, Seek, and ReadAt on a section From d44c9a5dcd28c5800c9529f47be168f38ebb0ffa Mon Sep 17 00:00:00 2001 From: Kouteki Date: Fri, 12 Apr 2024 11:19:40 +0200 Subject: [PATCH 17/19] fix: typo in portal-loop.md (#1918) Just a documentation typo fixed. It's not much, but it's honest work. --- docs/concepts/portal-loop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/portal-loop.md b/docs/concepts/portal-loop.md index f335013034d..10772cc5126 100644 --- a/docs/concepts/portal-loop.md +++ b/docs/concepts/portal-loop.md @@ -8,7 +8,7 @@ Portal Loop is an always-up-to-date staging testnet that allows for using the latest version of Gno, Gno.land, and TM2. By utilizing the power of Docker & the [tx-archive](https://github.com/gnolang/tx-archive) tool, the Portal Loop can run the latest code from the master branch on the [Gno monorepo](https://github.com/gnolang/gno), -while preserving most/all the previous the transaction data. +while preserving most/all of the previous transaction data. The Portal Loop allows for quick iteration on the latest version of Gno - without having to make a hard/soft fork. From 0cf65eef70b82abbee85a39dec6772db375e21e6 Mon Sep 17 00:00:00 2001 From: Guilhem Fanton <8671905+gfanton@users.noreply.github.com> Date: Sun, 14 Apr 2024 11:15:04 +0200 Subject: [PATCH 18/19] feat: improve gnodev logging (#1790) --- contribs/gnodev/go.mod | 10 ++ contribs/gnodev/go.sum | 24 +++ contribs/gnodev/main.go | 205 +++++++++++++---------- contribs/gnodev/pkg/dev/node.go | 91 +++++++--- contribs/gnodev/pkg/logger/colors.go | 60 +++++++ contribs/gnodev/pkg/logger/log_column.go | 199 ++++++++++++++++++++++ contribs/gnodev/pkg/logger/log_zap.go | 38 +++++ contribs/gnodev/pkg/rawterm/rawterm.go | 114 ++----------- gno.land/pkg/gnoland/app.go | 42 +++-- gno.land/pkg/gnoland/node_inmemory.go | 25 +-- gno.land/pkg/integration/testing_node.go | 7 +- 11 files changed, 573 insertions(+), 242 deletions(-) create mode 100644 contribs/gnodev/pkg/logger/colors.go create mode 100644 contribs/gnodev/pkg/logger/log_column.go create mode 100644 contribs/gnodev/pkg/logger/log_zap.go diff --git a/contribs/gnodev/go.mod b/contribs/gnodev/go.mod index 2f74709f360..9a9d1a9f798 100644 --- a/contribs/gnodev/go.mod +++ b/contribs/gnodev/go.mod @@ -5,15 +5,19 @@ go 1.21 replace github.com/gnolang/gno => ../.. require ( + github.com/charmbracelet/lipgloss v0.9.1 + github.com/charmbracelet/log v0.3.1 github.com/fsnotify/fsnotify v1.7.0 github.com/gnolang/gno v0.0.0-00010101000000-000000000000 github.com/gorilla/websocket v1.5.1 + github.com/muesli/termenv v0.15.2 go.uber.org/zap v1.27.0 golang.org/x/term v0.18.0 ) require ( dario.cat/mergo v1.0.0 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -22,6 +26,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -33,10 +38,15 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/jaekwon/testify v1.6.1 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/muesli/reflow v0.3.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/peterbourgon/ff/v3 v3.4.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rivo/uniseg v0.4.3 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.10.1 // indirect github.com/stretchr/testify v1.9.0 // indirect diff --git a/contribs/gnodev/go.sum b/contribs/gnodev/go.sum index 57943aa60ee..028c3f6f56e 100644 --- a/contribs/gnodev/go.sum +++ b/contribs/gnodev/go.sum @@ -1,6 +1,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd h1:js1gPwhcFflTZ7Nzl7WHaOTlTr5hIrR4n1NM4v9n4Kw= @@ -28,6 +30,10 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= +github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= +github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw= +github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= @@ -51,6 +57,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 h1:GKvsK3oLWG9B1GL7WP/VqwM6C92j5tIvB844oggL9Lk= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:xJhtEL7ahjM1WJipt89gel8tHzfIl/LyMY+lCYh38d8= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -108,6 +116,17 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/linxGnu/grocksdb v1.6.20 h1:C0SNv12/OBr/zOdGw6reXS+mKpIdQGb/AkZWjHYnO64= github.com/linxGnu/grocksdb v1.6.20/go.mod h1:IbTMGpmWg/1pg2hcG9LlxkqyqiJymdCweaUrzsLRFmg= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= @@ -129,6 +148,10 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= @@ -194,6 +217,7 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= diff --git a/contribs/gnodev/main.go b/contribs/gnodev/main.go index df68bf54bec..6e6d12fcbdc 100644 --- a/contribs/gnodev/main.go +++ b/contribs/gnodev/main.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "io" + "log/slog" "net" "net/http" "os" @@ -12,27 +13,28 @@ import ( "strings" "time" + "github.com/charmbracelet/lipgloss" "github.com/fsnotify/fsnotify" "github.com/gnolang/gno/contribs/gnodev/pkg/dev" gnodev "github.com/gnolang/gno/contribs/gnodev/pkg/dev" "github.com/gnolang/gno/contribs/gnodev/pkg/emitter" + "github.com/gnolang/gno/contribs/gnodev/pkg/logger" "github.com/gnolang/gno/contribs/gnodev/pkg/rawterm" "github.com/gnolang/gno/contribs/gnodev/pkg/watcher" "github.com/gnolang/gno/gno.land/pkg/gnoweb" - "github.com/gnolang/gno/gno.land/pkg/log" + zaplog "github.com/gnolang/gno/gno.land/pkg/log" "github.com/gnolang/gno/gnovm/pkg/gnoenv" "github.com/gnolang/gno/gnovm/pkg/gnomod" "github.com/gnolang/gno/tm2/pkg/commands" osm "github.com/gnolang/gno/tm2/pkg/os" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" + "github.com/muesli/termenv" ) const ( NodeLogName = "Node" WebLogName = "GnoWeb" KeyPressLogName = "KeyPress" - EventServerLogName = "Events" + EventServerLogName = "Event" ) type devCfg struct { @@ -41,13 +43,14 @@ type devCfg struct { nodeP2PListenerAddr string nodeProxyAppListenerAddr string - minimal bool - verbose bool - hotreload bool - noWatch bool - noReplay bool - maxGas int64 - chainId string + minimal bool + verbose bool + hotreload bool + noWatch bool + noReplay bool + maxGas int64 + chainId string + serverMode bool } var defaultDevOptions = &devCfg{ @@ -105,6 +108,13 @@ func (c *devCfg) RegisterFlags(fs *flag.FlagSet) { "do not load packages from examples directory", ) + fs.BoolVar( + &c.serverMode, + "server-mode", + defaultDevOptions.serverMode, + "disable interaction, and adjust logging for server use.", + ) + fs.BoolVar( &c.verbose, "verbose", @@ -141,7 +151,7 @@ func (c *devCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execDev(cfg *devCfg, args []string, io commands.IO) error { +func execDev(cfg *devCfg, args []string, io commands.IO) (err error) { ctx, cancel := context.WithCancelCause(context.Background()) defer cancel(nil) @@ -160,7 +170,7 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error { } // Setup Raw Terminal - rt, restore, err := setupRawTerm(io) + rt, restore, err := setupRawTerm(cfg, io) if err != nil { return fmt.Errorf("unable to init raw term: %w", err) } @@ -168,25 +178,28 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error { // Setup trap signal osm.TrapSignal(func() { - restore() cancel(nil) + restore() }) - zapLoggerEvents := NewZapLogger(rt.NamespacedWriter(EventServerLogName), zapcore.DebugLevel) - loggerEvents := log.ZapLoggerToSlog(zapLoggerEvents) + logger := setuplogger(cfg, rt) + loggerEvents := logger.WithGroup(EventServerLogName) emitterServer := emitter.NewServer(loggerEvents) // Setup Dev Node // XXX: find a good way to export or display node logs - devNode, err := setupDevNode(ctx, cfg, emitterServer, rt, pkgpaths) + devNode, err := setupDevNode(ctx, logger, cfg, emitterServer, pkgpaths) if err != nil { return err } defer devNode.Close() - rt.Taskf(NodeLogName, "Listener: %s\n", devNode.GetRemoteAddress()) - rt.Taskf(NodeLogName, "Default Address: %s\n", gnodev.DefaultCreator.String()) - rt.Taskf(NodeLogName, "Chain ID: %s\n", cfg.chainId) + logger.WithGroup(NodeLogName). + Info("node started", + "lisn", devNode.GetRemoteAddress(), + "addr", gnodev.DefaultCreator.String(), + "chainID", cfg.chainId, + ) // Create server mux := http.NewServeMux() @@ -197,7 +210,7 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error { defer server.Close() // Setup gnoweb - webhandler := setupGnoWebServer(cfg, devNode, rt) + webhandler := setupGnoWebServer(logger.WithGroup(WebLogName), cfg, devNode) // Setup HotReload if needed if !cfg.noWatch { @@ -213,7 +226,9 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error { cancel(err) }() - rt.Taskf(WebLogName, "Listener: http://%s\n", server.Addr) + logger.WithGroup(WebLogName). + Info("gnoweb started", + "lisn", fmt.Sprintf("http://%s", server.Addr)) watcher, err := watcher.NewPackageWatcher(loggerEvents, emitterServer) if err != nil { @@ -224,35 +239,28 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error { // Add node pkgs to watcher watcher.AddPackages(devNode.ListPkgs()...) - // GnoDev should be ready, run event loop - rt.Taskf("[Ready]", "for commands and help, press `h`") + logger.WithGroup("--- READY").Info("for commands and help, press `h`") // Run the main event loop - return runEventLoop(ctx, cfg, rt, devNode, watcher) + return runEventLoop(ctx, logger, rt, devNode, watcher) } -// XXX: Automatize this the same way command does -func printHelper(rt *rawterm.RawTerm) { - rt.Taskf("Helper", ` -Gno Dev Helper: - H Help - display this message - R Reload - Reload all packages to take change into account. - Ctrl+R Reset - Reset application state. - Ctrl+C Exit - Exit the application -`) -} +var helper string = ` +H Help - display this message +R Reload - Reload all packages to take change into account. +Ctrl+R Reset - Reset application state. +Ctrl+C Exit - Exit the application +` func runEventLoop( ctx context.Context, - cfg *devCfg, + logger *slog.Logger, rt *rawterm.RawTerm, dnode *dev.Node, watch *watcher.PackageWatcher, ) error { - nodeOut := rt.NamespacedWriter(NodeLogName) - keyOut := rt.NamespacedWriter(KeyPressLogName) - keyPressCh := listenForKeyPress(keyOut, rt) + keyPressCh := listenForKeyPress(logger.WithGroup(KeyPressLogName), rt) for { var err error @@ -264,41 +272,54 @@ func runEventLoop( return nil } - fmt.Fprintln(nodeOut, "Loading package updates...") + // fmt.Fprintln(nodeOut, "Loading package updates...") if err = dnode.UpdatePackages(pkgs.PackagesPath()...); err != nil { return fmt.Errorf("unable to update packages: %w", err) } - fmt.Fprintln(nodeOut, "Reloading...") - err = dnode.Reload(ctx) - - checkForError(rt, err) + logger.WithGroup(NodeLogName).Info("reloading...") + if err = dnode.Reload(ctx); err != nil { + logger.WithGroup(NodeLogName). + Error("unable to reload node", "err", err) + } case key, ok := <-keyPressCh: if !ok { return nil } - if cfg.verbose { - fmt.Fprintf(keyOut, "<%s>\n", key.String()) - } + logger.WithGroup(KeyPressLogName).Debug( + fmt.Sprintf("<%s>", key.String()), + ) switch key.Upper() { case rawterm.KeyH: - printHelper(rt) + logger.Info("Gno Dev Helper", "helper", helper) case rawterm.KeyR: - fmt.Fprintln(nodeOut, "Reloading all packages...") - checkForError(nodeOut, dnode.ReloadAll(ctx)) + logger.WithGroup(NodeLogName).Info("reloading...") + if err = dnode.ReloadAll(ctx); err != nil { + logger.WithGroup(NodeLogName). + Error("unable to reload node", "err", err) + + } + case rawterm.KeyCtrlR: - fmt.Fprintln(nodeOut, "Reseting state...") - checkForError(nodeOut, dnode.Reset(ctx)) + logger.WithGroup(NodeLogName).Info("reseting node state...") + if err = dnode.Reset(ctx); err != nil { + logger.WithGroup(NodeLogName). + Error("unable to reset node state", "err", err) + } + case rawterm.KeyCtrlC: return nil + case rawterm.KeyCtrlE: + panic("NOOOO") + return nil default: } - // Listen for the next keypress - keyPressCh = listenForKeyPress(keyOut, rt) + // Reset listen for the next keypress + keyPressCh = listenForKeyPress(logger.WithGroup(KeyPressLogName), rt) } } } @@ -348,15 +369,20 @@ func runPkgsWatcher(ctx context.Context, cfg *devCfg, pkgs []gnomod.Pkg, changed } } -func setupRawTerm(io commands.IO) (rt *rawterm.RawTerm, restore func() error, err error) { - rt = rawterm.NewRawTerm() +var noopRestore = func() error { return nil } - restore, err = rt.Init() - if err != nil { - return nil, nil, err +func setupRawTerm(cfg *devCfg, io commands.IO) (*rawterm.RawTerm, func() error, error) { + rt := rawterm.NewRawTerm() + restore := noopRestore + if !cfg.serverMode { + var err error + restore, err = rt.Init() + if err != nil { + return nil, nil, err + } } - // Correctly format output for terminal + // correctly format output for terminal io.SetOut(commands.WriteNopCloser(rt)) return rt, restore, nil } @@ -364,13 +390,12 @@ func setupRawTerm(io commands.IO) (rt *rawterm.RawTerm, restore func() error, er // setupDevNode initializes and returns a new DevNode. func setupDevNode( ctx context.Context, + logger *slog.Logger, cfg *devCfg, remitter emitter.Emitter, - rt *rawterm.RawTerm, pkgspath []string, ) (*gnodev.Node, error) { - nodeOut := rt.NamespacedWriter("Node") - zapLogger := NewZapLogger(nodeOut, zapcore.ErrorLevel) + nodeLogger := logger.WithGroup(NodeLogName) gnoroot := gnoenv.RootDir() @@ -379,7 +404,6 @@ func setupDevNode( config.PackagesPathList = pkgspath config.TMConfig.RPC.ListenAddress = resolveUnixOrTCPAddr(cfg.nodeRPCListenerAddr) config.NoReplay = cfg.noReplay - config.SkipFailingGenesisTxs = true config.MaxGasPerBlock = cfg.maxGas config.ChainID = cfg.chainId @@ -387,18 +411,17 @@ func setupDevNode( config.TMConfig.P2P.ListenAddress = defaultDevOptions.nodeP2PListenerAddr config.TMConfig.ProxyApp = defaultDevOptions.nodeProxyAppListenerAddr - return gnodev.NewDevNode(ctx, log.ZapLoggerToSlog(zapLogger), remitter, config) + return gnodev.NewDevNode(ctx, nodeLogger, remitter, config) } // setupGnowebServer initializes and starts the Gnoweb server. -func setupGnoWebServer(cfg *devCfg, dnode *gnodev.Node, rt *rawterm.RawTerm) http.Handler { +func setupGnoWebServer(logger *slog.Logger, cfg *devCfg, dnode *gnodev.Node) http.Handler { webConfig := gnoweb.NewDefaultConfig() webConfig.RemoteAddr = dnode.GetRemoteAddress() webConfig.HelpRemote = dnode.GetRemoteAddress() webConfig.HelpChainID = cfg.chainId - zapLogger := NewZapLogger(rt.NamespacedWriter("GnoWeb"), zapcore.DebugLevel) - app := gnoweb.MakeApp(log.ZapLoggerToSlog(zapLogger), webConfig) + app := gnoweb.MakeApp(logger, webConfig) return app.Router } @@ -421,13 +444,13 @@ func parseArgsPackages(args []string) (paths []string, err error) { return paths, nil } -func listenForKeyPress(w io.Writer, rt *rawterm.RawTerm) <-chan rawterm.KeyPress { +func listenForKeyPress(logger *slog.Logger, rt *rawterm.RawTerm) <-chan rawterm.KeyPress { cc := make(chan rawterm.KeyPress, 1) go func() { defer close(cc) key, err := rt.ReadKeyPress() if err != nil { - fmt.Fprintf(w, "unable to read keypress: %s\n", err.Error()) + logger.Error("unable to read keypress", "err", err) return } @@ -437,15 +460,6 @@ func listenForKeyPress(w io.Writer, rt *rawterm.RawTerm) <-chan rawterm.KeyPress return cc } -func checkForError(w io.Writer, err error) { - if err != nil { - fmt.Fprintf(w, "[ERROR] - %s\n", err.Error()) - return - } - - fmt.Fprintln(w, "[DONE]") -} - func resolveUnixOrTCPAddr(in string) (out string) { var err error var addr net.Addr @@ -469,15 +483,26 @@ func resolveUnixOrTCPAddr(in string) (out string) { panic(err) } -// NewZapLogger creates a zap logger with a console encoder for development use. -func NewZapLogger(w io.Writer, level zapcore.Level) *zap.Logger { - // Build encoder config - consoleConfig := zap.NewDevelopmentEncoderConfig() - consoleConfig.TimeKey = "" - consoleConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder - consoleConfig.EncodeName = zapcore.FullNameEncoder - - // Build encoder - enc := zapcore.NewConsoleEncoder(consoleConfig) - return log.NewZapLogger(enc, w, level) +func setuplogger(cfg *devCfg, out io.Writer) *slog.Logger { + level := slog.LevelInfo + if cfg.verbose { + level = slog.LevelDebug + } + + if cfg.serverMode { + zaplogger := logger.NewZapLogger(out, level) + return zaplog.ZapLoggerToSlog(zaplogger) + } + + // Detect term color profile + colorProfile := termenv.DefaultOutput().Profile + clogger := logger.NewColumnLogger(out, level, colorProfile) + + // Register well known group color with system colors + clogger.RegisterGroupColor(NodeLogName, lipgloss.Color("3")) + clogger.RegisterGroupColor(WebLogName, lipgloss.Color("4")) + clogger.RegisterGroupColor(KeyPressLogName, lipgloss.Color("5")) + clogger.RegisterGroupColor(EventServerLogName, lipgloss.Color("6")) + + return slog.New(clogger) } diff --git a/contribs/gnodev/pkg/dev/node.go b/contribs/gnodev/pkg/dev/node.go index 23ac66a5f9a..02d97dff733 100644 --- a/contribs/gnodev/pkg/dev/node.go +++ b/contribs/gnodev/pkg/dev/node.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "log/slog" + "strings" + "unicode" "github.com/gnolang/gno/contribs/gnodev/pkg/emitter" "github.com/gnolang/gno/contribs/gnodev/pkg/events" @@ -17,18 +19,19 @@ import ( bft "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/crypto" tm2events "github.com/gnolang/gno/tm2/pkg/events" + "github.com/gnolang/gno/tm2/pkg/log" + "github.com/gnolang/gno/tm2/pkg/sdk" "github.com/gnolang/gno/tm2/pkg/std" // backup "github.com/gnolang/tx-archive/backup/client" // restore "github.com/gnolang/tx-archive/restore/client" ) type NodeConfig struct { - PackagesPathList []string - TMConfig *tmcfg.Config - SkipFailingGenesisTxs bool - NoReplay bool - MaxGasPerBlock int64 - ChainID string + PackagesPathList []string + TMConfig *tmcfg.Config + NoReplay bool + MaxGasPerBlock int64 + ChainID string } func DefaultNodeConfig(rootdir string) *NodeConfig { @@ -36,11 +39,10 @@ func DefaultNodeConfig(rootdir string) *NodeConfig { tmc.Consensus.SkipTimeoutCommit = false // avoid time drifting, see issue #1507 return &NodeConfig{ - ChainID: tmc.ChainID(), - PackagesPathList: []string{}, - TMConfig: tmc, - SkipFailingGenesisTxs: true, - MaxGasPerBlock: 10_000_000_000, + ChainID: tmc.ChainID(), + PackagesPathList: []string{}, + TMConfig: tmc, + MaxGasPerBlock: 10_000_000_000, } } @@ -80,6 +82,8 @@ func NewDevNode(ctx context.Context, logger *slog.Logger, emitter emitter.Emitte return nil, fmt.Errorf("unable to load genesis packages: %w", err) } + logger.Info("pkgs loaded", "path", cfg.PackagesPathList) + // generate genesis state genesis := gnoland.GnoGenesisState{ Balances: DefaultBalance, @@ -125,6 +129,7 @@ func (d *Node) GetRemoteAddress() string { // UpdatePackages updates the currently known packages. It will be taken into // consideration in the next reload of the node. func (d *Node) UpdatePackages(paths ...string) error { + var n int for _, path := range paths { // List all packages from target path pkgslist, err := gnomod.ListPkgs(path) @@ -135,9 +140,13 @@ func (d *Node) UpdatePackages(paths ...string) error { // Update or add package in the current known list. for _, pkg := range pkgslist { d.pkgs[pkg.Dir] = pkg + d.logger.Debug("pkgs update", "name", pkg.Name, "path", pkg.Dir) } + + n += len(pkgslist) } + d.logger.Info(fmt.Sprintf("updated %d pacakges", n)) return nil } @@ -230,6 +239,36 @@ func (d *Node) Reload(ctx context.Context) error { return nil } +func (d *Node) genesisTxHandler(ctx sdk.Context, tx std.Tx, res sdk.Result) { + if res.IsErr() { + // XXX: for now, this is only way to catch the error + before, after, found := strings.Cut(res.Log, "\n") + if !found { + d.logger.Error("unable to send tx", "err", res.Error, "log", res.Log) + return + } + + var attrs []slog.Attr + + // Add error + attrs = append(attrs, slog.Any("err", res.Error)) + + // Fetch first line as error message + msg := strings.TrimFunc(before, func(r rune) bool { + return unicode.IsSpace(r) || r == ':' + }) + attrs = append(attrs, slog.String("err", msg)) + + // If debug is enable, also append stack + if d.logger.Enabled(context.Background(), slog.LevelDebug) { + attrs = append(attrs, slog.String("stack", after)) + + } + + d.logger.LogAttrs(context.Background(), slog.LevelError, "unable to deliver tx", attrs...) + } +} + // GetBlockTransactions returns the transactions contained // within the specified block, if any func (d *Node) GetBlockTransactions(blockNum uint64) ([]std.Tx, error) { @@ -322,30 +361,30 @@ func (n *Node) stopIfRunning() error { return nil } -func (n *Node) reset(ctx context.Context, genesis gnoland.GnoGenesisState) error { +func (n *Node) reset(ctx context.Context, genesis gnoland.GnoGenesisState) (err error) { // Setup node config nodeConfig := newNodeConfig(n.config.TMConfig, n.config.ChainID, genesis) - nodeConfig.SkipFailingGenesisTxs = n.config.SkipFailingGenesisTxs + nodeConfig.GenesisTxHandler = n.genesisTxHandler nodeConfig.Genesis.ConsensusParams.Block.MaxGas = n.config.MaxGasPerBlock - var recoverErr error - // recoverFromError handles panics and converts them to errors. recoverFromError := func() { if r := recover(); r != nil { - var ok bool - if recoverErr, ok = r.(error); !ok { - panic(r) // Re-panic if not an error. + switch val := r.(type) { + case error: + err = val + case string: + err = fmt.Errorf("error: %s", val) + default: + err = fmt.Errorf("unknown error: %#v", val) } } } // Execute node creation and handle any errors. defer recoverFromError() + node, nodeErr := buildNode(n.logger, n.emitter, nodeConfig) - if recoverErr != nil { // First check for recover error in case of panic - return fmt.Errorf("recovered from a node panic: %w", recoverErr) - } if nodeErr != nil { // Then for any node error return fmt.Errorf("unable to build the node: %w", nodeErr) } @@ -361,8 +400,11 @@ func (n *Node) reset(ctx context.Context, genesis gnoland.GnoGenesisState) error return nil } +var noopLogger = log.NewNoopLogger() + func buildNode(logger *slog.Logger, emitter emitter.Emitter, cfg *gnoland.InMemoryNodeConfig) (*node.Node, error) { - node, err := gnoland.NewInMemoryNode(logger, cfg) + // XXX(TODO): Redirect the node log somewhere else + node, err := gnoland.NewInMemoryNode(noopLogger, cfg) if err != nil { return nil, fmt.Errorf("unable to create a new node: %w", err) } @@ -371,8 +413,9 @@ func buildNode(logger *slog.Logger, emitter emitter.Emitter, cfg *gnoland.InMemo switch data := evt.(type) { case bft.EventTx: resEvt := events.TxResult{ - Height: data.Result.Height, - Index: data.Result.Index, + Height: data.Result.Height, + Index: data.Result.Index, + // XXX: Update this to split error for stack Response: data.Result.Response, } diff --git a/contribs/gnodev/pkg/logger/colors.go b/contribs/gnodev/pkg/logger/colors.go new file mode 100644 index 00000000000..b0499e01722 --- /dev/null +++ b/contribs/gnodev/pkg/logger/colors.go @@ -0,0 +1,60 @@ +package logger + +import ( + "fmt" + "hash/fnv" + "math" + + "github.com/charmbracelet/lipgloss" +) + +func colorFromString(s string, saturation, lightness float64) lipgloss.Color { + hue := float64(hash32a(s) % 360) + + r, g, b := hslToRGB(float64(hue), saturation, lightness) + hex := rgbToHex(r, g, b) + return lipgloss.Color(hex) +} + +func hash32a(s string) uint32 { + h := fnv.New32a() + h.Write([]byte(s)) + return h.Sum32() +} + +// from: https://www.rapidtables.com/convert/color/hsl-to-rgb.html +// hslToRGB converts an HSL triple to an RGB triple. +func hslToRGB(h, s, l float64) (r, g, b uint8) { + if h < 0 || h >= 360 || s < 0 || s > 1 || l < 0 || l > 1 { + return 0, 0, 0 + } + + C := (1 - math.Abs((2*l)-1)) * s + X := C * (1 - math.Abs(math.Mod(h/60, 2)-1)) + m := l - (C / 2) + + var rNot, gNot, bNot float64 + switch { + case 0 <= h && h < 60: + rNot, gNot, bNot = C, X, 0 + case 60 <= h && h < 120: + rNot, gNot, bNot = X, C, 0 + case 120 <= h && h < 180: + rNot, gNot, bNot = 0, C, X + case 180 <= h && h < 240: + rNot, gNot, bNot = 0, X, C + case 240 <= h && h < 300: + rNot, gNot, bNot = X, 0, C + case 300 <= h && h < 360: + rNot, gNot, bNot = C, 0, X + } + + r = uint8(math.Round((rNot + m) * 255)) + g = uint8(math.Round((gNot + m) * 255)) + b = uint8(math.Round((bNot + m) * 255)) + return r, g, b +} + +func rgbToHex(r, g, b uint8) string { + return fmt.Sprintf("#%02X%02X%02X", r, g, b) +} diff --git a/contribs/gnodev/pkg/logger/log_column.go b/contribs/gnodev/pkg/logger/log_column.go new file mode 100644 index 00000000000..8e145e89175 --- /dev/null +++ b/contribs/gnodev/pkg/logger/log_column.go @@ -0,0 +1,199 @@ +package logger + +import ( + "bytes" + "fmt" + "io" + "log/slog" + "strings" + "sync" + + "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/log" + "github.com/muesli/termenv" +) + +func NewColumnLogger(w io.Writer, level slog.Level, profile termenv.Profile) *ColumnLogger { + charmLogger := log.NewWithOptions(w, log.Options{ + ReportTimestamp: false, + ReportCaller: false, + Prefix: "", + }) + + // Default column output + defaultOutput := newColumeWriter(lipgloss.NewStyle(), "", w) + charmLogger.SetOutput(defaultOutput) + charmLogger.SetStyles(defaultStyles()) + charmLogger.SetColorProfile(profile) + charmLogger.SetReportCaller(false) + switch level { + case slog.LevelDebug: + charmLogger.SetLevel(log.DebugLevel) + case slog.LevelError: + charmLogger.SetLevel(log.ErrorLevel) + case slog.LevelInfo: + charmLogger.SetLevel(log.InfoLevel) + case slog.LevelWarn: + charmLogger.SetLevel(log.WarnLevel) + default: + panic("invalid slog level") + } + + return &ColumnLogger{ + Logger: charmLogger, + writer: w, + prefix: charmLogger.GetPrefix(), + colors: map[string]lipgloss.Color{}, + } +} + +type ColumnLogger struct { + *log.Logger + + prefix string + writer io.Writer + colorProfile termenv.Profile + + colors map[string]lipgloss.Color + muColors sync.RWMutex +} + +func (cl *ColumnLogger) WithGroup(group string) slog.Handler { + cl.muColors.RLock() + defer cl.muColors.RUnlock() + + if cl.prefix != "" { + group = fmt.Sprintf("%.1s.%s", cl.prefix, group) + } + + // check if we already know this group + fg, ok := cl.colors[group] + if !ok { + // generate bright color based on the group name + fg = colorFromString(group, 0.5, 0.6) + } + baseStyle := lipgloss.NewStyle().Foreground(fg) + + nlog := cl.Logger.With() // clone logger + nlog.SetOutput(newColumeWriter(baseStyle, group, cl.writer)) + nlog.SetColorProfile(cl.colorProfile) + return &ColumnLogger{ + Logger: nlog, + prefix: group, + writer: cl.writer, + } +} + +func (cl *ColumnLogger) RegisterGroupColor(group string, color lipgloss.Color) { + cl.muColors.Lock() + cl.colors[group] = color + cl.muColors.Unlock() +} + +var lf = []byte{'\n'} + +type columnWriter struct { + inline bool + style lipgloss.Style + prefix string + writer io.Writer +} + +func newColumeWriter(baseStyle lipgloss.Style, prefix string, writer io.Writer) *columnWriter { + const width = 12 + + style := baseStyle. + Border(lipgloss.ThickBorder(), false, true, false, false). + BorderForeground(baseStyle.GetForeground()). + Bold(true). + Width(width) + + if len(prefix) >= width { + prefix = prefix[:width-3] + "..." + } + + return &columnWriter{style: style, prefix: prefix, writer: writer} +} + +func (cl *columnWriter) Write(buf []byte) (n int, err error) { + for line := 0; len(buf) > 0; line++ { + i := bytes.IndexByte(buf, '\n') + todo := len(buf) + if i >= 0 { + todo = i + } + + if !cl.inline { + var prefix string + if line == 0 { + prefix = cl.prefix + } + + fmt.Fprint(cl.writer, cl.style.Render(prefix)+" ") + } + + var nn int + nn, err = cl.writer.Write(buf[:todo]) + n += nn + if err != nil { + return n, err + } + buf = buf[todo:] + + if cl.inline = i < 0; !cl.inline { + if _, err = cl.writer.Write([]byte(lf)); err != nil { + return n, err + } + n++ + buf = buf[1:] + } + } + + return n, nil +} + +// defaultStyles returns the default lipgloss styles for column logger +func defaultStyles() *log.Styles { + style := log.DefaultStyles() + style.Levels = map[log.Level]lipgloss.Style{ + log.DebugLevel: lipgloss.NewStyle(). + SetString(strings.ToUpper(log.DebugLevel.String())). + Bold(true). + MaxWidth(1). + Foreground(lipgloss.Color("63")), + log.InfoLevel: lipgloss.NewStyle(). + SetString(strings.ToUpper(log.InfoLevel.String())). + MaxWidth(1). + Foreground(lipgloss.Color("12")), + + log.WarnLevel: lipgloss.NewStyle(). + SetString(strings.ToUpper(log.WarnLevel.String())). + Bold(true). + MaxWidth(1). + Foreground(lipgloss.Color("192")), + log.ErrorLevel: lipgloss.NewStyle(). + SetString(strings.ToUpper(log.ErrorLevel.String())). + Bold(true). + MaxWidth(1). + Foreground(lipgloss.Color("204")), + log.FatalLevel: lipgloss.NewStyle(). + SetString(strings.ToUpper(log.FatalLevel.String())). + Bold(true). + MaxWidth(1). + Foreground(lipgloss.Color("134")), + } + style.Keys = map[string]lipgloss.Style{ + "err": lipgloss.NewStyle(). + Foreground(lipgloss.Color("204")), + "error": lipgloss.NewStyle(). + Foreground(lipgloss.Color("204")), + } + style.Values = map[string]lipgloss.Style{ + "err": lipgloss.NewStyle(). + Foreground(lipgloss.Color("204")), + "error": lipgloss.NewStyle(). + Foreground(lipgloss.Color("204")), + } + + return style +} diff --git a/contribs/gnodev/pkg/logger/log_zap.go b/contribs/gnodev/pkg/logger/log_zap.go new file mode 100644 index 00000000000..b7e5b34cc4e --- /dev/null +++ b/contribs/gnodev/pkg/logger/log_zap.go @@ -0,0 +1,38 @@ +package logger + +import ( + "io" + "log/slog" + + "github.com/gnolang/gno/gno.land/pkg/log" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func NewZapLogger(w io.Writer, slevel slog.Level) *zap.Logger { + // Build encoder config + consoleConfig := zap.NewDevelopmentEncoderConfig() + consoleConfig.EncodeCaller = zapcore.FullCallerEncoder + consoleConfig.EncodeTime = zapcore.RFC3339TimeEncoder + consoleConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + consoleConfig.EncodeName = zapcore.FullNameEncoder + + // Build encoder + enc := zapcore.NewConsoleEncoder(consoleConfig) + + var level zapcore.Level + switch slevel { + case slog.LevelDebug: + level = zapcore.DebugLevel + case slog.LevelError: + level = zapcore.ErrorLevel + case slog.LevelInfo: + level = zapcore.InfoLevel + case slog.LevelWarn: + level = zapcore.WarnLevel + default: + panic("invalid slog level") + } + + return log.NewZapLogger(enc, w, level) +} diff --git a/contribs/gnodev/pkg/rawterm/rawterm.go b/contribs/gnodev/pkg/rawterm/rawterm.go index f6d6e7534e2..58b8dde1530 100644 --- a/contribs/gnodev/pkg/rawterm/rawterm.go +++ b/contribs/gnodev/pkg/rawterm/rawterm.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "os" - "strings" "sync" "golang.org/x/term" @@ -17,16 +16,16 @@ var CRLF = []byte{'\r', '\n'} type RawTerm struct { syncWriter sync.Mutex - fsin *os.File - reader io.Reader - taskWriter TaskWriter + fsin *os.File + reader io.Reader + writer io.Writer } func NewRawTerm() *RawTerm { return &RawTerm{ - fsin: os.Stdin, - reader: os.Stdin, - taskWriter: &rawTaskWriter{os.Stdout}, + fsin: os.Stdin, + reader: os.Stdin, + writer: os.Stdout, } } @@ -38,38 +37,16 @@ func (rt *RawTerm) Init() (restore func() error, err error) { } rt.reader = rt.fsin - rt.taskWriter = &columnTaskWriter{os.Stdout} return func() error { return term.Restore(fd, oldstate) }, nil } -func (rt *RawTerm) Taskf(task string, format string, args ...interface{}) (n int, err error) { - format = strings.TrimSpace(format) - if len(args) > 0 { - str := fmt.Sprintf(format, args...) - return rt.taskWriter.WriteTask(task, []byte(str+"\n")) - } - - return rt.taskWriter.WriteTask(task, []byte(format+"\n")) -} - func (rt *RawTerm) Write(buf []byte) (n int, err error) { rt.syncWriter.Lock() defer rt.syncWriter.Unlock() - return rt.taskWriter.Write(buf) -} - -func (rt *RawTerm) WriteTask(name string, buf []byte) (n int, err error) { - rt.syncWriter.Lock() - defer rt.syncWriter.Unlock() - - return rt.taskWriter.WriteTask(name, buf) -} - -func (rt *RawTerm) NamespacedWriter(namepsace string) io.Writer { - return &namespaceWriter{namepsace, rt} + return writeWithCRLF(rt.writer, buf) } func (rt *RawTerm) read(buf []byte) (n int, err error) { @@ -85,31 +62,9 @@ func (rt *RawTerm) ReadKeyPress() (KeyPress, error) { return KeyPress(buf[0]), nil } -type namespaceWriter struct { - namespace string - writer TaskWriter -} - -func (r *namespaceWriter) Write(buf []byte) (n int, err error) { - return r.writer.WriteTask(r.namespace, buf) -} - -type TaskWriter interface { - io.Writer - WriteTask(task string, buf []byte) (n int, err error) -} - -type columnTaskWriter struct { - writer io.Writer -} - -func (r *columnTaskWriter) Write(buf []byte) (n int, err error) { - return r.WriteTask("", buf) -} - -func (r *columnTaskWriter) WriteTask(left string, buf []byte) (n int, err error) { - var nline int - for nline = 0; len(buf) > 0; nline++ { +// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n. +func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) { + for len(buf) > 0 { i := bytes.IndexByte(buf, '\n') todo := len(buf) if i >= 0 { @@ -117,23 +72,15 @@ func (r *columnTaskWriter) WriteTask(left string, buf []byte) (n int, err error) } var nn int - switch { - case nline == 0, left == "": // first line or left side is empty - nn, err = r.writeColumnLine(left, buf[:todo]) - case i < 0 || i+1 == len(buf): // last line - nn, err = r.writeColumnLine(" └─", buf[:todo]) - default: // middle lines - nn, err = r.writeColumnLine(" │", buf[:todo]) - } - + nn, err = w.Write(buf[:todo]) n += nn if err != nil { return n, err } buf = buf[todo:] - if i >= 0 { // always jump a line on the last line - if _, err = r.writer.Write(CRLF); err != nil { + if i >= 0 { + if _, err = w.Write(CRLF); err != nil { return n, err } n++ @@ -141,38 +88,5 @@ func (r *columnTaskWriter) WriteTask(left string, buf []byte) (n int, err error) } } - return -} - -func (r *columnTaskWriter) writeColumnLine(left string, line []byte) (n int, err error) { - // Write left column - if n, err = fmt.Fprintf(r.writer, "%-15s | ", left); err != nil { - return n, err - } - - // Write left line - var nn int - nn, err = r.writer.Write(line) - n += nn - - return -} - -type rawTaskWriter struct { - writer io.Writer -} - -func (r *rawTaskWriter) Write(buf []byte) (n int, err error) { - return r.writer.Write(buf) -} - -func (r *rawTaskWriter) WriteTask(task string, buf []byte) (n int, err error) { - if task != "" { - n, err = r.writer.Write([]byte(task + ": ")) - } - - var nn int - nn, err = r.writer.Write(buf) - n += nn - return + return n, nil } diff --git a/gno.land/pkg/gnoland/app.go b/gno.land/pkg/gnoland/app.go index cc15f74134e..f67b86fd735 100644 --- a/gno.land/pkg/gnoland/app.go +++ b/gno.land/pkg/gnoland/app.go @@ -28,17 +28,18 @@ type AppOptions struct { DB dbm.DB // `gnoRootDir` should point to the local location of the gno repository. // It serves as the gno equivalent of GOROOT. - GnoRootDir string - SkipFailingGenesisTxs bool - Logger *slog.Logger - MaxCycles int64 + GnoRootDir string + GenesisTxHandler GenesisTxHandler + Logger *slog.Logger + MaxCycles int64 } func NewAppOptions() *AppOptions { return &AppOptions{ - Logger: log.NewNoopLogger(), - DB: memdb.NewMemDB(), - GnoRootDir: gnoenv.RootDir(), + GenesisTxHandler: PanicOnFailingTxHandler, + Logger: log.NewNoopLogger(), + DB: memdb.NewMemDB(), + GnoRootDir: gnoenv.RootDir(), } } @@ -81,7 +82,7 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) { vmKpr := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, stdlibsDir, cfg.MaxCycles) // Set InitChainer - baseApp.SetInitChainer(InitChainer(baseApp, acctKpr, bankKpr, cfg.SkipFailingGenesisTxs)) + baseApp.SetInitChainer(InitChainer(baseApp, acctKpr, bankKpr, cfg.GenesisTxHandler)) // Set AnteHandler authOptions := auth.AnteOptions{ @@ -127,7 +128,9 @@ func NewApp(dataRootDir string, skipFailingGenesisTxs bool, logger *slog.Logger, var err error cfg := NewAppOptions() - cfg.SkipFailingGenesisTxs = skipFailingGenesisTxs + if skipFailingGenesisTxs { + cfg.GenesisTxHandler = NoopGenesisTxHandler + } // Get main DB. cfg.DB, err = dbm.NewDB("gnolang", dbm.GoLevelDBBackend, filepath.Join(dataRootDir, "data")) @@ -140,8 +143,18 @@ func NewApp(dataRootDir string, skipFailingGenesisTxs bool, logger *slog.Logger, return NewAppWithOptions(cfg) } +type GenesisTxHandler func(ctx sdk.Context, tx std.Tx, res sdk.Result) + +func NoopGenesisTxHandler(ctx sdk.Context, tx std.Tx, res sdk.Result) {} + +func PanicOnFailingTxHandler(ctx sdk.Context, tx std.Tx, res sdk.Result) { + if res.IsErr() { + panic(res.Log) + } +} + // InitChainer returns a function that can initialize the chain with genesis. -func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank.BankKeeperI, skipFailingGenesisTxs bool) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain { +func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank.BankKeeperI, resHandler GenesisTxHandler) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain { return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { // Get genesis state. genState := req.AppState.(GnoGenesisState) @@ -154,21 +167,20 @@ func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank panic(err) } } + // Run genesis txs. for i, tx := range genState.Txs { res := baseApp.Deliver(tx) if res.IsErr() { ctx.Logger().Error("LOG", "log", res.Log) ctx.Logger().Error(fmt.Sprintf("#%d", i), "value", string(amino.MustMarshalJSON(tx))) - - // NOTE: comment out to ignore. - if !skipFailingGenesisTxs { - panic(res.Log) - } } else { ctx.Logger().Info("SUCCESS:", "value", string(amino.MustMarshalJSON(tx))) } + + resHandler(ctx, tx, res) } + // Done! return abci.ResponseInitChain{ Validators: req.Validators, diff --git a/gno.land/pkg/gnoland/node_inmemory.go b/gno.land/pkg/gnoland/node_inmemory.go index 89f222738d0..d48d0e2ab47 100644 --- a/gno.land/pkg/gnoland/node_inmemory.go +++ b/gno.land/pkg/gnoland/node_inmemory.go @@ -21,11 +21,11 @@ import ( ) type InMemoryNodeConfig struct { - PrivValidator bft.PrivValidator // identity of the validator - Genesis *bft.GenesisDoc - TMConfig *tmcfg.Config - SkipFailingGenesisTxs bool - GenesisMaxVMCycles int64 + PrivValidator bft.PrivValidator // identity of the validator + Genesis *bft.GenesisDoc + TMConfig *tmcfg.Config + GenesisTxHandler GenesisTxHandler + GenesisMaxVMCycles int64 } // NewMockedPrivValidator generate a new key @@ -82,6 +82,7 @@ func NewDefaultInMemoryNodeConfig(rootdir string) *InMemoryNodeConfig { PrivValidator: pv, TMConfig: tm, Genesis: genesis, + GenesisTxHandler: PanicOnFailingTxHandler, GenesisMaxVMCycles: 10_000_000, } } @@ -99,6 +100,10 @@ func (cfg *InMemoryNodeConfig) validate() error { return fmt.Errorf("`TMConfig.RootDir` is required to locate `stdlibs` directory") } + if cfg.GenesisTxHandler == nil { + return fmt.Errorf("`GenesisTxHandler` is required but not provided") + } + return nil } @@ -112,11 +117,11 @@ func NewInMemoryNode(logger *slog.Logger, cfg *InMemoryNodeConfig) (*node.Node, // Initialize the application with the provided options gnoApp, err := NewAppWithOptions(&AppOptions{ - Logger: logger, - GnoRootDir: cfg.TMConfig.RootDir, - SkipFailingGenesisTxs: cfg.SkipFailingGenesisTxs, - MaxCycles: cfg.GenesisMaxVMCycles, - DB: memdb.NewMemDB(), + Logger: logger, + GnoRootDir: cfg.TMConfig.RootDir, + GenesisTxHandler: cfg.GenesisTxHandler, + MaxCycles: cfg.GenesisMaxVMCycles, + DB: memdb.NewMemDB(), }) if err != nil { return nil, fmt.Errorf("error initializing new app: %w", err) diff --git a/gno.land/pkg/integration/testing_node.go b/gno.land/pkg/integration/testing_node.go index 106c5b14bb8..16b23b6565c 100644 --- a/gno.land/pkg/integration/testing_node.go +++ b/gno.land/pkg/integration/testing_node.go @@ -71,9 +71,10 @@ func TestingMinimalNodeConfig(t TestingTS, gnoroot string) *gnoland.InMemoryNode genesis := DefaultTestingGenesisConfig(t, gnoroot, pv.GetPubKey(), tmconfig) return &gnoland.InMemoryNodeConfig{ - PrivValidator: pv, - Genesis: genesis, - TMConfig: tmconfig, + PrivValidator: pv, + Genesis: genesis, + TMConfig: tmconfig, + GenesisTxHandler: gnoland.PanicOnFailingTxHandler, } } From 54bd960bf8f6940cb809254d81b755e0b07b3437 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:18:52 +0200 Subject: [PATCH 19/19] chore(deps): Bump the everything-else group with 3 updates (#1928) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the everything-else group with 3 updates: [github.com/decred/dcrd/dcrec/secp256k1/v4](https://github.com/decred/dcrd), [github.com/gnolang/faucet](https://github.com/gnolang/faucet) and [github.com/btcsuite/btcd/btcec/v2](https://github.com/btcsuite/btcd). Updates `github.com/decred/dcrd/dcrec/secp256k1/v4` from 4.2.0 to 4.3.0
Commits
  • 08d8572 secp256k1: Prepare v4.3.0.
  • fe9a28c secp256k1: No allocs in slow scalar base mult path.
  • 2104419 wire: Fix typo in comment.
  • b9d8d49 wire: add p2p mixing messages
  • 25adf60 secp256k1: Add scalar base mult variant benchmarks.
  • 2ee2ebe secp256k1: Add TinyGo support.
  • c6322d5 docker: Update image to golang:1.22.1-alpine3.19.
  • 20dedca server: Update required minimum protocol version.
  • eb3de8e docs: Update README.md to required Go 1.21/1.22.
  • fedbaf9 build: Test against Go 1.22.
  • Additional commits viewable in compare view

Updates `github.com/gnolang/faucet` from 0.1.3 to 0.2.0
Release notes

Sourced from github.com/gnolang/faucet's releases.

v0.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/gnolang/faucet/compare/v0.1.3...v0.2.0

Commits
  • 58d6a69 Merge pull request #30 from gnolang/chore/update-goreleaser
  • fa0d50a feat: Add most common architectures to goreleaser.
  • f11f08e Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 (#25)
  • a147682 Bump anchore/sbom-action from 0.15.9 to 0.15.10 (#27)
  • 48a127e Bump golang.org/x/sync from 0.6.0 to 0.7.0 (#28)
  • See full diff in compare view

Updates `github.com/btcsuite/btcd/btcec/v2` from 2.3.2 to 2.3.3
Commits
  • e4b32e0 Merge pull request #2156 from ffranr/add-pubkey-serialized-type
  • 92b24d2 Merge pull request #2150 from xiaoxianBoy/fix-typos
  • ae55336 Merge pull request #2142 from YusukeShimizu/feeRate-BTCkvB
  • 665eeb5 btcec: add new type SerializedKey
  • 31647e4 btcec: add missing doc comments
  • 9851d96 chore: fix typos
  • 95330bc chore: fix some comments (#2146)
  • 80b27f5 btcclient+btcjson: add type alias for BTC/kvB
  • bbb6967 btcclient+btcjson: feeRate to BTC/kvB
  • a03259b Merge pull request #1991 from ffranr/add-json-support
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] --- contribs/gnodev/go.mod | 4 ++-- contribs/gnodev/go.sum | 8 ++++---- contribs/gnokeykc/go.mod | 4 ++-- contribs/gnokeykc/go.sum | 8 ++++---- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/contribs/gnodev/go.mod b/contribs/gnodev/go.mod index 9a9d1a9f798..0f466f9dc5d 100644 --- a/contribs/gnodev/go.mod +++ b/contribs/gnodev/go.mod @@ -18,13 +18,13 @@ require ( require ( dario.cat/mergo v1.0.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.3 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.1 // indirect diff --git a/contribs/gnodev/go.sum b/contribs/gnodev/go.sum index 028c3f6f56e..7cde4cbdb93 100644 --- a/contribs/gnodev/go.sum +++ b/contribs/gnodev/go.sum @@ -9,8 +9,8 @@ github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd h1:js1gPwhcFflTZ7 github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= +github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= @@ -46,8 +46,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= diff --git a/contribs/gnokeykc/go.mod b/contribs/gnokeykc/go.mod index b66d9ddd0b5..0a4965e4a5d 100644 --- a/contribs/gnokeykc/go.mod +++ b/contribs/gnokeykc/go.mod @@ -11,13 +11,13 @@ require ( require ( github.com/alessio/shellescape v1.4.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.3 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect diff --git a/contribs/gnokeykc/go.sum b/contribs/gnokeykc/go.sum index 3eb03548817..d19ce65d8d7 100644 --- a/contribs/gnokeykc/go.sum +++ b/contribs/gnokeykc/go.sum @@ -9,8 +9,8 @@ github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd h1:js1gPwhcFflTZ7 github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= +github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= @@ -42,8 +42,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= diff --git a/go.mod b/go.mod index cdbd51d67da..e2d8baf6e74 100644 --- a/go.mod +++ b/go.mod @@ -8,10 +8,10 @@ require ( github.com/cockroachdb/apd/v3 v3.2.1 github.com/cosmos/ledger-cosmos-go v0.13.3 github.com/davecgh/go-spew v1.1.1 - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/fortytw2/leaktest v1.3.0 github.com/gdamore/tcell/v2 v2.7.4 - github.com/gnolang/faucet v0.1.3 + github.com/gnolang/faucet v0.2.0 github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 github.com/golang/protobuf v1.5.4 github.com/google/gofuzz v1.2.0 @@ -61,7 +61,7 @@ require ( ) require ( - github.com/btcsuite/btcd/btcec/v2 v2.3.2 + github.com/btcsuite/btcd/btcec/v2 v2.3.3 github.com/gdamore/encoding v1.0.0 // indirect github.com/go-chi/chi/v5 v5.0.12 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -73,7 +73,7 @@ require ( github.com/rivo/uniseg v0.4.3 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect - golang.org/x/sync v0.6.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect diff --git a/go.sum b/go.sum index 12bad5b3d35..c7c81d86bd1 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd h1:js1gPwhcFflTZ7 github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= +github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= @@ -40,8 +40,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= @@ -59,8 +59,8 @@ github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdk github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell/v2 v2.7.4 h1:sg6/UnTM9jGpZU+oFYAsDahfchWAFW8Xx2yFinNSAYU= github.com/gdamore/tcell/v2 v2.7.4/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg= -github.com/gnolang/faucet v0.1.3 h1:eg3S4rGkW6LYWo7nhc4AhWrPmHsaEFy6R8fyef/KgK4= -github.com/gnolang/faucet v0.1.3/go.mod h1:+91pqgE+pyX8FO9eoe2MGiwgTpYY0bITYsHO/4Zg+CY= +github.com/gnolang/faucet v0.2.0 h1:ynUgJ/z5F6to/4j5F9v7tpPth4b9ZUvLseGKd+tiL/g= +github.com/gnolang/faucet v0.2.0/go.mod h1:E7Nxsgmx4JbXWlBXE8teSj7IZf/BSwCfB2pO9hGY02E= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 h1:GKvsK3oLWG9B1GL7WP/VqwM6C92j5tIvB844oggL9Lk= github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:xJhtEL7ahjM1WJipt89gel8tHzfIl/LyMY+lCYh38d8= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= @@ -218,8 +218,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=