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

consensus roothash events specialization #588

Merged
merged 22 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1db1e46
api: wrap more $ref in allOf
pro-wh Feb 27, 2024
939448c
storage: cobalt extract roothash executor committed node ID
pro-wh Dec 29, 2023
17ce303
storage: handle roothash.message consensus events
pro-wh Dec 29, 2023
de71c92
storage: specialize roothash message events
pro-wh Jan 9, 2024
2d09cea
storage: handle roothash.in_msg_processed consensus events
pro-wh Dec 16, 2023
de6de13
storage: retain roothash event runtime and round
pro-wh Dec 29, 2023
f832e88
storage: add roothash event columns and indexes
pro-wh Dec 16, 2023
437b9b4
consensus: add RuntimeFromId
pro-wh Dec 29, 2023
b44bc73
consensus: index roothash related runtime and round
pro-wh Jan 6, 2024
f99f123
consensus: add node id preimage todo
pro-wh Dec 29, 2023
3c418c1
api: add related runtime and round fields to consensus events
pro-wh Jan 3, 2024
d97f6dc
coreapi: add ExecutionDiscrepancyDetectedEvent.Round
pro-wh Feb 14, 2024
52501fe
storage: get new discrepancy round
pro-wh Feb 15, 2024
5ee212f
storage: bump cache keys for roothash events
pro-wh Jan 5, 2024
0b4f5e9
storage: split convertEvent
pro-wh Feb 15, 2024
dd13713
ci: show openapi lint report
pro-wh Feb 27, 2024
38bf07a
tests: unrelated event order change
pro-wh Feb 28, 2024
0ff09b7
tests: rebuild damask consensus cache
pro-wh Feb 28, 2024
abbb0f9
tests: reindex damask sourcify cache
pro-wh Feb 28, 2024
05980a9
tests: reindex eden sourcify cache
pro-wh Feb 29, 2024
a9a5ed8
tests: rebuild eden consensus cache
pro-wh Feb 29, 2024
0934827
consensus: rename related_runtime and related_runtime_round
pro-wh Feb 29, 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
2 changes: 1 addition & 1 deletion .github/workflows/ci-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
<api/spec/v1.yaml ./yq --output-format json | ./yq --output-format yaml --input-format json >api/spec/v1-normalized.yaml
- name: Validate OpenAPI definition
run: |
./vacuum lint --ruleset .vacuum.yaml --errors api/spec/v1-normalized.yaml
./vacuum lint --ruleset .vacuum.yaml --details --snippets --errors api/spec/v1-normalized.yaml

validate-migrations:
runs-on: ubuntu-20.04
Expand Down
36 changes: 30 additions & 6 deletions analyzer/consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import (
"os"
"strings"

coreCommon "github.com/oasisprotocol/oasis-core/go/common"
"github.com/oasisprotocol/oasis-core/go/common/cbor"
"github.com/oasisprotocol/oasis-core/go/common/crypto/signature"
sdkConfig "github.com/oasisprotocol/oasis-sdk/client-sdk/go/config"

"github.com/oasisprotocol/nexus/common"
"github.com/oasisprotocol/nexus/coreapi/v22.2.11/consensus/api/transaction"
genesis "github.com/oasisprotocol/nexus/coreapi/v22.2.11/genesis/api"
staking "github.com/oasisprotocol/nexus/coreapi/v22.2.11/staking/api"
Expand All @@ -37,9 +39,12 @@ const (
type EventType = apiTypes.ConsensusEventType // alias for brevity

type parsedEvent struct {
ty EventType
rawBody json.RawMessage
relatedAddresses []staking.Address
ty EventType
rawBody json.RawMessage
roothashRuntimeID *coreCommon.Namespace
roothashRuntime *common.Runtime
roothashRuntimeRound *uint64
relatedAddresses []staking.Address
}

// OpenSignedTxNoVerify decodes the Transaction inside a Signed transaction
Expand Down Expand Up @@ -479,6 +484,9 @@ func (m *processor) queueTxEventInserts(batch *storage.QueryBatch, data *consens
txr.Transaction.Hash().Hex(),
i,
accounts,
common.StringOrNil(eventData.roothashRuntimeID),
eventData.roothashRuntime,
eventData.roothashRuntimeRound,
)
}
uniqueTxAccounts := extractUniqueAddresses(txAccounts)
Expand Down Expand Up @@ -1035,6 +1043,9 @@ func (m *processor) queueSingleEventInserts(batch *storage.QueryBatch, eventData
nil,
nil,
accounts,
common.StringOrNil(eventData.roothashRuntimeID),
eventData.roothashRuntime,
eventData.roothashRuntimeRound,
)

return nil
Expand Down Expand Up @@ -1068,9 +1079,22 @@ func (m *processor) extractEventData(event nodeapi.Event) parsedEvent {
eventData.relatedAddresses = []staking.Address{event.GovernanceProposalSubmitted.Submitter}
case event.GovernanceVote != nil:
eventData.relatedAddresses = []staking.Address{event.GovernanceVote.Submitter}
case event.RoothashExecutorCommitted != nil && event.RoothashExecutorCommitted.NodeID != nil:
nodeAddr := staking.NewAddress(*event.RoothashExecutorCommitted.NodeID)
eventData.relatedAddresses = []staking.Address{nodeAddr}
case event.RoothashMisc != nil:
eventData.roothashRuntimeID = &event.RoothashMisc.RuntimeID
eventData.roothashRuntime = RuntimeFromID(event.RoothashMisc.RuntimeID, m.network)
eventData.roothashRuntimeRound = event.RoothashMisc.Round
case event.RoothashExecutorCommitted != nil:
eventData.roothashRuntimeID = &event.RoothashExecutorCommitted.RuntimeID
eventData.roothashRuntime = RuntimeFromID(event.RoothashExecutorCommitted.RuntimeID, m.network)
eventData.roothashRuntimeRound = &event.RoothashExecutorCommitted.Round
if event.RoothashExecutorCommitted.NodeID != nil {
// TODO: preimage?
nodeAddr := staking.NewAddress(*event.RoothashExecutorCommitted.NodeID)
eventData.relatedAddresses = []staking.Address{nodeAddr}
}
case event.RoothashMessage != nil:
eventData.roothashRuntimeID = &event.RoothashMessage.RuntimeID
eventData.roothashRuntime = RuntimeFromID(event.RoothashMessage.RuntimeID, m.network)
case event.RegistryEntity != nil:
addr := staking.NewAddress(event.RegistryEntity.Entity.ID)
accounts := []staking.Address{addr}
Expand Down
24 changes: 24 additions & 0 deletions analyzer/consensus/runtimes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package consensus

import (
"bytes"
"encoding/hex"

coreCommon "github.com/oasisprotocol/oasis-core/go/common"
sdkConfig "github.com/oasisprotocol/oasis-sdk/client-sdk/go/config"

"github.com/oasisprotocol/nexus/common"
)

func RuntimeFromID(rtid coreCommon.Namespace, network sdkConfig.Network) *common.Runtime {
for name, pt := range network.ParaTimes.All {
pro-wh marked this conversation as resolved.
Show resolved Hide resolved
id, err := hex.DecodeString(pt.ID)
if err != nil {
return nil
}
if bytes.Equal(id, rtid[:]) {
return common.Ptr(common.Runtime(name))
}
}
return nil
}
4 changes: 2 additions & 2 deletions analyzer/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ var (
schedule = excluded.schedule`

ConsensusEventInsert = `
INSERT INTO chain.events (type, body, tx_block, tx_hash, tx_index, related_accounts)
VALUES ($1, $2, $3, $4, $5, $6)`
INSERT INTO chain.events (type, body, tx_block, tx_hash, tx_index, related_accounts, roothash_runtime_id, roothash_runtime, roothash_runtime_round)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`

ConsensusAccountRelatedTransactionInsert = `
INSERT INTO chain.accounts_related_transactions (account_address, tx_block, tx_index)
Expand Down
51 changes: 38 additions & 13 deletions api/spec/v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ paths:
- in: query
name: rel
schema:
$ref: '#/components/schemas/StakingAddress'
allOf: [$ref: '#/components/schemas/StakingAddress']
# TODO: Implement autodetection of Eth addresses, get rid of last sentence.
description: |
A filter on related accounts. Every returned transaction will refer to
Expand Down Expand Up @@ -1557,6 +1557,11 @@ components:
- roothash.execution_discrepancy
- roothash.executor_committed
- roothash.finalized
# Note: roothash.message is no longer used as an event since Damask.
# Message results are now in RoundResults.
# The MessageEvent structure remains and is used in RoundResults.
- roothash.message
pro-wh marked this conversation as resolved.
Show resolved Hide resolved
- roothash.in_msg_processed
- staking.allowance_change
- staking.burn
- staking.escrow.add
Expand Down Expand Up @@ -1601,6 +1606,26 @@ components:
Hash of this event's originating transaction.
Absent if the event did not originate from a transaction.
example: *tx_hash_1
roothash_runtime_id:
type: string
pro-wh marked this conversation as resolved.
Show resolved Hide resolved
description: |
The ID of the runtime to which the event relates, encoded in hex.
Present only for events of type `roothash.*`.
example: 000000000000000000000000000000000000000000000000e2eaa99fc008f87f
roothash_runtime:
allOf: [$ref: '#/components/schemas/Runtime']
description: |
The runtime to which the event relates.
Present only for events of type `roothash.*`.
example: emerald
roothash_runtime_round:
type: integer
pro-wh marked this conversation as resolved.
Show resolved Hide resolved
format: int64
description: |
When applicable, the round in the runtime to which this event
relates.
Present only for events of type `roothash.*` except for
`roothash.execution_discrepancy` before Eden.
type:
allOf: [$ref: '#/components/schemas/ConsensusEventType']
description: The type of the event.
Expand Down Expand Up @@ -1730,7 +1755,7 @@ components:
type: boolean
description: Whether the entity has a node that is registered for being a validator, node is up to date, and has successfully registered itself. It may or may not be part of validator set.
media:
$ref: '#/components/schemas/ValidatorMedia'
allOf: [$ref: '#/components/schemas/ValidatorMedia']
current_rate:
type: integer
format: uint64
Expand Down Expand Up @@ -1899,7 +1924,7 @@ components:
type: string
description: The name of the token. Not guaranteed to be unique across distinct EVM tokens.
token_type:
$ref: "#/components/schemas/EvmTokenType"
allOf: [$ref: "#/components/schemas/EvmTokenType"]
token_decimals:
type: integer
description: The number of decimals of precision for this token.
Expand Down Expand Up @@ -2074,15 +2099,15 @@ components:
description: The staking address of the proposal submitter.
example: *staking_address_1
state:
$ref: '#/components/schemas/ProposalState'
allOf: [$ref: '#/components/schemas/ProposalState']
deposit:
allOf: [$ref: '#/components/schemas/TextBigInt']
description: The deposit attached to this proposal.
handler:
type: string
description: The name of the upgrade handler.
target:
$ref: '#/components/schemas/ProposalTarget'
allOf: [$ref: '#/components/schemas/ProposalTarget']
epoch:
type: integer
format: uint64
Expand Down Expand Up @@ -2315,7 +2340,7 @@ components:
type: object
properties:
type:
$ref: '#/components/schemas/EvmTokenType'
allOf: [$ref: '#/components/schemas/EvmTokenType']
symbol:
type: string
description: Symbol of the token, as provided by token contract's `symbol()` method.
Expand Down Expand Up @@ -2385,7 +2410,7 @@ components:
type: object
properties:
verification_level:
$ref: '#/components/schemas/VerificationLevel'
allOf: [$ref: '#/components/schemas/VerificationLevel']
compilation_metadata:
type: object
description: |
Expand Down Expand Up @@ -2610,7 +2635,7 @@ components:
description: The staking address for this account.
example: *staking_address_1
address_preimage:
$ref: '#/components/schemas/AddressPreimage'
allOf: [$ref: '#/components/schemas/AddressPreimage']
balances:
description: |
The balance(s) of this account in this runtime. Most runtimes use only one denomination, and thus
Expand All @@ -2619,7 +2644,7 @@ components:
this does not include ERC-20 tokens
type: array
items:
$ref: '#/components/schemas/RuntimeSdkBalance'
allOf: [$ref: '#/components/schemas/RuntimeSdkBalance']
evm_contract:
allOf: [$ref: '#/components/schemas/RuntimeEvmContract']
description: |
Expand All @@ -2631,9 +2656,9 @@ components:
NOTE: This field is limited to 1000 entries. If you need more, please let us know in a GitHub issue.
type: array
items:
$ref: '#/components/schemas/RuntimeEvmBalance'
allOf: [$ref: '#/components/schemas/RuntimeEvmBalance']
stats:
$ref: '#/components/schemas/AccountStats'
allOf: [$ref: '#/components/schemas/AccountStats']

RuntimeStatus:
type: object
Expand Down Expand Up @@ -2739,7 +2764,7 @@ components:
DEPRECATED: This field will be removed in the future in favor of verification_level
example: false
verification_level:
$ref: '#/components/schemas/VerificationLevel'
allOf: [$ref: '#/components/schemas/VerificationLevel']

EvmNftList:
allOf:
Expand All @@ -2761,7 +2786,7 @@ components:
- id
properties:
token:
$ref: '#/components/schemas/EvmToken'
allOf: [$ref: '#/components/schemas/EvmToken']
id:
allOf: [$ref: '#/components/schemas/TextBigInt']
description: The instance ID of this NFT within the collection represented by `token`.
Expand Down
2 changes: 2 additions & 0 deletions coreapi/v23.0/roothash/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ type ExecutorCommittedEvent struct {

// ExecutionDiscrepancyDetectedEvent is an execute discrepancy detected event.
type ExecutionDiscrepancyDetectedEvent struct {
// Round is the round in which the discrepancy was detected.
Round *uint64 `json:"round,omitempty"`
// Rank is the rank of the transaction scheduler.
Rank uint64 `json:"rank"`
// Timeout signals whether the discrepancy was due to a timeout.
Expand Down
13 changes: 13 additions & 0 deletions scripts/vendor-oasis-core/patches/v23.0/discrepancy_round.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/coreapi/v23.0/roothash/api/api.go b/coreapi/v23.0/roothash/api/api.go
index e7653d7d..e6a88db5 100644
--- a/coreapi/v23.0/roothash/api/api.go
+++ b/coreapi/v23.0/roothash/api/api.go
@@ -192,6 +192,8 @@ type ExecutorCommittedEvent struct {

// ExecutionDiscrepancyDetectedEvent is an execute discrepancy detected event.
type ExecutionDiscrepancyDetectedEvent struct {
+ // Round is the round in which the discrepancy was detected.
+ Round *uint64 `json:"round,omitempty"`
// Rank is the rank of the transaction scheduler.
Rank uint64 `json:"rank"`
// Timeout signals whether the discrepancy was due to a timeout.
11 changes: 10 additions & 1 deletion storage/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,16 @@ func (c *StorageClient) Events(ctx context.Context, p apiTypes.GetConsensusEvent

for res.rows.Next() {
var e Event
if err := res.rows.Scan(&e.Block, &e.TxIndex, &e.TxHash, &e.Type, &e.Body); err != nil {
if err := res.rows.Scan(
&e.Block,
&e.TxIndex,
&e.TxHash,
&e.RoothashRuntimeId,
&e.RoothashRuntime,
&e.RoothashRuntimeRound,
&e.Type,
&e.Body,
); err != nil {
return nil, wrapError(err)
}
es.Events = append(es.Events, e)
Expand Down
2 changes: 1 addition & 1 deletion storage/client/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const (
WHERE tx_hash = $1::text`

Events = `
SELECT tx_block, tx_index, tx_hash, type, body
SELECT tx_block, tx_index, tx_hash, roothash_runtime_id, roothash_runtime, roothash_runtime_round, type, body
FROM chain.events
WHERE ($1::bigint IS NULL OR tx_block = $1::bigint) AND
($2::integer IS NULL OR tx_index = $2::integer) AND
Expand Down
10 changes: 10 additions & 0 deletions storage/migrations/00_consensus.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,23 @@ CREATE TABLE chain.events
body JSONB,
tx_hash HEX64, -- could be fetched from `transactions` table; denormalized for efficiency
related_accounts TEXT[],
-- added in 10_roothash.up.sql
-- roothash_runtime_id HEX64,
-- roothash_runtime runtime,
-- roothash_runtime_round UINT63,

FOREIGN KEY (tx_block, tx_index) REFERENCES chain.transactions(block, tx_index) DEFERRABLE INITIALLY DEFERRED
);
CREATE INDEX ix_events_related_accounts ON chain.events USING gin(related_accounts);
CREATE INDEX ix_events_tx_block ON chain.events (tx_block); -- for fetching events without filters
CREATE INDEX ix_events_tx_hash ON chain.events (tx_hash);
CREATE INDEX ix_events_type ON chain.events (type, tx_block); -- tx_block is for sorting the events of a given type by recency
-- added in 10_roothash.up.sql
-- CREATE INDEX ix_events_roothash
-- ON chain.events (roothash_runtime, roothash_runtime_round)
-- WHERE
-- roothash_runtime IS NOT NULL AND
-- roothash_runtime_round IS NOT NULL;

-- Beacon Backend Data

Expand Down
32 changes: 32 additions & 0 deletions storage/migrations/10_roothash.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
BEGIN;

ALTER TABLE chain.events
-- There's some mismatch between oasis-core's style in Go and nexus's
-- style in SQL and JSON. oasis-core likes structures filled with nilable
-- pointers, where one pointer is non-nil. nexus likes a type string plus
-- a "body" blob. In roothash events though, the roothash/api Event
-- structure additionally has a RuntimeID field, which nexus otherwise
-- loses when it extracts the one non-nil event next to it. In the nexus,
-- database, we're storing that runtime identifier in a column.
--
-- This is a runtime identifier, which is a binary "namespace," e.g.
-- `000000000000000000000000000000000000000000000000f80306c9858e7279` for
-- Sapphire on Mainnet. This is taken from the event from the node, and it
-- is set even for runtimes that nexus isn't configured to analyze.
ADD COLUMN roothash_runtime_id HEX64,
-- This is a nexus runtime name, for example `sapphire`. This is only set
-- for supported runtimes.
ADD COLUMN roothash_runtime runtime,
ADD COLUMN roothash_runtime_round UINT63;

-- ix_events_roothash is the link between runtime blocks and consensus blocks.
-- Given a runtime block (runtime, round), you can look up the roothash events
-- with this index and find the events when the block was proposed (first
-- executor commit), committed to, and finalized.
CREATE INDEX ix_events_roothash
ON chain.events (roothash_runtime, roothash_runtime_round)
WHERE
roothash_runtime IS NOT NULL AND
roothash_runtime_round IS NOT NULL;

COMMIT;
Loading
Loading