-
Notifications
You must be signed in to change notification settings - Fork 24
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
feat: commit transaction data to L1 #85
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work! Thanks for the hard work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work so far! I'm still going through the whole PR (it's a beefy one), but I thought I'd leave some comments before I finish it all, mostly around some maintainability improvements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! Must have been soul deadening to get the blob txs to work with ethers.
I have a suggestion for the schema:
I feel we might be denormalizing the schema a bit too early. Wdyt about replacing all the completed
fields with queries:
Say we have 3 entities:
submissions
fragments
transactions
We retain the current relationship that a submission can have many fragments, while one fragment only belongs to one submission.
A fragment can appear in many l1 transactions (*), and one L1 transaction can have many fragments.
(*) because we plan on supporting retries, a fragment might be in one tx that failed and in another that succeeded, or in two that both succeeded (if we screw up and send two due to edge cases, we only care that one succeeds).
So the question:
Give me all successfully finished submissions would turn into:
Give me all submissions, whose fragments appear in at least one successful L1 transaction.
POC:
-- Create the tables
CREATE TABLE submissions (
id SERIAL PRIMARY KEY
);
CREATE TABLE fragments (
id SERIAL PRIMARY KEY,
position BIGINT NOT NULL CHECK (position >= 0),
submission_id INTEGER NOT NULL REFERENCES submissions(id),
data BYTEA NOT NULL
);
CREATE TABLE transactions (
id SERIAL PRIMARY KEY,
hash BYTEA NOT NULL UNIQUE,
status TEXT NOT NULL CHECK (status IN ('succeeded', 'pending', 'failed'))
);
CREATE TABLE transaction_fragments (
transaction_id INTEGER NOT NULL REFERENCES transactions(id),
fragment_id INTEGER NOT NULL REFERENCES fragments(id),
PRIMARY KEY (transaction_id, fragment_id)
);
-- Create the additional index
CREATE INDEX idx_transactions_status ON transactions(status);
-- Insert values into submissions
INSERT INTO submissions (id) VALUES (DEFAULT), (DEFAULT);
-- Insert values into fragments
-- For completed submission (submission_id = 1)
INSERT INTO fragments (position, submission_id, data) VALUES
(0, 1, '\x010203'),
(1, 1, '\x040506'),
(2, 1, '\x070809');
-- For incomplete submission (submission_id = 2)
INSERT INTO fragments (position, submission_id, data) VALUES
(0, 2, '\x0a0b0c'),
(1, 2, '\x0d0e0f'),
(2, 2, '\x101112');
-- Insert values into transactions
INSERT INTO transactions (hash, status) VALUES
('\xa1b2c3d4', 'succeeded'),
('\xb2c3d4e5', 'succeeded'),
('\xc3d4e5f6', 'pending');
-- Insert values into transaction_fragments
-- For completed submission (submission_id = 1)
INSERT INTO transaction_fragments (transaction_id, fragment_id) VALUES
(1, 1), -- fragment_id 1 belongs to succeeded transaction
(1, 2), -- fragment_id 2 belongs to succeeded transaction
(1, 3); -- fragment_id 3 belongs to succeeded transaction
-- For incomplete submission (submission_id = 2)
INSERT INTO transaction_fragments (transaction_id, fragment_id) VALUES
(3, 4), -- fragment_id 4 belongs to pending transaction
(3, 5); -- fragment_id 5 belongs to pending transaction
-- fragment_id 6 is not in a succeeded transaction
SELECT
s.id AS submission_id,
(
SELECT COUNT(*)
FROM fragments f
WHERE f.submission_id = s.id
) = (
SELECT COUNT(DISTINCT f.id)
FROM fragments f
JOIN transaction_fragments tf ON tf.fragment_id = f.id
JOIN transactions t ON t.id = tf.transaction_id
WHERE f.submission_id = s.id
AND t.status = 'succeeded'
) AS is_completed
FROM
submissions s;
Would result in:
submission_id | is_completed
---------------+--------------
1 | t
2 | f
(2 rows)
So a single write to inform the db of a successful l1 transaction will be all that it takes to mark a submission as completed.
The query should be optimal as is, eventually an index on the tx status. But I think that our expected load plus the cleaning we'll be doing periodically is enough to keep the performance of this query optimal.
Co-authored-by: Rodrigo Araújo <[email protected]>
…uel-block-committer into feature/transaction-committer
This comment was marked as off-topic.
This comment was marked as off-topic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huge PR, but I think with the previous review comments it's as good as it can be. Legend 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-- incredible work!
Initial setup for committing transaction data to L1.
Changes:
New runnable tasks:
a
StateSubmission
and the correspondingStateFragment
to the dbDatabase:
Changes to config: