Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrus committed Jan 23, 2025
1 parent 564b0a1 commit bf6f039
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 90 deletions.
20 changes: 8 additions & 12 deletions analyzer/evmabibackfill/evm_abi_backfill.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ type abiEncodedTx struct {

type abiEncodedEvent struct {
// Event primary key.
Runtime common.Runtime
Round uint64
TxIndex *int
Type string
TypeIndex int
Runtime common.Runtime
Round uint64
TxIndex int
EventIndex int

EventBody sdkEVM.Event
}
Expand Down Expand Up @@ -130,8 +129,7 @@ func (p *processor) GetItems(ctx context.Context, limit uint64) ([]*abiEncodedIt
&ev.Runtime,
&ev.Round,
&ev.TxIndex,
&ev.Type,
&ev.TypeIndex,
&ev.EventIndex,
&ev.EventBody,
); err != nil {
return nil, fmt.Errorf("scanning verified contract event: %w", err)
Expand Down Expand Up @@ -247,8 +245,7 @@ func (p *processor) ProcessItem(ctx context.Context, batch *storage.QueryBatch,
item.Event.Runtime,
item.Event.Round,
item.Event.TxIndex,
item.Event.Type,
item.Event.TypeIndex,
item.Event.EventIndex,
nil,
nil,
nil,
Expand All @@ -271,16 +268,15 @@ func (p *processor) ProcessItem(ctx context.Context, batch *storage.QueryBatch,
if item.Event != nil {
eventName, eventArgs, eventSig, err := p.parseEvent(item.Event, contractAbi)
if err != nil {
p.logger.Warn("error parsing event with abi", "err", err, "contract_address", item.ContractAddr, "event_round", item.Event.Round, "event_tx_index", item.Event.TxIndex)
p.logger.Warn("error parsing event with abi", "err", err, "contract_address", item.ContractAddr, "event_round", item.Event.Round, "event_tx_index", item.Event.TxIndex, "event_index", item.Event.EventIndex)
// Write to the DB regardless of error so we don't keep retrying the same item.
}
batch.Queue(
queries.RuntimeEventEvmParsedFieldsUpdate,
item.Event.Runtime,
item.Event.Round,
item.Event.TxIndex,
item.Event.Type,
item.Event.TypeIndex,
item.Event.EventIndex,
eventName,
eventArgs,
eventSig,
Expand Down
10 changes: 4 additions & 6 deletions analyzer/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,11 +636,11 @@ var (
tx_hash = $2`

RuntimeEventInsert = `
INSERT INTO chain.runtime_events (runtime, round, tx_index, type, type_index, tx_hash, tx_eth_hash, timestamp, body, evm_log_name, evm_log_params, evm_log_signature)
INSERT INTO chain.runtime_events (runtime, round, tx_index, event_index, tx_hash, tx_eth_hash, timestamp, type, body, evm_log_name, evm_log_params, evm_log_signature)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`

RuntimeEventRelatedAccountsInsert = `
INSERT INTO chain.runtime_events_related_accounts (runtime, round, tx_index, type, type_index, account_address)
INSERT INTO chain.runtime_events_related_accounts (runtime, round, tx_index, event_index, type, account_address)
SELECT $1, $2, $3, $4, $5, unnest($6::text[])`

// We use COALESCE here to avoid overwriting existing data with null values.
Expand All @@ -655,8 +655,7 @@ var (
runtime = $1 AND
round = $2 AND
tx_index = $3 AND
type = $4 AND
type_index = $5`
event_index = $4`

RuntimeMintInsert = `
INSERT INTO chain.runtime_transfers (runtime, round, sender, receiver, symbol, amount)
Expand Down Expand Up @@ -1142,8 +1141,7 @@ var (
evs.runtime,
evs.round,
evs.tx_index,
evs.type,
evs.type_index,
evs.event_index,
evs.body
FROM abi_contracts
JOIN chain.address_preimages as preimages ON
Expand Down
28 changes: 14 additions & 14 deletions analyzer/runtime/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ type EventData struct {
TxIndex *int // nil for non-tx events
TxHash *string // nil for non-tx events
TxEthHash *string // nil for non-evm-tx events
EventIdx int // Unique event index within the block.
Type apiTypes.RuntimeEventType
TypeIndex int // Events of the same type within the block are ordered by index.
Body EventBody
WithScope ScopedSdkEvent
EvmLogName *string
Expand Down Expand Up @@ -709,8 +709,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
Core: func(event *core.Event, eventIdx int) error {
if event.GasUsed != nil {
eventData := EventData{
EventIdx: eventIdx,
Type: apiTypes.RuntimeEventTypeCoreGasUsed,
TypeIndex: eventIdx,
Body: event.GasUsed,
WithScope: ScopedSdkEvent{Core: event},
}
Expand All @@ -729,8 +729,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("to: %w", err1)
}
eventData := EventData{
EventIdx: eventIdx,
Type: apiTypes.RuntimeEventTypeAccountsTransfer,
TypeIndex: eventIdx,
Body: event.Transfer,
WithScope: ScopedSdkEvent{Accounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}},
Expand All @@ -743,8 +743,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("owner: %w", err1)
}
eventData := EventData{
EventIdx: eventIdx,
Type: apiTypes.RuntimeEventTypeAccountsBurn,
TypeIndex: eventIdx,
Body: event.Burn,
WithScope: ScopedSdkEvent{Accounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{ownerAddr: {}},
Expand All @@ -757,8 +757,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("owner: %w", err1)
}
eventData := EventData{
EventIdx: eventIdx,
Type: apiTypes.RuntimeEventTypeAccountsMint,
TypeIndex: eventIdx,
Body: event.Mint,
WithScope: ScopedSdkEvent{Accounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{ownerAddr: {}},
Expand All @@ -779,8 +779,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("to: %w", err1)
}
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeConsensusAccountsDeposit,
TypeIndex: eventIndex,
Body: event.Deposit,
WithScope: ScopedSdkEvent{ConsensusAccounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}},
Expand All @@ -798,8 +798,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("to: %w", err1)
}
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeConsensusAccountsWithdraw,
TypeIndex: eventIndex,
Body: event.Withdraw,
WithScope: ScopedSdkEvent{ConsensusAccounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}},
Expand All @@ -818,8 +818,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("to: %w", err1)
}
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeConsensusAccountsDelegate,
TypeIndex: eventIndex,
Body: event.Delegate,
WithScope: ScopedSdkEvent{ConsensusAccounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}},
Expand All @@ -836,8 +836,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("to: %w", err1)
}
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeConsensusAccountsUndelegateStart,
TypeIndex: eventIndex,
Body: event.UndelegateStart,
WithScope: ScopedSdkEvent{ConsensusAccounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}},
Expand All @@ -855,8 +855,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("to: %w", err1)
}
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeConsensusAccountsUndelegateDone,
TypeIndex: eventIndex,
Body: event.UndelegateDone,
WithScope: ScopedSdkEvent{ConsensusAccounts: event},
RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}},
Expand All @@ -871,8 +871,8 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
return fmt.Errorf("event address: %w", err1)
}
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeEvmLog,
TypeIndex: eventIndex,
Body: event,
WithScope: ScopedSdkEvent{EVM: event},
RelatedAddresses: map[apiTypes.Address]struct{}{eventAddr: {}},
Expand Down Expand Up @@ -1414,26 +1414,26 @@ func extractEvents(blockData *BlockData, eventsRaw []nodeapi.RuntimeEvent) ([]*E
Rofl: func(event *rofl.Event, eventIndex int) error {
if event.AppCreated != nil {
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeRoflAppCreated,
TypeIndex: eventIndex,
Body: event.AppCreated,
WithScope: ScopedSdkEvent{Rofl: event},
}
extractedEvents = append(extractedEvents, &eventData)
}
if event.AppRemoved != nil {
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeRoflAppRemoved,
TypeIndex: eventIndex,
Body: event.AppRemoved,
WithScope: ScopedSdkEvent{Rofl: event},
}
extractedEvents = append(extractedEvents, &eventData)
}
if event.AppUpdated != nil {
eventData := EventData{
EventIdx: eventIndex,
Type: apiTypes.RuntimeEventTypeRoflAppUpdated,
TypeIndex: eventIndex,
Body: event.AppUpdated,
WithScope: ScopedSdkEvent{Rofl: event},
}
Expand Down
6 changes: 3 additions & 3 deletions analyzer/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,11 +415,11 @@ func (m *processor) queueDbUpdates(batch *storage.QueryBatch, data *BlockData) {
m.runtime,
data.Header.Round,
txIdx,
eventData.Type,
eventData.TypeIndex,
eventData.EventIdx,
eventData.TxHash,
eventData.TxEthHash,
data.Header.Timestamp,
eventData.Type,
eventData.Body,
eventData.EvmLogName,
eventData.EvmLogParams,
Expand All @@ -431,8 +431,8 @@ func (m *processor) queueDbUpdates(batch *storage.QueryBatch, data *BlockData) {
m.runtime,
data.Header.Round,
txIdx,
eventData.EventIdx,
eventData.Type,
eventData.TypeIndex,
addresses.SliceFromSet(eventData.RelatedAddresses),
)
}
Expand Down
41 changes: 23 additions & 18 deletions analyzer/runtime/visitors.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,69 +182,74 @@ type SdkEventHandler struct {
Rofl func(event *rofl.Event, eventIdx int) error
}

func VisitSdkEvent(event *nodeapi.RuntimeEvent, handler *SdkEventHandler) error {
func VisitSdkEvent(event *nodeapi.RuntimeEvent, handler *SdkEventHandler, eventIdx int) (int, error) {
if handler.Core != nil {
coreEvents, err := DecodeCoreEvent(event)
if err != nil {
return fmt.Errorf("decode core: %w", err)
return 0, fmt.Errorf("decode core: %w", err)
}
for i := range coreEvents {
if err = handler.Core(&coreEvents[i], i); err != nil {
return fmt.Errorf("decoded event %d core: %w", i, err)
if err = handler.Core(&coreEvents[i], eventIdx+i); err != nil {
return 0, fmt.Errorf("decoded event %d core: %w", i, err)
}
}
}
if handler.Accounts != nil {
accountEvents, err := DecodeAccountsEvent(event)
if err != nil {
return fmt.Errorf("decode accounts: %w", err)
return 0, fmt.Errorf("decode accounts: %w", err)
}
for i := range accountEvents {
if err = handler.Accounts(&accountEvents[i], i); err != nil {
return fmt.Errorf("decoded event %d accounts: %w", i, err)
if err = handler.Accounts(&accountEvents[i], eventIdx); err != nil {
return 0, fmt.Errorf("decoded event %d accounts: %w", i, err)
}
eventIdx++
}
}
if handler.ConsensusAccounts != nil {
consensusAccountsEvents, err := DecodeConsensusAccountsEvent(event)
if err != nil {
return fmt.Errorf("decode consensus accounts: %w", err)
return 0, fmt.Errorf("decode consensus accounts: %w", err)
}
for i := range consensusAccountsEvents {
if err = handler.ConsensusAccounts(&consensusAccountsEvents[i], i); err != nil {
return fmt.Errorf("decoded event %d consensus accounts: %w", i, err)
if err = handler.ConsensusAccounts(&consensusAccountsEvents[i], eventIdx); err != nil {
return 0, fmt.Errorf("decoded event %d consensus accounts: %w", i, err)
}
eventIdx++
}
}
if handler.EVM != nil {
evmEvents, err := DecodeEVMEvent(event)
if err != nil {
return fmt.Errorf("decode evm: %w", err)
return 0, fmt.Errorf("decode evm: %w", err)
}
for i := range evmEvents {
if err = handler.EVM(&evmEvents[i], i); err != nil {
return fmt.Errorf("decoded event %d evm: %w", i, err)
if err = handler.EVM(&evmEvents[i], eventIdx); err != nil {
return 0, fmt.Errorf("decoded event %d evm: %w", i, err)
}
eventIdx++
}
}
if handler.Rofl != nil {
roflEvents, err := DecodeRoflEvent(event)
if err != nil {
return fmt.Errorf("decode rofl: %w", err)
return 0, fmt.Errorf("decode rofl: %w", err)
}
for i := range roflEvents {
if err = handler.Rofl(&roflEvents[i], i); err != nil {
return fmt.Errorf("decoded event %d rofl: %w", i, err)
if err = handler.Rofl(&roflEvents[i], eventIdx); err != nil {
return 0, fmt.Errorf("decoded event %d rofl: %w", i, err)
}
eventIdx++
}
}
return nil
return eventIdx, nil
}

func VisitSdkEvents(events []nodeapi.RuntimeEvent, handler *SdkEventHandler) error {
var err error
var idx int
for i := range events {
if err = VisitSdkEvent(&events[i], handler); err != nil {
if idx, err = VisitSdkEvent(&events[i], handler, idx); err != nil {
return fmt.Errorf("event %d: %w; raw event: %+v", i, err, events[i])
}
}
Expand Down
18 changes: 9 additions & 9 deletions storage/migrations/01_runtimes.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -145,19 +145,21 @@ CREATE TABLE chain.runtime_events
round UINT63 NOT NULL,

tx_index INTEGER NOT NULL, -- -1 for events not associated with a transaction.
type TEXT NOT NULL,
type_index UINT31 NOT NULL, -- The index within events of the same type emitted within the block.

PRIMARY KEY (runtime, round, tx_index, type, type_index),
FOREIGN KEY (runtime, round, tx_index) REFERENCES chain.runtime_transactions(runtime, round, tx_index) DEFERRABLE INITIALLY DEFERRED,

-- Added in 13_runtime_events_related_accounts.up.sql.
-- event_index UINT31 NOT NULL, -- Unique event index within the block. We need this so that we can uniquely reference events.
-- PRIMARY KEY (runtime, round, tx_index, event_index),

tx_hash HEX64,
tx_eth_hash HEX64,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL,


-- The raw event, as returned by the oasis-sdk runtime client.
type TEXT NOT NULL,
body JSONB NOT NULL,
related_accounts TEXT[], -- Removed in 13_runtime_events_related_accounts.up.sql.

-- The events of type `evm.log` are further parsed into known event types, e.g. (ERC20) Transfer,
-- to populate the `evm_log_name`, `evm_log_params`, and `evm_log_signature` fields.
Expand All @@ -169,14 +171,12 @@ CREATE TABLE chain.runtime_events

-- Internal tracking for parsing evm.Call events using the contract
-- abi when available.
abi_parsed_at TIMESTAMP WITH TIME ZONE,

related_accounts TEXT[] -- Removed in 12_runtime_events_related_accounts.up.sql.
abi_parsed_at TIMESTAMP WITH TIME ZONE
);
CREATE INDEX ix_runtime_events_round ON chain.runtime_events(runtime, round); -- for sorting by round, when there are no filters applied
CREATE INDEX ix_runtime_events_tx_hash ON chain.runtime_events USING hash (tx_hash);
CREATE INDEX ix_runtime_events_tx_eth_hash ON chain.runtime_events USING hash (tx_eth_hash);
CREATE INDEX ix_runtime_events_related_accounts ON chain.runtime_events USING gin(related_accounts); -- for fetching account activity for a given account -- Deleted in 12_runtime_events_related_accounts.up.sql.
CREATE INDEX ix_runtime_events_related_accounts ON chain.runtime_events USING gin(related_accounts); -- for fetching account activity for a given account -- Removed in 13_runtime_events_related_accounts.up.sql.
CREATE INDEX ix_runtime_events_evm_log_signature ON chain.runtime_events(runtime, evm_log_signature, round); -- for fetching a certain event type, eg Transfers
CREATE INDEX ix_runtime_events_evm_log_params ON chain.runtime_events USING gin(evm_log_params);
CREATE INDEX ix_runtime_events_type ON chain.runtime_events (runtime, type);
Expand All @@ -192,7 +192,7 @@ CREATE INDEX ix_runtime_events_nft_transfers ON chain.runtime_events (runtime, (
-- WHERE
-- type = 'evm.log';

-- Added in 12_runtime_events_related_accounts.up.sql.
-- Added in 13_runtime_events_related_accounts.up.sql.
-- CREATE TABLE chain.runtime_events_related_accounts
-- (
-- runtime runtime NOT NULL,
Expand Down
Loading

0 comments on commit bf6f039

Please sign in to comment.