Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gnovm, tm2): implement event emission with std.Emit #1653

Merged
merged 65 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
c67e718
[WIP] feat(gnovm, tm2): Yet Another Emit/Event
notJoon Feb 13, 2024
d7cb7d9
add test for e&e and change file names
notJoon Feb 22, 2024
94ab8ef
Merge branch 'master' into emit-event
notJoon Mar 26, 2024
c06f079
fixup
notJoon Mar 26, 2024
5360fa9
feat: EmitEvent in gno
r3v4s Mar 28, 2024
79f5752
fmt
notJoon Mar 29, 2024
fd84dc5
Merge branch 'master' into emit-event
notJoon Apr 1, 2024
35ef5f8
Event holds more metadata
notJoon Apr 1, 2024
0afd6cd
run go generate
notJoon Apr 1, 2024
6625e7e
fix lint error
notJoon Apr 1, 2024
2a87886
Merge branch 'master' into emit-event
notJoon Apr 2, 2024
d7f1fed
pkgPath in Events
notJoon Apr 2, 2024
2a6084a
re-organize code
notJoon Apr 2, 2024
97e2c07
print attribute
notJoon Apr 2, 2024
860e9bd
print metadata finish
notJoon Apr 2, 2024
63c5829
fix CI failing
notJoon Apr 2, 2024
943ac20
Merge branch 'master' into emit-event
notJoon Apr 3, 2024
866250e
change timestamp to expose the block header data
notJoon Apr 11, 2024
2a99d96
Merge branch 'master' into emit-event
notJoon Apr 11, 2024
3e5636b
fix failing error
notJoon Apr 11, 2024
be033a7
remove height, don't panic
notJoon Apr 12, 2024
52e5412
expose function name
notJoon Apr 12, 2024
1a9a524
save
notJoon Apr 12, 2024
f054d67
event stringfy
notJoon Apr 12, 2024
2adfdd7
fix CI
notJoon Apr 12, 2024
ebb387a
json style event string
notJoon Apr 13, 2024
bb80a2e
Update gnovm/tests/file.go
notJoon Apr 17, 2024
61bc407
fix: apply suggestions
notJoon Apr 17, 2024
e76e231
fix: apply suggestions
notJoon Apr 17, 2024
87d4d9e
Merge branch 'master' into emit-event
notJoon Apr 17, 2024
929eb6d
fix: resolve simple comments
notJoon Apr 18, 2024
49f1d84
moving previous DetailedEvent type into gnovm dir and renamed it
notJoon Apr 18, 2024
9b183fb
valid json
notJoon Apr 18, 2024
d2a0c98
fix: lint, remove leftover
notJoon Apr 18, 2024
59c020f
fix: apply some comments
notJoon Apr 19, 2024
13d7b4f
use EventString
notJoon Apr 19, 2024
9f726ca
remove leftover
notJoon Apr 19, 2024
271651a
Update gnovm/stdlibs/std/emit_event.go
notJoon Apr 22, 2024
b207069
Update gnovm/stdlibs/std/emit_event.go
notJoon Apr 22, 2024
d1c28cc
Update tm2/pkg/bft/abci/types/types.go
notJoon Apr 22, 2024
849ac83
Merge branch 'master' into emit-event
notJoon Apr 22, 2024
2e9d9ed
add very basic test
notJoon Apr 22, 2024
1d83801
add more tests
notJoon Apr 23, 2024
2ab7577
Update gnovm/stdlibs/std/emit_event.go
moul Apr 23, 2024
5a16ac6
explicit regex, remove unnecessary marshaling step.
notJoon Apr 23, 2024
ffb66ae
update comment
notJoon Apr 23, 2024
e49793a
store result to EventString
notJoon Apr 23, 2024
ff0877f
Update tm2/pkg/crypto/keys/client/maketx.go
moul Apr 24, 2024
8ddfd0f
Update gno.land/cmd/gnoland/testdata/event.txtar
notJoon Apr 24, 2024
55b6704
Update gnovm/stdlibs/std/emit_event_test.go
notJoon Apr 24, 2024
a7ae1a7
Update gnovm/stdlibs/std/native.go
notJoon Apr 24, 2024
191c130
Update gnovm/stdlibs/std/emit_event.gno
notJoon Apr 24, 2024
1474c0d
Update gnovm/stdlibs/std/context.go
notJoon Apr 24, 2024
150fe46
no regex
notJoon Apr 24, 2024
ed5f542
fixup (maybe)
notJoon Apr 25, 2024
67a40e2
fixup
notJoon Apr 25, 2024
ae5292a
Merge branch 'emit-event' of https://github.com/notJoon/gno-core into…
notJoon Apr 25, 2024
6cd31f1
fix: CI failing
notJoon Apr 25, 2024
c8219e4
Apply suggestions from code review
moul Apr 26, 2024
7e391a9
change field name and remove EmittedEvents, no global consst in test
notJoon Apr 29, 2024
96f7ca5
panic
notJoon Apr 29, 2024
0358dd6
Merge branch 'master' into emit-event
notJoon Apr 29, 2024
317108a
func name change
notJoon Apr 29, 2024
b0d9b28
Merge branch 'master' into emit-event
moul Apr 29, 2024
7a5fd74
use attrs for field name and change to use loadpkg
notJoon Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions gno.land/cmd/gnoland/testdata/event.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# start a new node
gnoland start

gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/ee -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2500000'
stdout 'GAS USED: \d+'
stdout 'HEIGHT: \d+'
stdout 'EVENTS: \[\]'

gnokey maketx call -pkgpath gno.land/r/demo/ee -func Foo -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2000000'
stdout 'GAS USED: \d+'
stdout 'HEIGHT: \d+'
stdout 'EVENTS: \[{\"type\":\"foo\",\"pkg_path\":\"gno.land\/r\/demo\/ee\",\"func\":\"SubFoo\",\"attributes\":\[{\"key\":\"key1\",\"value\":\"value1\"},{\"key\":\"key2\",\"value\":\"value2\"},{\"key\":\"key3\",\"value\":\"value3\"}\]},{\"type\":\"bar\",\"pkg_path\":\"gno.land\/r\/demo\/ee\",\"func\":\"SubBar\",\"attributes\":\[{\"key\":\"bar\",\"value\":\"baz\"}\]}\]'

gnokey maketx call -pkgpath gno.land/r/demo/ee -func Bar -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2000000'
stdout 'GAS USED: \d+'
stdout 'HEIGHT: \d+'
stdout 'EVENTS: \[{\"type\":\"bar\",\"pkg_path\":\"gno.land\/r\/demo\/ee\",\"func\":\"Bar\",\"attributes\":\[{\"key\":\"foo\",\"value\":\"bar\"}\]}\]'

-- ee.gno --
package ee

import (
"std"
)

const (
EventFoo = "foo"
EventBar = "bar"
)

func Foo(){
SubFoo()
SubBar()
}

func SubFoo() {
std.Emit(
EventFoo,
"key1", "value1",
"key2", "value2",
"key3", "value3",
)
}

func SubBar() {
std.Emit(
EventBar,
"bar", "baz",
)
}

func Bar() {
std.Emit(
EventBar,
"foo", "bar",
)
}
55 changes: 55 additions & 0 deletions gno.land/cmd/gnoland/testdata/event_callback.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# start a new node
gnoland start

gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/cbee -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2500000'
stdout 'GAS USED: [0-9]+'
stdout 'HEIGHT: [0-9]+'
stdout 'EVENTS: \[\]'

gnokey maketx call -pkgpath gno.land/r/demo/cbee -func Foo -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2000000'
stdout 'GAS USED: [0-9]+'
stdout 'HEIGHT: [0-9]+'
stdout 'EVENTS: \[{\"type\":\"foo\",\"pkg_path\":\"gno\.land\/r\/demo\/cbee\",\"func\":\"subFoo\",\"attributes\":\[{\"key\":\"k1\",\"value\":\"v1\"},{\"key\":\"k2\",\"value\":\"v2\"}\]},{\"type\":\"bar\",\"pkg_path\":\"gno\.land\/r\/demo\/cbee\",\"func\":\"subBar\",\"attributes\":\[{\"key\":\"bar\",\"value\":\"baz\"}\]}\]'


-- cbee.gno --
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
package cbee

import (
"std"
)

const (
foo = "foo"
bar = "bar"
)

type contractA struct{}

func (c *contractA) foo(cb func()) {
subFoo()
cb()
}

func subFoo() {
std.Emit(foo, "k1", "v1", "k2", "v2")
}

type contractB struct{}

func (c *contractB) subBar() {
std.Emit(bar, "bar", "baz")
}

func Foo() {
a := &contractA{}
b := &contractB{}

a.foo(func() {
b.subBar()
})
}
68 changes: 68 additions & 0 deletions gno.land/cmd/gnoland/testdata/event_defer_callback_loop.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# start a new node
gnoland start

gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/edcl -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2500000'
stdout 'GAS USED: [0-9]+'
stdout 'HEIGHT: [0-9]+'
stdout 'EVENTS: \[\]'

gnokey maketx call -pkgpath gno.land/r/demo/edcl -func Main -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2000000'
stdout 'GAS USED: [0-9]+'
stdout 'HEIGHT: [0-9]+'
stdout 'EVENTS: \[{\"type\":\"ForLoopEvent\",\"pkg_path\":\"gno.land\/r\/demo\/edcl\",\"func\":\"\",\"attributes\":\[{\"key\":\"iteration\",\"value\":\"0\"},{\"key\":\"key\",\"value\":\"value\"}\]},{\"type\":\"ForLoopEvent\",\"pkg_path\":\"gno.land\/r\/demo\/edcl\",\"func\":\"\",\"attributes\":\[{\"key\":\"iteration\",\"value\":\"1\"},{\"key\":\"key\",\"value\":\"value\"}\]},{\"type\":\"ForLoopEvent\",\"pkg_path\":\"gno.land\/r\/demo\/edcl\",\"func\":\"\",\"attributes\":\[{\"key\":\"iteration\",\"value\":\"2\"},{\"key\":\"key\",\"value\":\"value\"}\]},{\"type\":\"ForLoopCompletionEvent\",\"pkg_path\":\"gno.land\/r\/demo\/edcl\",\"func\":\"forLoopEmitExample\",\"attributes\":\[{\"key\":\"count\",\"value\":\"3\"}\]},{\"type\":\"CallbackEvent\",\"pkg_path\":\"gno.land\/r\/demo\/edcl\",\"func\":\"\",\"attributes\":\[{\"key\":\"key1\",\"value\":\"value1\"},{\"key\":\"key2\",\"value\":\"value2\"}\]},{\"type\":\"CallbackCompletionEvent\",\"pkg_path\":\"gno.land\/r\/demo\/edcl\",\"func\":\"callbackEmitExample\",\"attributes\":\[{\"key\":\"key\",\"value\":\"value\"}\]},{\"type\":\"DeferEvent\",\"pkg_path\":\"gno.land\/r\/demo\/edcl\",\"func\":\"deferEmitExample\",\"attributes\":\[{\"key\":\"key1\",\"value\":\"value1\"},{\"key\":\"key2\",\"value\":\"value2\"}\]}\]'
moul marked this conversation as resolved.
Show resolved Hide resolved

-- edcl.gno --

package edcl

import (
"std"
"strconv"
)

func Main() {
deferEmitExample()
}

func deferEmitExample() {
defer func() {
std.Emit("DeferEvent", "key1", "value1", "key2", "value2")
println("Defer emit executed")
}()

forLoopEmitExample(3, func(i int) {
std.Emit("ForLoopEvent", "iteration", strconv.Itoa(i), "key", "value")
println("For loop emit executed: iteration ", i)
})

callbackEmitExample(func() {
std.Emit("CallbackEvent", "key1", "value1", "key2", "value2")
println("Callback emit executed")
})

println("deferEmitExample completed")
}

func forLoopEmitExample(count int, callback func(int)) {
defer func() {
std.Emit("ForLoopCompletionEvent", "count", strconv.Itoa(count))
println("For loop completion emit executed ", count)
}()

for i := 0; i < count; i++ {
callback(i)
}
}

func callbackEmitExample(callback func()) {
defer func() {
std.Emit("CallbackCompletionEvent", "key", "value")
println("Callback completion emit executed")
}()

callback()
}
68 changes: 68 additions & 0 deletions gno.land/cmd/gnoland/testdata/event_for_statement.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# start a new node
gnoland start

gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/foree -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2500000'
stdout 'GAS USED: [0-9]+'
stdout 'HEIGHT: [0-9]+'
stdout 'EVENTS: \[\]'

gnokey maketx call -pkgpath gno.land/r/demo/foree -func Foo -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2000000'
stdout 'GAS USED: [0-9]+'
stdout 'HEIGHT: [0-9]+'
stdout 'EVENTS: \[{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]},{"type":"testing","pkg_path":"gno.land\/r\/demo\/foree","func":"Foo","attributes":\[{"key":"foo","value":"bar"}\]}\]'

gnokey maketx call -pkgpath gno.land/r/demo/foree -func Bar -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
stdout 'GAS WANTED: 2000000'
stdout 'GAS USED: [0-9]+'
stdout 'HEIGHT: [0-9]+'
stdout 'EVENTS: \[{"type":"Foo","pkg_path":"gno.land\/r\/demo\/foree","func":"subFoo","attributes":\[{"key":"k1","value":"v1"},{"key":"k2","value":"v2"}\]},{"type":"Bar","pkg_path":"gno.land\/r\/demo\/foree","func":"subBar","attributes":\[{"key":"bar","value":"baz"}\]},{"type":"Foo","pkg_path":"gno.land\/r\/demo\/foree","func":"subFoo","attributes":\[{"key":"k1","value":"v1"},{"key":"k2","value":"v2"}\]},{"type":"Bar","pkg_path":"gno.land\/r\/demo\/foree","func":"subBar","attributes":\[{"key":"bar","value":"baz"}\]}\]'


-- foree.gno --

package foree

import "std"

func Foo() {
for i := 0; i < 10; i++ {
std.Emit("testing", "foo", "bar")
}
}

const (
eventFoo = "Foo"
eventBar = "Bar"
)

type contractA struct{}

func (c *contractA) Foo(cb func()) {
subFoo()
cb()
}

func subFoo() {
std.Emit(eventFoo, "k1", "v1", "k2", "v2")
}

type contractB struct{}

func (c *contractB) subBar() {
std.Emit(eventBar, "bar", "baz")
}

func Bar() {
a := &contractA{}
b := &contractB{}
for i := 0; i < 2; i++ {
a.Foo(func() {
b.subBar()
})
}
}
5 changes: 5 additions & 0 deletions gno.land/pkg/sdk/vm/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) (err error) {
OrigSendSpent: new(std.Coins),
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx),
EventLogger: ctx.EventLogger(),
}
// Parse and run the files, construct *PV.
m2 := gno.NewMachineWithOptions(
Expand Down Expand Up @@ -275,6 +276,7 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) {
OrigSendSpent: new(std.Coins),
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx),
EventLogger: ctx.EventLogger(),
}
// Construct machine and evaluate.
m := gno.NewMachineWithOptions(
Expand Down Expand Up @@ -351,6 +353,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) {
OrigSendSpent: new(std.Coins),
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx),
EventLogger: ctx.EventLogger(),
}
// Parse and run the files, construct *PV.
buf := new(bytes.Buffer)
Expand Down Expand Up @@ -500,6 +503,7 @@ func (vm *VMKeeper) QueryEval(ctx sdk.Context, pkgPath string, expr string) (res
// OrigSendSpent: nil,
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx), // safe as long as ctx is a fork to be discarded.
EventLogger: ctx.EventLogger(),
}
m := gno.NewMachineWithOptions(
gno.MachineOptions{
Expand Down Expand Up @@ -566,6 +570,7 @@ func (vm *VMKeeper) QueryEvalString(ctx sdk.Context, pkgPath string, expr string
// OrigSendSpent: nil,
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx), // safe as long as ctx is a fork to be discarded.
EventLogger: ctx.EventLogger(),
}
m := gno.NewMachineWithOptions(
gno.MachineOptions{
Expand Down
25 changes: 25 additions & 0 deletions gnovm/stdlibs/native.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions gnovm/stdlibs/std/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ type ExecContext struct {
OrigSend std.Coins
OrigSendSpent *std.Coins // mutable
Banker BankerInterface
EventLogger *sdk.EventLogger
}
19 changes: 19 additions & 0 deletions gnovm/stdlibs/std/emit_event.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package std

// Emit is a function that constructs a gnoEvent with a specified type and attributes.
// It then forwards this event to the event logger. Each emitted event carries metadata
// such as the event type, the initializing realm, and the provided attributes.
//
// The function takes type and attribute strings. typ (or type) is an arbitrary string that represents
// the type of the event. It plays a role of indexing what kind of event occurred. For example,
// a name like "Foo" or "Bar" can be used to indicating the purpose (nature) of the event.
//
// And the attrs (attributes) accepts an even number of strings and sets them as key-value pairs
// according to the order they are passed. For example, if the attr strings "key1", "value1" are
// passed in, the key is set to "key1" and the value is set to "value1".
//
// The event is dispatched to the EventLogger, which resides in the tm2/pkg/sdk/events.go file.
//
// For more details about the GnoEvent data structure, refer to its definition in the emit_event.go file.
func Emit(typ string, attrs ...string) { emit(typ, attrs) }
func emit(typ string, attrs []string)
Loading
Loading