Skip to content

Commit

Permalink
feat: Add support for runtime rofl transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrus committed Dec 13, 2024
1 parent 41b5d88 commit 4684659
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 163 deletions.
9 changes: 9 additions & 0 deletions .changelog/812.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
feature: Add support for runtime rofl transactions

New runtime transactions:

- `rofl.Create`, `rofl.Update`, `rofl.Remove`, `rofl.Register`

New runtime events:

- `rofl.app_created`, `rofl.app_updated`, `rofl.app_removed`
37 changes: 37 additions & 0 deletions analyzer/runtime/decode_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/consensusaccounts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/core"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/evm"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"

"github.com/oasisprotocol/nexus/storage/oasis/nodeapi"
)
Expand Down Expand Up @@ -145,6 +146,42 @@ func DecodeEVMEvent(event *nodeapi.RuntimeEvent) ([]evm.Event, error) {
return events, nil
}

func DecodeRoflEvent(event *nodeapi.RuntimeEvent) ([]rofl.Event, error) {
if event.Module != rofl.ModuleName {
return nil, nil
}
var events []rofl.Event
switch event.Code {
case rofl.AppCreatedEventCode:
var evs []*rofl.AppCreatedEvent
if err := unmarshalSingleOrArray(event.Value, &evs); err != nil {
return nil, fmt.Errorf("decode rofl app created event value: %w", err)
}
for _, ev := range evs {
events = append(events, rofl.Event{AppCreated: ev})
}
case rofl.AppUpdatedEventCode:
var evs []*rofl.AppUpdatedEvent
if err := unmarshalSingleOrArray(event.Value, &evs); err != nil {
return nil, fmt.Errorf("decode rofl app updated event value: %w", err)
}
for _, ev := range evs {
events = append(events, rofl.Event{AppUpdated: ev})
}
case rofl.AppRemovedEventCode:
var evs []*rofl.AppRemovedEvent
if err := unmarshalSingleOrArray(event.Value, &evs); err != nil {
return nil, fmt.Errorf("decode rofl app removed event value: %w", err)
}
for _, ev := range evs {
events = append(events, rofl.Event{AppRemoved: ev})
}
default:
return nil, fmt.Errorf("invalid rofl event code: %v", event.Code)
}
return events, nil
}

// unmarshalSingleOrArray tries to interpret `data` as an array of `T`.
// Failing that, it interprets it as a single `T`, and returns a slice
// of size 1 containing that `T`.
Expand Down
48 changes: 48 additions & 0 deletions analyzer/runtime/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/consensusaccounts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/core"
sdkEVM "github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/evm"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"
sdkTypes "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types"

"github.com/oasisprotocol/nexus/analyzer/evmabi"
Expand Down Expand Up @@ -109,6 +110,7 @@ type ScopedSdkEvent struct {
Accounts *accounts.Event
ConsensusAccounts *consensusaccounts.Event
EVM *sdkEVM.Event
Rofl *rofl.Event
}

type TokenChangeKey struct {
Expand Down Expand Up @@ -505,6 +507,25 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime
// TODO: maybe parse known token methods (ERC-20 etc)
return nil
},
RoflCreate: func(body *rofl.Create) error {
blockTransactionData.Body = body
return nil
},
RoflUpdate: func(body *rofl.Update) error {
blockTransactionData.Body = body
if _, err = addresses.RegisterRelatedSdkAddress(blockTransactionData.RelatedAccountAddresses, body.Admin); err != nil {
return fmt.Errorf("rofl.Update admin address: %w", err)
}
return nil
},
RoflRemove: func(body *rofl.Remove) error {
blockTransactionData.Body = body
return nil
},
RoflRegister: func(body *rofl.Register) error {
blockTransactionData.Body = body
return nil
},
UnknownMethod: func(methodName string) error {
logger.Warn("unknown tx method, skipping tx-specific analysis", "tx_method", methodName)
return nil
Expand Down Expand Up @@ -1359,6 +1380,33 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad
extractedEvents = append(extractedEvents, &eventData)
return nil
},
Rofl: func(event *rofl.Event) error {
if event.AppCreated != nil {
eventData := EventData{
Type: apiTypes.RuntimeEventTypeRoflAppCreated,
Body: event.AppCreated,
WithScope: ScopedSdkEvent{Rofl: event},
}
extractedEvents = append(extractedEvents, &eventData)
}
if event.AppRemoved != nil {
eventData := EventData{
Type: apiTypes.RuntimeEventTypeRoflAppRemoved,
Body: event.AppRemoved,
WithScope: ScopedSdkEvent{Rofl: event},
}
extractedEvents = append(extractedEvents, &eventData)
}
if event.AppUpdated != nil {
eventData := EventData{
Type: apiTypes.RuntimeEventTypeRoflAppUpdated,
Body: event.AppUpdated,
WithScope: ScopedSdkEvent{Rofl: event},
}
extractedEvents = append(extractedEvents, &eventData)
}
return nil
},
}); err != nil {
return nil, err
}
Expand Down
57 changes: 57 additions & 0 deletions analyzer/runtime/visitors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/consensusaccounts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/core"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/evm"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"
sdkTypes "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types"

"github.com/oasisprotocol/nexus/analyzer/evmabi"
Expand All @@ -27,6 +28,10 @@ type CallHandler struct {
ConsensusAccountsUndelegate func(body *consensusaccounts.Undelegate) error
EVMCreate func(body *evm.Create, ok *[]byte) error
EVMCall func(body *evm.Call, ok *[]byte) error
RoflCreate func(body *rofl.Create) error
RoflUpdate func(body *rofl.Update) error
RoflRemove func(body *rofl.Remove) error
RoflRegister func(body *rofl.Register) error
UnknownMethod func(methodName string) error // Invoked for a tx call that doesn't map to any of the above method names.
}

Expand Down Expand Up @@ -121,6 +126,46 @@ func VisitCall(call *sdkTypes.Call, result *sdkTypes.CallResult, handler *CallHa
return fmt.Errorf("evm call: %w", err)
}
}
case "rofl.Create":
if handler.RoflCreate != nil {
var body rofl.Create
if err := cbor.Unmarshal(call.Body, &body); err != nil {
return fmt.Errorf("unmarshal rofl create: %w", err)
}
if err := handler.RoflCreate(&body); err != nil {
return fmt.Errorf("rofl create: %w", err)
}
}
case "rofl.Update":
if handler.RoflUpdate != nil {
var body rofl.Update
if err := cbor.Unmarshal(call.Body, &body); err != nil {
return fmt.Errorf("unmarshal rofl update: %w", err)
}
if err := handler.RoflUpdate(&body); err != nil {
return fmt.Errorf("rofl update: %w", err)
}
}
case "rofl.Remove":
if handler.RoflRemove != nil {
var body rofl.Remove
if err := cbor.Unmarshal(call.Body, &body); err != nil {
return fmt.Errorf("unmarshal rofl remove: %w", err)
}
if err := handler.RoflRemove(&body); err != nil {
return fmt.Errorf("rofl remove: %w", err)
}
}
case "rofl.Register":
if handler.RoflRegister != nil {
var body rofl.Register
if err := cbor.Unmarshal(call.Body, &body); err != nil {
return fmt.Errorf("unmarshal rofl register: %w", err)
}
if err := handler.RoflRegister(&body); err != nil {
return fmt.Errorf("rofl register: %w", err)
}
}
default:
if handler.UnknownMethod != nil {
return handler.UnknownMethod(string(call.Method))
Expand All @@ -134,6 +179,7 @@ type SdkEventHandler struct {
Accounts func(event *accounts.Event) error
ConsensusAccounts func(event *consensusaccounts.Event) error
EVM func(event *evm.Event) error
Rofl func(event *rofl.Event) error
}

func VisitSdkEvent(event *nodeapi.RuntimeEvent, handler *SdkEventHandler) error {
Expand Down Expand Up @@ -181,6 +227,17 @@ func VisitSdkEvent(event *nodeapi.RuntimeEvent, handler *SdkEventHandler) error
}
}
}
if handler.Rofl != nil {
roflEvents, err := DecodeRoflEvent(event)
if err != nil {
return fmt.Errorf("decode rofl: %w", err)
}
for i := range roflEvents {
if err = handler.Rofl(&roflEvents[i]); err != nil {
return fmt.Errorf("decoded event %d rofl: %w", i, err)
}
}
}
return nil
}

Expand Down
7 changes: 7 additions & 0 deletions api/spec/v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2779,6 +2779,9 @@ components:
- consensus_accounts.undelegate_done
- core.gas_used
- evm.log
- rofl.app_created
- rofl.app_updated
- rofl.app_removed
example: *runtime_event_type_1

EvmAbiParam:
Expand Down Expand Up @@ -3009,6 +3012,10 @@ components:
- "consensus.Undelegate"
- "evm.Create"
- "evm.Call"
- "rofl.Create"
- "rofl.Update"
- "rofl.Remove"
- "rofl.Register"
May be null if the transaction was malformed or encrypted.
example: "evm.Call"
body:
Expand Down
Loading

0 comments on commit 4684659

Please sign in to comment.