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)) + } +} 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..df16ecf0ad9 100644 --- a/gnovm/pkg/gnolang/uverse.go +++ b/gnovm/pkg/gnolang/uverse.go @@ -709,7 +709,24 @@ 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 { + // 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 case *NativeType: krv := reflect.New(cbt.Type.Key()).Elem()