From cf0f2ad0cea43a9c3432392145caee350b3223fa Mon Sep 17 00:00:00 2001 From: n3wbie Date: Thu, 2 May 2024 15:36:34 +0900 Subject: [PATCH 1/4] fix: map-delete --- .../cmd/gnoland/testdata/map-delete.txtar | 41 +++++++++++++++++++ gnovm/pkg/gnolang/uverse.go | 1 + 2 files changed, 42 insertions(+) create mode 100644 gno.land/cmd/gnoland/testdata/map-delete.txtar diff --git a/gno.land/cmd/gnoland/testdata/map-delete.txtar b/gno.land/cmd/gnoland/testdata/map-delete.txtar new file mode 100644 index 00000000000..12783d46ac5 --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/map-delete.txtar @@ -0,0 +1,41 @@ +gnoland start + +# add contract +gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/mapdelete -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! + +# delete map +gnokey maketx call -pkgpath gno.land/r/demo/mapdelete -func DeleteMap -args 3 -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! + +# check deletion +gnokey maketx call -pkgpath gno.land/r/demo/mapdelete -func GetMap -args 3 -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! +stdout 'false bool' +# XXX without patching uverse.go, expected stdout is +# stdout 'true bool' + + + +-- gno.mod -- +module gno.land/r/demo/mapdelete + +-- realm.gno -- +package mapdelete + +var mapus map[uint64]string = make(map[uint64]string) + +func init() { + mapus[3] = "three" + mapus[5] = "five" + mapus[9] = "nine" +} + +func DeleteMap(k uint64) { + delete(mapus, k) +} + +func GetMap(k uint64) bool { + _, exist := mapus[k] + return exist +} \ No newline at end of file diff --git a/gnovm/pkg/gnolang/uverse.go b/gnovm/pkg/gnolang/uverse.go index 9f836c789fe..e25ba1d983e 100644 --- a/gnovm/pkg/gnolang/uverse.go +++ b/gnovm/pkg/gnolang/uverse.go @@ -710,6 +710,7 @@ func UverseNode() *PackageNode { case *MapType: mv := arg0.TV.V.(*MapValue) mv.DeleteForKey(m.Store, &itv) + m.Realm.DidUpdate(mv, nil, nil) return case *NativeType: krv := reflect.New(cbt.Type.Key()).Elem() From 01a71edebd08bbd963830425688bfb71f36c6e9c Mon Sep 17 00:00:00 2001 From: n3wbie Date: Thu, 2 May 2024 17:21:48 +0900 Subject: [PATCH 2/4] test: unit test --- .../gno.land/r/x/map_delete/map_delete.gno | 18 ++++++++++++++++ .../r/x/map_delete/map_delete_test.gno | 21 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 examples/gno.land/r/x/map_delete/map_delete.gno create mode 100644 examples/gno.land/r/x/map_delete/map_delete_test.gno diff --git a/examples/gno.land/r/x/map_delete/map_delete.gno b/examples/gno.land/r/x/map_delete/map_delete.gno new file mode 100644 index 00000000000..f7f89e8893d --- /dev/null +++ b/examples/gno.land/r/x/map_delete/map_delete.gno @@ -0,0 +1,18 @@ +package mapdelete + +var mapus map[uint64]string = make(map[uint64]string) + +func init() { + mapus[3] = "three" + mapus[5] = "five" + mapus[9] = "nine" +} + +func DeleteMap(k uint64) { + delete(mapus, k) +} + +func GetMap(k uint64) bool { + _, exist := mapus[k] + return exist +} diff --git a/examples/gno.land/r/x/map_delete/map_delete_test.gno b/examples/gno.land/r/x/map_delete/map_delete_test.gno new file mode 100644 index 00000000000..a0118befed2 --- /dev/null +++ b/examples/gno.land/r/x/map_delete/map_delete_test.gno @@ -0,0 +1,21 @@ +package mapdelete + +import ( + "testing" +) + +func TestGetMap(t *testing.T) { + if !(GetMap(3)) { + t.Error("Expected true, got ", GetMap(3)) + } +} + +func TestDeleteMap(t *testing.T) { + DeleteMap(3) +} + +func TestGetMapAfterDelete(t *testing.T) { + if GetMap(3) { + t.Error("Expected false, got ", GetMap(3)) + } +} From a834c5f05debe2de45e3e8cf13cec9f25b54cbe4 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Fri, 3 May 2024 17:02:28 +0900 Subject: [PATCH 3/4] feat: mark object if its deleted --- gnovm/pkg/gnolang/uverse.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gnovm/pkg/gnolang/uverse.go b/gnovm/pkg/gnolang/uverse.go index e25ba1d983e..4de318a61ab 100644 --- a/gnovm/pkg/gnolang/uverse.go +++ b/gnovm/pkg/gnolang/uverse.go @@ -710,7 +710,12 @@ func UverseNode() *PackageNode { case *MapType: mv := arg0.TV.V.(*MapValue) mv.DeleteForKey(m.Store, &itv) - m.Realm.DidUpdate(mv, nil, nil) + if m.Realm != nil { + // delete value and mark it deleted if it's a object + oo1 := itv.GetFirstObject(m.Store) + m.Realm.DidUpdate(mv, oo1, nil) + } + return case *NativeType: krv := reflect.New(cbt.Type.Key()).Elem() From beec18754dff199a8e9a92f5f02380f58b9d82d8 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Tue, 7 May 2024 13:56:51 +0900 Subject: [PATCH 4/4] feat: mark both key and value as deleted --- gnovm/pkg/gnolang/uverse.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/gnovm/pkg/gnolang/uverse.go b/gnovm/pkg/gnolang/uverse.go index 4de318a61ab..df16ecf0ad9 100644 --- a/gnovm/pkg/gnolang/uverse.go +++ b/gnovm/pkg/gnolang/uverse.go @@ -709,11 +709,22 @@ func UverseNode() *PackageNode { switch cbt := baseOf(arg0.TV.T).(type) { case *MapType: mv := arg0.TV.V.(*MapValue) + val, ok := mv.GetValueForKey(m.Store, &itv) + if !ok { + return + } + + // delete mv.DeleteForKey(m.Store, &itv) + if m.Realm != nil { - // delete value and mark it deleted if it's a object - oo1 := itv.GetFirstObject(m.Store) - m.Realm.DidUpdate(mv, oo1, nil) + // mark key as deleted + keyObj := itv.GetFirstObject(m.Store) + m.Realm.DidUpdate(mv, keyObj, nil) + + // mark value as deleted + valObj := val.GetFirstObject(m.Store) + m.Realm.DidUpdate(mv, valObj, nil) } return