-
Notifications
You must be signed in to change notification settings - Fork 18
Combine owners and nonce tables #391
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
base: unstable
Are you sure you want to change the base?
Conversation
Thanks for the PR!
Yeah, I also noticed that the tests for the database can not be run on their own due to this. There is some other PR where I add the "sync" feature.
Makes sense. But I think we might need to adjust this:
Option<String> .
I think defaulting the nonce to I will add two test cases to illustrate these issues :) |
I changed the in-memory storage a bit. I changed nonce storage to
Also modified all the related nonce code to use I'm happy changing it either way you see fit. A simpler solution is to leave it like it was, and handle situations with NULL nonces like this: |
INSERT INTO nonce (owner, nonce) VALUES (?1, 0) | ||
ON CONFLICT (owner) DO UPDATE SET nonce = nonce + 1 | ||
INSERT INTO owners (owner, nonce) VALUES (?1, 0) | ||
ON CONFLICT (owner) DO UPDATE SET nonce = COALESCE(nonce, -1) + 1 |
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.
Oooh, good idea, I like it :)
I think COALESCE(nonce + 1, 0)
might be easier to understand and should also work because NULL + 1
computes to NULL
.
Some required checks have failed. Could you please take a look @petarjuki7? 🙏 |
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.
Pull Request Overview
Combines the previous owners
and nonce
tables into a single owners
table, making both fee_recipient
and nonce
nullable and updating all related queries and code paths accordingly.
- Merged schema: replaced separate
owners
andnonce
tables with oneowners
table containing both fields - Refactored SQL operations and Rust code to handle nullable
fee_recipient
andnonce
- Added tests for NULL handling of
fee_recipient
and nonce consistency across operations
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
anchor/database/src/validator_operations.rs | Adapt fee_recipient_for_owner to return Option<Address> |
anchor/database/src/tests/cluster_tests.rs | Add tests for NULL fee_recipient and nonce progression logic |
anchor/database/src/table_schema.sql | Drop old tables and define unified owners schema |
anchor/database/src/state.rs | Filter out rows with NULL nonce when collecting nonces |
anchor/database/src/sql_operations.rs | Update SQL queries for merged owners table |
// Get he nonce from column 1 | ||
let nonce = row.get::<_, u16>(1)?; | ||
// Get the nonce from column 1 | ||
let nonce = row.get(1)?; | ||
Ok((owner, nonce)) | ||
})? |
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.
[nitpick] The filter_map
call silently drops owners with a NULL
nonce. If that’s intended, add a comment clarifying this behavior; otherwise consider handling the None
case explicitly.
})? | |
})? | |
// Owners with a `NULL` nonce are intentionally dropped here. |
Copilot uses AI. Check for mistakes.
Can we say an unused nonce is 0? |
Since nonces in Ethereum start with 0 (the first transactions nonce is 0), then maybe putting it at 0 could read as "already had a first transaction as nonce 0" and not that it hasn't been set yet |
Are you sure? The yellow paper defines nonce as the number of transactions sent from the address. |
It also says "An account is empty when it has no code, zero nonce and zero balance" |
We are not talking about Ethereum nonces here, but nonces as used in the SSV network. In the database, we store the previous, not the next nonce. Therefore there is a difference between 0 (which means the last |
To clear up the confusion why I put " 👍 " to
While we do not work with Ethereum nonces, but with nonces as used in SSV's I will test this change on some nodes to ensure it's working fine, then we can merge this :) Thanks @petarjuki7! |
I found another small issue: we needed to account for the null value when We will merge this soon after deciding what will go into the next version 👍 |
Great, thanks! :) Thought of something else that might be worth changing: anchor/anchor/database/src/cluster_operations.rs Lines 164 to 180 in 94d9d4a
It could be changed to: let mut stmt = tx.prepare_cached(sql_operations::GET_NONCE)?;
let nonce: u16 = stmt.query_row(params![owner.to_string()], |row| row.get(0))?;
// Update in memory with the truth from the database
self.modify_state(|state| {
state.single_state.nonces.insert(*owner, nonce);
});
Ok(nonce) So we are sure it is the same in the database as in memory. This removes any risk of the in-memory logic diverging from the SQL logic. This passes all the tests also, let me know what do you think, I can include it in a commit. |
Issue Addressed
Addresses Issue #385
Proposed Changes
There is now one table
owners
which has both thefee_recipient
andnonce
fields.Additional Info
Removed
NOT NULL
onfee_recipient
, had to do it because on theBUMP_NONCE
command we are only inserting onowner
andnonce
.Tested with
cargo test
in thedatabase
crate and all the tests pass.Side comment:
As far as I can tell
cargo test
doesn't work on thestable
branch, because in the top levelCargo.toml
there is async
feature missing in thetokio
dependency import.