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

[chain] Support for on-chain Realm Events #1833

Closed
zivkovicmilos opened this issue Mar 25, 2024 · 5 comments · Fixed by #1653
Closed

[chain] Support for on-chain Realm Events #1833

zivkovicmilos opened this issue Mar 25, 2024 · 5 comments · Fixed by #1653
Assignees
Labels
📦 🌐 tendermint v2 Issues or PRs tm2 related

Comments

@zivkovicmilos
Copy link
Member

zivkovicmilos commented Mar 25, 2024

Description

This effort covers the ability to emit events on-chain through Realm gno code, and being able to parse those events through transaction results.

Copied from a Gno issue:
As Gno revolves around Smart Contracts (Realms), there is a need for tapping into real-time Realm data off-chain. For example, a Realm could house the validator set (addresses / public keys) for the running chain.

In order for critical data to be housed on a Realm, it should be reachable from a 3rd party process that potentially lives off-chain. In our validator set example, there should be a listener that can subscribe to Realm state changes, and execute node-specific protocol logic accordingly.

Solidity in Ethereum has a similar concept in the form of Events. In Solidity, users can specify an event emit, which is reflected in the Transaction Receipt as part of the execution log. Based on this log, users can subscribe to ongoing Events and be alerted the moment they are committed to the running chain.

Previously, there was the ability for the Gno node itself to index transactions over RPC (HTTP / WS), but this functionality has since been deprecated.
Based on discussions with @jaekwon on on Gno Event Store PR (indexing) and tm2-js-client issue, we've finalized the scope of work that needs to be done in order to provide users with indexing functionality. This scope of work consists of building out a separate tool that is capable of parsing event information from the TM2 node, and internally indexing the data so it can be provided to users. The functionality that this tool should have is not limited to:

  • import past transaction data
  • monitor new event data
  • provide an RPC endpoint (HTTP / WS) for querying indexed data
  • provide the ability to subscribe to specific event types

Successful outcome of this effort:

  • There exists a standalone tool that can index blocks and transactions, and provide the detailed functionality through RPC endpoints - ✅ done with tx-indexer
  • The Gno execution environment saves event emit data in the transaction result, so that it can be indexed and read asynchronously

Related:

@zivkovicmilos zivkovicmilos added the 📦 🌐 tendermint v2 Issues or PRs tm2 related label Mar 25, 2024
@n0izn0iz
Copy link
Contributor

IMO, events in transactions results should include the path of the realm emitting them

@zivkovicmilos
Copy link
Member Author

IMO, events in transactions results should include the path of the realm emitting them

@notJoon what do you think about this proposal?

@notJoon
Copy link
Member

notJoon commented Mar 26, 2024

IMO, events in transactions results should include the path of the realm emitting them

@notJoon what do you think about this proposal?

I thinks it would be good. This approach could offer several advantages:

  1. Transparency and Traceability: By including the path of the realm, we can clearly identify which contract the events are come from. This will help to trace the origins of specific transactions and events.
  2. Provide Context: Events occurring within a specific realm may be closely linked to particular logic or functions within that realm. Including the realm's path in the event information could aid in interpreting these events more accurately.
  3. Security (maybe?): By clarifying the origin of events, I believe we can prevent malicious actors from forging events.

While there is a tradeoff of increased data size and processing costs exists, but I think the benefits outweigh that.

@n0izn0iz
Copy link
Contributor

n0izn0iz commented Mar 26, 2024

Maybe using the realm address is enough, it could reduce the storage size for long realm names but it would require extra work on the indexer side to get the actual realm path. Not sure what is best

@moul
Copy link
Member

moul commented Apr 21, 2024

Hey, is this issue necessary, or can we merge it with #575?

Edit: I suggest focusing on this new one and closing the old one with a reference.

moul added a commit that referenced this issue Apr 30, 2024
# Description

Succeed in my predecessor's legacy.

I have implemented the output to show the path where the event occurred,
as discussed in #1833. Also made it print the timestamp or block height
together.

## Key Changes

In this change, event emission functionality has been added to the Gno.
The main changes include:

1. Introducing of the `emitEvent` function:
- The `emitEvent` function emits an event based on the given type and
attributes
    - Attributes are passed as an even-length of array key-value pairs
- When emitting an event, the current _package path_, _timestamp_, and
_block height_ information are recorded along with the event(discussed
in #1833). This metadata provides additional context about where the
event occured.

2. Additional of event-related types and functions in the `sdk`
packages:
- `NewEvent` creates a new `Event` object based on the provided
information.
- `ArributedEvent` struct contains informations such as event type,
package path, block height, timestamp and attributes. But I'm not sure
how to utilize the `eventType` yet. So, I've just put it as a
placeholder which will be a disscussion for another time.
- `EventArribute` represents an attribute of an event and consists of a
key-value pair
- `NewEventArribute` creates a new `EventAttribute` object based on the
given key-value pair.

## Example

```go
package ee

import (
	"std"
)

const (
	EventSender = "sender"
	EventReceiver = "receiver"
)

func Sender(){
    SubSender()
    SubReceiver()
}

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

func SubReceiver() {
    std.Emit(
        EventReceiver,
        "bar", "baz",
    )
}

func Receiver() {
    std.Emit(
        EventReceiver,
        "foo", "bar",
    )
}
```

### Result

```json
[
  "{\"type\":\"sender\",\"pkg_path\":\"gno.land/r/demo/ee\",\"identifier\":\"SubSender\",\"timestamp\":1713846501,\"attributes\":[{\"key\":\"key1\",\"value\":\"value1\"},{\"key\":\"key2\",\"value\":\"value2\"},{\"key\":\"key3\",\"value\":\"value3\"}]}",
  "{\"type\":\"receiver\",\"pkg_path\":\"gno.land/r/demo/ee\",\"identifier\":\"SubReceiver\",\"timestamp\":1713846501,\"attributes\":[{\"key\":\"bar\",\"value\":\"baz\"}]}"
]
```

## Related Issue/PR

#575 emit & event built-in functions (@r3v4s)
#853 feat: event & emit in gno (@anarcher) <- previous work.
#975 [META] Gno Wishlist / Feature Request Dump (@zivkovicmilos)

---------

Co-authored-by: n3wbie <[email protected]>
Co-authored-by: Manfred Touron <[email protected]>
gfanton pushed a commit to gfanton/gno that referenced this issue May 1, 2024
)

# Description

Succeed in my predecessor's legacy.

I have implemented the output to show the path where the event occurred,
as discussed in gnolang#1833. Also made it print the timestamp or block height
together.

## Key Changes

In this change, event emission functionality has been added to the Gno.
The main changes include:

1. Introducing of the `emitEvent` function:
- The `emitEvent` function emits an event based on the given type and
attributes
    - Attributes are passed as an even-length of array key-value pairs
- When emitting an event, the current _package path_, _timestamp_, and
_block height_ information are recorded along with the event(discussed
in gnolang#1833). This metadata provides additional context about where the
event occured.

2. Additional of event-related types and functions in the `sdk`
packages:
- `NewEvent` creates a new `Event` object based on the provided
information.
- `ArributedEvent` struct contains informations such as event type,
package path, block height, timestamp and attributes. But I'm not sure
how to utilize the `eventType` yet. So, I've just put it as a
placeholder which will be a disscussion for another time.
- `EventArribute` represents an attribute of an event and consists of a
key-value pair
- `NewEventArribute` creates a new `EventAttribute` object based on the
given key-value pair.

## Example

```go
package ee

import (
	"std"
)

const (
	EventSender = "sender"
	EventReceiver = "receiver"
)

func Sender(){
    SubSender()
    SubReceiver()
}

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

func SubReceiver() {
    std.Emit(
        EventReceiver,
        "bar", "baz",
    )
}

func Receiver() {
    std.Emit(
        EventReceiver,
        "foo", "bar",
    )
}
```

### Result

```json
[
  "{\"type\":\"sender\",\"pkg_path\":\"gno.land/r/demo/ee\",\"identifier\":\"SubSender\",\"timestamp\":1713846501,\"attributes\":[{\"key\":\"key1\",\"value\":\"value1\"},{\"key\":\"key2\",\"value\":\"value2\"},{\"key\":\"key3\",\"value\":\"value3\"}]}",
  "{\"type\":\"receiver\",\"pkg_path\":\"gno.land/r/demo/ee\",\"identifier\":\"SubReceiver\",\"timestamp\":1713846501,\"attributes\":[{\"key\":\"bar\",\"value\":\"baz\"}]}"
]
```

## Related Issue/PR

gnolang#575 emit & event built-in functions (@r3v4s)
gnolang#853 feat: event & emit in gno (@anarcher) <- previous work.
gnolang#975 [META] Gno Wishlist / Feature Request Dump (@zivkovicmilos)

---------

Co-authored-by: n3wbie <[email protected]>
Co-authored-by: Manfred Touron <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 🌐 tendermint v2 Issues or PRs tm2 related
Projects
Development

Successfully merging a pull request may close this issue.

4 participants