diff --git a/gno.land/cmd/gnoland/testdata/issue-1167.txtar b/gno.land/cmd/gnoland/testdata/issue-1167.txtar new file mode 100644 index 00000000000..a24cca5dce9 --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/issue-1167.txtar @@ -0,0 +1,114 @@ +# Reproducible Test for https://github.com/gnolang/gno/issues/1167 + +gnoland start + +# add contract +gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/xx -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! + +# execute New +gnokey maketx call -pkgpath gno.land/r/demo/xx -func New -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! + +# execute Delta for the first time +gnokey maketx call -pkgpath gno.land/r/demo/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! +stdout '"1,1,1;" string' + +# execute Delta for the second time +gnokey maketx call -pkgpath gno.land/r/demo/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! +stdout '1,1,1;2,2,2;" string' + +# execute Delta for the third time +gnokey maketx call -pkgpath gno.land/r/demo/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! +stdout '1,1,1;2,2,2;3,3,3;" string' + +# execute Render +gnokey maketx call -pkgpath gno.land/r/demo/xx -func Render -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! +stdout '1,1,1;2,2,2;3,3,3;" string' + +-- gno.mod -- +module gno.land/r/demo/xx + +require ( + gno.land/p/demo/avl v0.0.0-latest +) + +-- realm.gno -- +package xx + +import ( + "strconv" + + "gno.land/p/demo/avl" +) + +type Move struct { + N1, N2, N3 byte +} + +type Position struct { + Moves []Move +} + +func (p Position) clone() Position { + mv := p.Moves + return Position{Moves: mv} +} + +func (oldp Position) update() Position { + p := oldp.clone() + + counter++ + // This is a workaround for the wrong behaviour (ie. uncomment this line): + // p.Moves = append([]Move{}, p.Moves...) + p.Moves = append(p.Moves, Move{counter, counter, counter}) + return p +} + +type Game struct { + Position Position +} + +var games avl.Tree // id -> *Game + +var counter byte + +func New(s string) string { + // Bug shows if Moves has a cap > 0 when initialised. + el := &Game{Position: Position{Moves: make([]Move, 0, 2)}} + games.Set(s, el) + return values(el.Position) +} + +func Delta(s string) string { + v, _ := games.Get(s) + g, ok := v.(*Game) + if !ok { + panic("invalid game") + } + n := g.Position.update() + g.Position = n + ret := values(n) + return ret +} + +func Render(s string) string { + v, _ := games.Get(s) + g, ok := v.(*Game) + if !ok { + panic("invalid game") + } + return values(g.Position) +} + +func values(x Position) string { + s := "" + for _, val := range x.Moves { + s += strconv.Itoa(int(val.N1)) + "," + strconv.Itoa(int(val.N2)) + "," + strconv.Itoa(int(val.N3)) + ";" + } + return s +}