Disclaimer: These are planning documents. The functionalities described
here may be unimplemented, partially implemented, or implemented differently
than the original design.
Splinter v0.7 Database Design
Scabbard v3
erDiagram
scabbard_service {
Text circuit_id PK
Text service_id PK
Text status
Text consensus
}
scabbard_alarm {
Text circuit_id PK
Text service_id PK
Text alarm_type PK
BigInt alarm
}
scabbard_alarm }o--|| scabbard_service: contains
scabbard_peer {
Text circuit_id PK
Text service_id PK
Text peer_service_id PK
}
scabbard_peer }o--|| scabbard_service: contains
scabbard_alarm
Diesel
table! {
scabbard_alarm (circuit_id, service_id, alarm_type) {
circuit_id -> Text,
service_id -> Text,
alarm_type -> Text,
alarm -> BigInt,
}
}
PostgreSQL
Table "public.scabbard_alarm"
Column | Type | Collation | Nullable | Default
------------+------------+-----------+----------+---------
circuit_id | text | | not null |
service_id | text | | not null |
alarm_type | alarm_type | | not null |
alarm | bigint | | not null |
Indexes:
"scabbard_alarm_pkey" PRIMARY KEY, btree (circuit_id, service_id, alarm_type)
Foreign-key constraints:
"scabbard_alarm_service_id_fkey" FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id) ON DELETE CASCADE
SQLite
CREATE TABLE scabbard_alarm (
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
alarm_type TEXT NOT NULL
CHECK ( alarm_type IN ('TWO_PHASE_COMMIT')),
alarm BIGINT NOT NULL,
FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id) ON DELETE CASCADE,
PRIMARY KEY (circuit_id, service_id, alarm_type)
);
scabbard_peer
Diesel
table! {
scabbard_peer (circuit_id, service_id, peer_service_id) {
circuit_id -> Text,
service_id -> Text,
peer_service_id -> Text,
}
}
PostgreSQL
Table "public.scabbard_peer"
Column | Type | Collation | Nullable | Default
-----------------+------+-----------+----------+---------
circuit_id | text | | not null |
service_id | text | | not null |
peer_service_id | text | | not null |
Indexes:
"scabbard_peer_pkey" PRIMARY KEY, btree (circuit_id, service_id, peer_service_id)
Foreign-key constraints:
"scabbard_peer_service_id_fkey" FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
SQLite
CREATE TABLE scabbard_peer (
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
peer_service_id TEXT,
PRIMARY KEY(circuit_id, service_id, peer_service_id),
FOREIGN KEY(circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
);
scabbard_service
Diesel
table! {
scabbard_service (circuit_id, service_id) {
circuit_id -> Text,
service_id -> Text,
consensus -> Text,
status -> Text,
}
}
PostgreSQL
Table "public.scabbard_service"
Column | Type | Collation | Nullable | Default
------------+------------------------------+-----------+----------+---------------------------
circuit_id | text | | not null |
service_id | text | | not null |
status | scabbard_service_status_type | | not null |
consensus | scabbard_consensus | | not null | '2PC'::scabbard_consensus
Indexes:
"scabbard_service_pkey" PRIMARY KEY, btree (circuit_id, service_id)
SQLite
CREATE TABLE scabbard_service (
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
status TEXT NOT NULL
CHECK ( status IN ('PREPARED', 'FINALIZED', 'RETIRED') )
, consensus Text NOT NULL DEFAULT '2PC'
CHECK ( consensus IN ('2PC') ),
PRIMARY KEY(circuit_id, service_id)
);
scabbard_v3_commit_history
Diesel Schema
table! {
scabbard_v3_commit_history (circuit_id, service_id, epoch) {
circuit_id -> Text,
service_id -> Text,
epoch -> BigInt,
value -> VarChar,
decision -> Nullable<Text>,
}
}
Scabbard v3: 2PC Consensus
Context
A consensus context contains current information maintained by the consensus algorithm in use (for example, 2PC).
These tables persist specific Augrim data structures.
erDiagram
consensus_2pc_context {
Text circuit_id PK
Text service_id PK
Text coordinator
BigInt epoch
BigInt last_commit_epoch
Text state
BigInt vote_timer_start
Boolean vote
BigInt decision_timeout_start
}
consensus_2pc_context_participant {
Text circuit_id PK
Text service_id PK
Text process PK
BigInt epoch
Boolean vote
Boolean decision_ack
}
consensus_2pc_context }o--|| scabbard_service: contains
consensus_2pc_context_participant }o--|| scabbard_service: contains
Actions
A consensus action is the result of processing an event with a consensus algorithm, and represents work which must be performed.
erDiagram
consensus_2pc_action {
INTEGER id PK
TEXT circuit_id FK
TEXT service_id FK
TIMESTAMP created_at
BIGINT executed_at
TEXT action_type
}
consensus_2pc_action }o--|| scabbard_service: contains
consensus_2pc_update_context_action {
Int8 action_id PK
Text coordinator
BigInt epoch
BigInt last_commit_epoch
Text state
BigInt vote_timeout_start
Boolean vote
BigInt decision_timeout_start
BigInt action_alarm
}
consensus_2pc_action ||--o| consensus_2pc_update_context_action: is
consensus_2pc_send_message_action {
Int8 action_id PK
BigInt epoch
Text receiver_service_id
Text message_type
Boolean vote_response
Binary vote_request
}
consensus_2pc_action ||--o| consensus_2pc_send_message_action: is
consensus_2pc_notification_action {
Int8 action_id PK
Text notification_type
Text dropped_message
Binary request_for_vote_value
}
consensus_2pc_action ||--o| consensus_2pc_notification_action: is
consensus_2pc_update_context_action_participant {
Int8 action_id PK
Text process PK
Boolean vote
Boolean decision_ack
}
consensus_2pc_action ||--o| consensus_2pc_update_context_action_participant: is
Events
A consensus event is input into the consensus algorithm.
erDiagram
consensus_2pc_event {
Int8 id PK
Text circuit_id FK
Text service_id FK
Timestamp created_at
BigInt executed_at
Text event_type
BigInt executed_epoch
}
consensus_2pc_event }o--|| scabbard_service: contains
consensus_2pc_deliver_event {
Int8 event_id PK
BigInt epoch
Text receiver_service_id
Text message_type
Boolean vote_response
Binary vote_request
}
consensus_2pc_event ||--o| consensus_2pc_deliver_event: is
consensus_2pc_start_event {
Int8 event_id PK
Binary value
}
consensus_2pc_event ||--o| consensus_2pc_start_event: is
consensus_2pc_vote_event {
Int8 event_id PK
Boolean vote
}
consensus_2pc_event ||--o| consensus_2pc_vote_event: is
consensus_2pc_action
Diesel
table! {
consensus_2pc_action (id) {
id -> Int8,
circuit_id -> Text,
service_id -> Text,
created_at -> Timestamp,
executed_at -> Nullable<BigInt>,
action_type -> Text,
event_id -> Int8,
}
}
PostgreSQL
Table "public.consensus_2pc_action"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+--------------------------------------------------
id | bigint | | not null | nextval('consensus_2pc_action_id_seq'::regclass)
circuit_id | text | | not null |
service_id | text | | not null |
created_at | timestamp without time zone | | not null | CURRENT_TIMESTAMP
executed_at | bigint | | |
action_type | text | | not null |
event_id | bigint | | not null |
Indexes:
"consensus_2pc_action_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"consensus_2pc_action_circuit_id_service_id_fkey" FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
"consensus_2pc_action_event_id_fkey" FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id)
SQLite
CREATE TABLE consensus_2pc_action (
id INTEGER PRIMARY KEY AUTOINCREMENT,
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
executed_at BIGINT,
action_type TEXT,
event_id INTEGER NOT NULL,
FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id)
);
consensus_2pc_context
Diesel
table! {
consensus_2pc_context (circuit_id, service_id) {
circuit_id -> Text,
service_id -> Text,
coordinator -> Text,
epoch -> BigInt,
last_commit_epoch -> Nullable<BigInt>,
state -> Text,
vote_timeout_start -> Nullable<BigInt>,
vote -> Nullable<Bool>,
decision_timeout_start -> Nullable<BigInt>,
}
}
PostgreSQL
Table "public.consensus_2pc_context"
Column | Type | Collation | Nullable | Default
------------------------+---------------+-----------+----------+---------
circuit_id | text | | not null |
service_id | text | | not null |
coordinator | text | | not null |
epoch | bigint | | not null |
last_commit_epoch | bigint | | |
state | context_state | | not null |
vote_timeout_start | bigint | | |
vote | boolean | | |
decision_timeout_start | bigint | | |
Indexes:
"consensus_2pc_context_pkey" PRIMARY KEY, btree (circuit_id, service_id)
Check constraints:
"consensus_2pc_context_check" CHECK (vote_timeout_start IS NOT NULL OR state <> 'VOTING'::context_state)
"consensus_2pc_context_check1" CHECK (vote IS NOT NULL OR state <> 'VOTED'::context_state)
"consensus_2pc_context_check2" CHECK (decision_timeout_start IS NOT NULL OR state <> 'VOTED'::context_state)
Foreign-key constraints:
"consensus_2pc_context_circuit_id_service_id_fkey" FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
SQLite
CREATE TABLE consensus_2pc_context (
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
coordinator TEXT NOT NULL,
epoch BIGINT NOT NULL,
last_commit_epoch BIGINT,
state TEXT NOT NULL
CHECK ( state IN ( 'WAITING_FOR_START', 'VOTING', 'WAITING_FOR_VOTE', 'ABORT', 'COMMIT', 'WAITING_FOR_VOTE_REQUEST', 'VOTED', 'WAITING_FOR_DECISION_ACK') ),
vote_timeout_start BIGINT
CHECK ( (vote_timeout_start IS NOT NULL) OR ( state != 'VOTING') ),
vote NUMERIC
CHECK ( (vote IS NOT NULL) OR ( state != 'VOTED') ),
decision_timeout_start BIGINT
CHECK ( (decision_timeout_start IS NOT NULL) OR ( state != 'VOTED') ),
PRIMARY KEY(circuit_id, service_id),
FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
);
consensus_2pc_context_participant
Diesel
table! {
consensus_2pc_context_participant (circuit_id, service_id, process) {
circuit_id -> Text,
service_id -> Text,
epoch -> BigInt,
process -> Text,
vote -> Nullable<Bool>,
decision_ack -> Bool,
}
}
PostgreSQL
Table "public.consensus_2pc_context_participant"
Column | Type | Collation | Nullable | Default
--------------+---------+-----------+----------+---------
circuit_id | text | | not null |
service_id | text | | not null |
epoch | bigint | | not null |
process | text | | not null |
vote | boolean | | |
decision_ack | boolean | | not null | false
Indexes:
"consensus_2pc_context_participant_pkey" PRIMARY KEY, btree (circuit_id, service_id, process)
Foreign-key constraints:
"consensus_2pc_context_participant_circuit_id_service_id_fkey" FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
SQLite
CREATE TABLE consensus_2pc_context_participant (
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
epoch BIGINT NOT NULL,
process TEXT NOT NULL,
vote NUMERIC,
decision_ack NUMERIC NOT NULL DEFAULT 0,
PRIMARY KEY (circuit_id, service_id, process),
FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
);
consensus_2pc_deliver_event
Diesel
table! {
consensus_2pc_deliver_event (event_id) {
event_id -> Int8,
epoch -> BigInt,
receiver_service_id -> Text,
message_type -> Text,
vote_response -> Nullable<Bool>,
vote_request -> Nullable<Binary>,
}
}
PostgreSQL
Table "public.consensus_2pc_deliver_event"
Column | Type | Collation | Nullable | Default
---------------------+----------------------------+-----------+----------+---------
event_id | integer | | not null |
epoch | bigint | | not null |
receiver_service_id | text | | not null |
message_type | deliver_event_message_type | | not null |
vote_response | boolean | | |
vote_request | bytea | | |
Indexes:
"consensus_2pc_deliver_event_pkey" PRIMARY KEY, btree (event_id)
Check constraints:
"consensus_2pc_deliver_event_check" CHECK ((vote_response IS NOT NULL) OR message_type <> 'VOTE_RESPONSE'::deliver_event_message_type)
"consensus_2pc_deliver_event_check1" CHECK (vote_request IS NOT NULL OR message_type <> 'VOTE_REQUEST'::deliver_event_message_type)
Foreign-key constraints:
"consensus_2pc_deliver_event_event_id_fkey" FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id) ON DELETE CASCADE
SQLite
CREATE TABLE consensus_2pc_deliver_event (
event_id INTEGER PRIMARY KEY,
epoch BIGINT NOT NULL,
receiver_service_id TEXT NOT NULL,
message_type TEXT NOT NULL
CHECK ( message_type IN ('VOTE_RESPONSE', 'DECISION_REQUEST', 'VOTE_REQUEST', 'COMMIT', 'ABORT', 'DECISION_ACK') ),
vote_response NUMERIC
CHECK ( (vote_response IS NOT NULL) OR (message_type != 'VOTE_RESPONSE') ),
vote_request BINARY
CHECK ( (vote_request IS NOT NULL) OR (message_type != 'VOTE_REQUEST') ),
FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id) ON DELETE CASCADE
);
consensus_2pc_event
Diesel
table! {
consensus_2pc_event (id) {
id -> Int8,
circuit_id -> Text,
service_id -> Text,
created_at -> Timestamp,
executed_at -> Nullable<BigInt>,
event_type -> Text,
executed_epoch -> Nullable<BigInt>,
}
}
PostgreSQL
Table "public.consensus_2pc_event"
Column | Type | Collation | Nullable | Default
----------------+-----------------------------+-----------+----------+-------------------------------------------------
id | bigint | | not null | nextval('consensus_2pc_event_id_seq'::regclass)
circuit_id | text | | not null |
service_id | text | | not null |
created_at | timestamp without time zone | | not null | CURRENT_TIMESTAMP
executed_at | bigint | | |
event_type | event_type | | not null |
executed_epoch | bigint | | |
Indexes:
"consensus_2pc_event_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"consensus_2pc_event_circuit_id_service_id_fkey" FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
SQLite
CREATE TABLE consensus_2pc_event (
id INTEGER PRIMARY KEY AUTOINCREMENT,
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
executed_at BIGINT,
event_type TEXT NOT NULL
CHECK ( event_type IN ('ALARM', 'DELIVER', 'START', 'VOTE') ),
executed_epoch BIGINT,
FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id)
);
consensus_2pc_notification_action
Diesel
table! {
consensus_2pc_notification_action (action_id) {
action_id -> Int8,
notification_type -> Text,
dropped_message -> Nullable<Text>,
request_for_vote_value -> Nullable<Binary>,
}
}
PostgreSQL
Table "public.consensus_2pc_notification_action"
Column | Type | Collation | Nullable | Default
------------------------+-------------------+-----------+----------+---------
action_id | integer | | not null |
notification_type | notification_type | | not null |
dropped_message | text | | |
request_for_vote_value | bytea | | |
Indexes:
"consensus_2pc_notification_action_pkey" PRIMARY KEY, btree (action_id)
Check constraints:
"consensus_2pc_notification_action_check" CHECK (dropped_message IS NOT NULL OR notification_type <> 'MESSAGE_DROPPED'::notification_type)
"consensus_2pc_notification_action_check1" CHECK (request_for_vote_value IS NOT NULL OR notification_type <> 'PARTICIPANT_REQUEST_FOR_VOTE'::notification_type)
Foreign-key constraints:
"consensus_2pc_notification_action_action_id_fkey" FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
SQLite
CREATE TABLE consensus_2pc_notification_action (
action_id INTEGER PRIMARY KEY,
notification_type TEXT NOT NULL
CHECK ( notification_type IN ('REQUEST_FOR_START', 'COORDINATOR_REQUEST_FOR_VOTE', 'PARTICIPANT_REQUEST_FOR_VOTE', 'COMMIT', 'ABORT', 'MESSAGE_DROPPED') ),
dropped_message TEXT
CHECK ( (dropped_message IS NOT NULL) OR (notification_type != 'MESSAGE_DROPPED') ),
request_for_vote_value BINARY
CHECK ( (request_for_vote_value IS NOT NULL) OR (notification_type != 'PARTICIPANT_REQUEST_FOR_VOTE') ),
FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
);
consensus_2pc_send_message_action
Diesel
table! {
consensus_2pc_send_message_action (action_id) {
action_id -> Int8,
epoch -> BigInt,
receiver_service_id -> Text,
message_type -> Text,
vote_response -> Nullable<Bool>,
vote_request -> Nullable<Binary>,
}
}
PostgreSQL
Table "public.consensus_2pc_send_message_action"
Column | Type | Collation | Nullable | Default
---------------------+--------------+-----------+----------+---------
action_id | integer | | not null |
epoch | bigint | | not null |
receiver_service_id | text | | not null |
message_type | message_type | | not null |
vote_response | boolean | | |
vote_request | bytea | | |
Indexes:
"consensus_2pc_send_message_action_pkey" PRIMARY KEY, btree (action_id)
Check constraints:
"consensus_2pc_send_message_action_check" CHECK ((vote_response IS NOT NULL) OR message_type <> 'VOTE_RESPONSE'::message_type)
"consensus_2pc_send_message_action_check1" CHECK (vote_request IS NOT NULL OR message_type <> 'VOTE_REQUEST'::message_type)
Foreign-key constraints:
"consensus_2pc_send_message_action_action_id_fkey" FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
SQLite
CREATE TABLE consensus_2pc_send_message_action (
action_id INTEGER PRIMARY KEY,
epoch BIGINT NOT NULL,
receiver_service_id TEXT NOT NULL,
message_type TEXT NOT NULL
CHECK ( message_type IN ('VOTE_RESPONSE', 'DECISION_REQUEST', 'VOTE_REQUEST', 'COMMIT', 'ABORT', 'DECISION_ACK') ),
vote_response NUMERIC
CHECK ( (vote_response IS NOT NULL) OR (message_type != 'VOTE_RESPONSE') ),
vote_request BINARY
CHECK ( (vote_request IS NOT NULL) OR (message_type != 'VOTE_REQUEST') ),
FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
);
consensus_2pc_start_event
Diesel
table! {
consensus_2pc_start_event (event_id) {
event_id -> Int8,
value -> Binary,
}
}
PostgreSQL
Table "public.consensus_2pc_start_event"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+---------
event_id | integer | | not null |
value | bytea | | |
Indexes:
"consensus_2pc_start_event_pkey" PRIMARY KEY, btree (event_id)
Foreign-key constraints:
"consensus_2pc_start_event_event_id_fkey" FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id) ON DELETE CASCADE
SQLite
CREATE TABLE consensus_2pc_start_event (
event_id INTEGER PRIMARY KEY,
value BINARY,
FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id) ON DELETE CASCADE
);
consensus_2pc_update_context_action
Diesel
table! {
consensus_2pc_update_context_action (action_id) {
action_id -> Int8,
coordinator -> Text,
epoch -> BigInt,
last_commit_epoch -> Nullable<BigInt>,
state -> Text,
vote_timeout_start -> Nullable<BigInt>,
vote -> Nullable<Bool>,
decision_timeout_start -> Nullable<BigInt>,
action_alarm -> Nullable<BigInt>,
}
}
PostgreSQL
Table "public.consensus_2pc_update_context_action"
Column | Type | Collation | Nullable | Default
------------------------+---------------+-----------+----------+---------
action_id | integer | | not null |
coordinator | text | | not null |
epoch | bigint | | not null |
last_commit_epoch | bigint | | |
state | context_state | | not null |
vote_timeout_start | bigint | | |
vote | boolean | | |
decision_timeout_start | bigint | | |
action_alarm | bigint | | |
Indexes:
"consensus_2pc_update_context_action_pkey" PRIMARY KEY, btree (action_id)
Check constraints:
"consensus_2pc_update_context_action_check" CHECK (vote_timeout_start IS NOT NULL OR state <> 'VOTING'::context_state)
"consensus_2pc_update_context_action_check1" CHECK ((vote IS NOT NULL) OR state <> 'VOTED'::context_state)
"consensus_2pc_update_context_action_check2" CHECK (decision_timeout_start IS NOT NULL OR state <> 'VOTED'::context_state)
Foreign-key constraints:
"consensus_2pc_update_context_action_action_id_fkey" FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
SQLite
CREATE TABLE consensus_2pc_update_context_action (
action_id INTEGER PRIMARY KEY,
coordinator TEXT NOT NULL,
epoch BIGINT NOT NULL,
last_commit_epoch BIGINT,
state TEXT NOT NULL
CHECK ( state IN ( 'WAITING_FOR_START', 'VOTING', 'WAITING_FOR_VOTE', 'ABORT', 'COMMIT', 'WAITING_FOR_VOTE_REQUEST', 'VOTED', 'WAITING_FOR_DECISION_ACK') ),
vote_timeout_start BIGINT
CHECK ( (vote_timeout_start IS NOT NULL) OR ( state != 'VOTING') ),
vote NUMERIC
CHECK ( (vote IS NOT NULL) OR ( state != 'VOTED') ),
decision_timeout_start BIGINT
CHECK ( (decision_timeout_start IS NOT NULL) OR ( state != 'VOTED') ),
action_alarm BIGINT,
FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
);
consensus_2pc_update_context_action_participant
Diesel
table! {
consensus_2pc_update_context_action_participant (action_id, process) {
action_id -> Int8,
process -> Text,
vote -> Nullable<Bool>,
decision_ack -> Bool,
}
}
PostgreSQL
Table "public.consensus_2pc_update_context_action_participant"
Column | Type | Collation | Nullable | Default
--------------+---------+-----------+----------+---------
action_id | integer | | not null |
process | text | | not null |
vote | boolean | | |
decision_ack | boolean | | not null | false
Indexes:
"consensus_2pc_update_context_action_participant_pkey" PRIMARY KEY, btree (action_id, process)
Foreign-key constraints:
"consensus_2pc_update_context_action_participant_action_id_fkey" FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
"consensus_2pc_update_context_action_participant_action_id_fkey1" FOREIGN KEY (action_id) REFERENCES consensus_2pc_update_context_action(action_id) ON DELETE CASCADE
SQLite
CREATE TABLE consensus_2pc_update_context_action_participant (
action_id INTEGER PRIMARY KEY,
process TEXT NOT NULL,
vote NUMERIC,
decision_ack NUMERIC NOT NULL DEFAULT 0,
FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE,
FOREIGN KEY (action_id) REFERENCES consensus_2pc_update_context_action(action_id) ON DELETE CASCADE
);
consensus_2pc_vote_event
Diesel
table! {
consensus_2pc_vote_event (event_id) {
event_id -> Int8,
vote -> Bool,
}
}
PostgreSQL
Table "public.consensus_2pc_vote_event"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+---------
event_id | integer | | not null |
vote | boolean | | not null |
Indexes:
"consensus_2pc_vote_event_pkey" PRIMARY KEY, btree (event_id)
Foreign-key constraints:
"consensus_2pc_vote_event_event_id_fkey" FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id) ON DELETE CASCADE
SQLite
CREATE TABLE consensus_2pc_vote_event (
event_id INTEGER PRIMARY KEY,
vote NUMERIC NOT NULL,
FOREIGN KEY (event_id) REFERENCES consensus_2pc_event(id) ON DELETE CASCADE
);
Views
Scabbard store has 3 views that join various 2 phase commit consensus tables
consensus_2pc_actions_all
consensus_2pc_events_all
consensus_2pc_actions_and_events_all
Listing all actions
SELECT * FROM consensus_2pc_actions_all;
Listing all actions for a given epoch
SELECT consensus_2pc_actions_all.*
FROM consensus_2pc_actions_all, consensus_2pc_event
WHERE consensus_2pc_actions_all.event_id = consensus_2pc_event.id
AND consensus_2pc_event.executed_epoch = <desired-epoch>;
Listing all events
SELECT * FROM consensus_2pc_events_all;
List all events for a given epoch
SELECT *
FROM consensus_2pc_events_all
WHERE executed_epoch = <desired-epoch>;
Listing all events and actions in the order they were executed
SELECT * FROM consensus_2pc_actions_and_events_all;
Listing all events and actions for a given epoch
SELECT consensus_2pc_actions_and_events_all.*
FROM consensus_2pc_actions_and_events_all
INNER JOIN consensus_2pc_event
ON (consensus_2pc_actions_and_events_all.a_event_id = consensus_2pc_event.id)
OR (consensus_2pc_actions_and_events_all.e_id = consensus_2pc_event.id)
WHERE consensus_2pc_event.executed_epoch = <desired-epoch>
ORDER BY consensus_2pc_actions_and_events_all.executed_at;
Listing all events and the context used to run the event
SELECT * FROM consensus_2pc_events_and_contexts_all;
Listing all events and the context used to run the event for a given epoch
SELECT *
FROM consensus_2pc_events_and_contexts_all
WHERE e_executed_epoch = <desired-epoch>;
Scabbard v3: Supervisor
erDiagram
scabbard_services {
}
supervisor_notification {
BigInt id PK
Text service_id FK
Text circuit_id FK
BigInt action_id FK
Text notification_type
Binary request_for_vote_value
Timestamp created_at
Timestamp executed_at
}
scabbard_services ||--o{ supervisor_notification: contains
consensus_2pc_action {
BitInt id PK
Text circuit_id FK
Text service_id FK
Text action_type
Timestamp created_at
Timestamp executed_at
}
consensus_2pc_action ||--o| supervisor_notification: contains
consensus_2pc_action }o--|| scabbard_services: contains
consensus_2pc_notification_action {
Int8 action_id PK
Text notification_type
Text dropped_message
Binary request_for_vote_value
}
consensus_2pc_action ||--o| consensus_2pc_notification_action: is
supervisor_notfication
Diesel
table! {
supervisor_notification (id) {
id -> Int8,
circuit_id -> Text,
service_id -> Text,
action_id -> Int8,
notification_type -> Text,
request_for_vote_value -> Nullable<Binary>,
created_at -> Timestamp,
executed_at -> Nullable<Timestamp>,
}
}
PostgreSQL
Table "public.supervisor_notification"
Column | Type | Collation | Nullable | Default
------------------------+------------------------------+-----------+----------+-----------------------------------------------------
id | bigint | | not null | nextval('supervisor_notification_id_seq'::regclass)
circuit_id | text | | not null |
service_id | text | | not null |
action_id | bigint | | not null |
notification_type | supervisgor_notification_type| | not null |
request_for_vote_value | bytea | | |
created_at | timestamp without time zone | | not null | CURRENT_TIMESTAMP
executed_at | timestamp without time zone | | |
Indexes:
"supervisor_notification_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"supervisor_notification_action_id_fkey" FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
"supervisor_notification_circuit_id_service_id_fkey" FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id) ON DELETE CASCADE
SQLite
CREATE TABLE IF NOT EXISTS supervisor_notification (
id INTEGER PRIMARY KEY AUTOINCREMENT,
circuit_id TEXT NOT NULL,
service_id TEXT NOT NULL,
action_id INTEGER NOT NULL,
notification_type TEXT NOT NULL
CHECK ( notification_type IN (
'ABORT',
'COMMIT',
'REQUEST_FOR_START',
'COORDINATOR_REQUEST_FOR_VOTE',
'PARTICIPANT_REQUEST_FOR_VOTE'
)
),
request_for_vote_value BINARY,
created_at TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f','now')) NOT NULL,
executed_at TEXT,
FOREIGN KEY (circuit_id, service_id) REFERENCES scabbard_service(circuit_id, service_id) ON DELETE CASCADE,
FOREIGN KEY (action_id) REFERENCES consensus_2pc_action(id) ON DELETE CASCADE
);