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

Enforce base fee #1390

Merged
merged 12 commits into from
May 15, 2024
Merged

Enforce base fee #1390

merged 12 commits into from
May 15, 2024

Conversation

jbearer
Copy link
Member

@jbearer jbearer commented Apr 26, 2024

  • Add logic in validate_proposal to enforce that the provided fee is at least the base fee
  • Enable base fees in the demo, enforcing in the sequencers and configuring the builder to pay the base fee
  • Deploy bridge contract before starting sequencers, read deposits from here
  • Add a tool to work with the bridge, use this to fund the builder instead of prefunded accounts

The new demo configuration should work on a real network like Sepolia or Ethereum, and demonstrates the startup order/dependencies.

Draft because I think this should go in after the latest builder and HotShot updates, but I don't know how to do those updates.

Testing

A good end-to-end test is to run demo-native, convince yourself that it's working as you normally would (look at block height, submit-transactions logs, etc) and then watch the balance of the builder account and burner account:

  • cargo run --release --all-features --bin bridge -- balance -e http://localhost:44001 -a 0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f
  • cargo run --release --all-features --bin bridge -- balance -e http://localhost:44001 -a 0x0000000000000000000000000000000000000000

The former should be steadily decreasing while the latter is steadily increasing, as the builder pays fees

Copy link
Contributor

@move47 move47 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/builder changes looks good.

@move47
Copy link
Contributor

move47 commented Apr 29, 2024

I think this can go first and later we can update with hotshot 0.5.45(needs to release tag) which will have simplify builder interaction, and update builder along with that.

@jbearer
Copy link
Member Author

jbearer commented Apr 29, 2024

We need to wait until @Ancient123 is ready for the new contracts deployment order

@jbearer jbearer force-pushed the jb/enforce-base-fee branch 6 times, most recently from 9b197de to a82f075 Compare May 7, 2024 19:18
@jbearer jbearer marked this pull request as ready for review May 7, 2024 19:31
@jbearer jbearer force-pushed the jb/enforce-base-fee branch 3 times, most recently from a46cf22 to 21bd047 Compare May 10, 2024 13:30
sequencer/src/bin/bridge.rs Outdated Show resolved Hide resolved
function get_balance() {
(
unset MNEMONIC
cargo run --release --all-features --bin bridge -- balance -e $SEQUENCER_API -a $1 -b $2
Copy link
Collaborator

@sveitser sveitser May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal but I think it's kind of nice that this script is currently portable and doesn't need a rust toolchain. Maybe it would be useful to expose reading the bridge query APIs via the explorer then we could query that instead. If we do add the cargo run here we should probably add rust-cache to the test-demo github action workflow.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean exactly by reading the bridge APIs via the explorer?

Another approach could be to use bridge as an executable for the native demo (since the native demo already relies on cargo targets being added to $PATH) and use the bridge docker for the docker demo, which would also have the nice benefit of testing that the new docker is built correctly. I could add a CLI flag to this script to choose the bridge executable

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean if we had a HTTP API that allowed to query the bridge balances either run by the hotshot node or via the block explorer that would be useful here and I think it would be convenient with anyone interacting with our sequencer too but it's also somewhat out of scope.

We could also call bridge if it's in the PATH and otherwise try the docker container then we don't need a flag.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean if we had a HTTP API that allowed to query the bridge balances either run by the hotshot node or via the block explorer that would be useful here and I think it would be convenient with anyone interacting with our sequencer too but it's also somewhat out of scope.

I agree, but yeah, I think adding this to the block explorer is a lot of work. We do have an HTTP API (that is how the bridge tool gets its information) but it outputs a merkle path and the balance is base64 encoded which makes it a bit annoying to work with, hence the bridge tool.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The collection of fees (or lack thereof) is not completely controlled
by ChainConfig. This makes it possible to launch without fees (even
without a fee contract) and upgrade to enable fees at a later date.
The only code change required to do this upgraded will be the ability
to change the ChainConfig by upgrading. After that, only a configuration
change is need to change the ChainConfig to set the fee contract and
base fee.
This will allow the underlying asset to be conserved, and we can
decide what to do with the burnt fees at a later point.
* Use fee message defined in HotShot trait, rather than constructing
  it ourselves, to avoid accidentally going out of sync with how the
  builder is signing
* Fail signature recovery if the recovered address is wrong, rather
  than proceeding with a random address
Err(err)
} else {
Ok(())
return Err(err);
Copy link
Contributor

@tbro tbro May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really an issue w/ this PR, but I wonder if persistent_update_with should take a closure that returns a Result instead of an Option. I think we could then bubble the error up to the caller instead of mutating err. This code appears to demonstrate that we do need to handle more than just the Some and None cases. I might be confused though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think that would be cleaner. This pattern is basically just implementing that in a messier way. @mrain maybe you can clean this up in jf-merkle-tree whenever you find yourself with some spare time?

let header = parent.get_block_header();

// Validation fails because the genesis fee (0) is too low.
let err = validate_proposal(&state, instance.chain_config, &parent, header, &vid_common)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inspect the error to ensure that it failed because of the base fee being too low?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will do this in the followup #1463

sequencer/src/state.rs Outdated Show resolved Hide resolved
anyhow::ensure!(
(VidSchemeType::get_payload_byte_len(vid_common) as u64)
< expected_chain_config.max_block_size(),
block_size < expected_chain_config.max_block_size,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added some time ago but wouldn't it be more intuitive to make the range inclusive so that a block of max_block_size is still allowed? If yes, let's add an issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -90,6 +94,14 @@ impl ValidatedState {
self.fee_merkle_tree.update(account, amount).unwrap();
}

pub fn balance(&mut self, account: FeeAccount) -> Option<FeeAmount> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is only used in tests (unless my rust-analyzer is tripping). I'm not sure returning None is a good idea for the NotInMemory case, but if we make it test code only then I think it's not a problem.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we don't have a stable public Rust API yet but I feel like a function like this should be part of it. Could easily be useful outside tests for clients and apps built on top of this. What do you think such a public function should do in the NotInMemory case? Should it return Result instead of Option?

Copy link
Collaborator

@sveitser sveitser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The request for change is because I think we should avoid the term "burn" unless we do light things on fire.

The other comments are just suggestions / nitpicky stuff.

Use the bridge executable from the path if it is already built;
otherwise use Docker.
@sveitser sveitser self-requested a review May 15, 2024 14:21
@jbearer jbearer merged commit 97548f0 into main May 15, 2024
15 checks passed
@jbearer jbearer deleted the jb/enforce-base-fee branch May 15, 2024 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants