Skip to content

Commit 5e38e89

Browse files
authored
Merge branch 'master' into Jiajie/de-register-proposer
2 parents e1b3276 + 43371b2 commit 5e38e89

10 files changed

Lines changed: 214 additions & 173 deletions

File tree

.github/workflows/on-pull-request.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
5555
rollup-prover:
5656
name: Rollup prover integration Test
57-
timeout-minutes: 420
57+
timeout-minutes: 480
5858
needs: [build, forge, resync] # This test is long so start it after we're sure the others have passed
5959
runs-on: self-hosted
6060
env:

doc/nf_4.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,3 +682,14 @@ Withdraws the stake of a de-registered proposer, actually, the amount withdrawn
682682
## Production deployment
683683
684684
TBD once environment is confirmed
685+
686+
## Appendix
687+
688+
### Note on `VerifierKey.sol`
689+
690+
There is a VerificationKey.sol contract in blockchain_assets/contracts i.e. the normal place for a Solidity contract. This contract's job is to put the verification key into memory, which it does via assembly code, directly placing the values into memory locations. This is to support the RollupVerifier contract, which also uses assembly code that expects to find a key in particular locations. VerificationKey.sol is only relevant for the full Rollup prover. Neither the Mock prover nor the unit tests reference it.
691+
VerificationKey.sol is never actually used directly. When the Deployer runs, it overwrites the contract file with a new one, which is similar in format, but contains the Rollup verification keys that have been computed during key generation. Note that this overwriting only happens when we are using a full rollup prover. This explains why VerificationKey.sol is not updated in Git, even though the keys change: the updated file is never seen by Git because we never push from a machine that is running a full rollup prover.
692+
The overwriting is an unusual approach. Normally one would have a static VerificationKey.sol which contains a function that lets us update the key on deployment. However, the current approach is taken because we want to control exactly how the key data is stored in memory so that we can benefit from the speed increase we get from assembly. Achieving this is much easier if all the key data is hard-coded. We therefore generate the code in Rust so that we can have hard-coded keys (in Solidity) that can be still changed (in Rust) at deployment if they need to be updated.
693+
The unit tests compute their own keys and use a test contract (test_contracts/TestVerifier.sol) which is kept separate from the 'production' contract. This seems sensible because we don't want the unit test to change the main contract as it's more a test of the key generation.
694+
Is there a better way? Probably not. It's the use of Assembly, which creates the requirement to store a large amount of key data in specific locations, that makes this a sensible approach in this case.
695+
We don't actually need VerificationKey.sol so it could be removed from the repository, in principle. However RollupVerifier.sol expects it to be there. Having a work around for that seems more trouble than keeping a 'placeholder' VerificationKey.sol.

docker-compose.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ services:
367367
build:
368368
dockerfile: nightfall_deployer/Dockerfile
369369
context: .
370+
ulimits:
371+
nofile:
372+
soft: 65536
373+
hard: 65536
370374
platform: linux/amd64 # Required for building on M1 Macs
371375
# command: ["tail", "-f","/dev/null"] # For debugging if required
372376
networks:

nightfall_client/src/driven/db/mongo.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ impl From<DBMembershipProof> for MembershipProof<Fr254> {
164164
pub struct CommitmentEntry {
165165
pub preimage: Preimage,
166166
pub status: CommitmentStatus,
167-
#[serde(serialize_with = "ark_se_hex", deserialize_with = "ark_de_hex")]
167+
168+
#[serde(rename = "_id",serialize_with = "ark_se_hex", deserialize_with = "ark_de_hex")]
168169
pub key: Fr254,
169170
#[serde(
170171
serialize_with = "ark_se_hex",
@@ -203,7 +204,8 @@ impl Commitment for CommitmentEntry {
203204
}
204205
}
205206
impl CommitmentEntryDB for CommitmentEntry {
206-
fn new(preimage: Preimage, key: Fr254, nullifier: Fr254, status: CommitmentStatus) -> Self {
207+
fn new(preimage: Preimage, nullifier: Fr254, status: CommitmentStatus) -> Self {
208+
let key = preimage.hash().expect("failed to hash preimage");
207209
Self {
208210
preimage,
209211
status,
@@ -328,7 +330,7 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
328330
}
329331

330332
async fn get_commitment(&self, k: &Fr254) -> Option<CommitmentEntry> {
331-
let filter = doc! { "key": hex::encode(k.into_bigint().to_bytes_le()) };
333+
let filter = doc! { "_id": hex::encode(k.into_bigint().to_bytes_le()) };
332334
self.database(DB)
333335
.collection::<CommitmentEntry>("commitments")
334336
.find_one(filter)
@@ -365,7 +367,7 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
365367
.into_iter()
366368
.map(|c| hex::encode(c.into_bigint().to_bytes_le()))
367369
.collect::<Vec<_>>();
368-
let filter = doc! { "key": { "$in": commitment_str }};
370+
let filter = doc! { "_id": { "$in": commitment_str }};
369371
let update = doc! {"$set": { "status": "PendingSpend" }};
370372
self.database(DB)
371373
.collection::<CommitmentEntry>("commitments")
@@ -380,7 +382,7 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
380382
.into_iter()
381383
.map(|c| hex::encode(c.into_bigint().to_bytes_le()))
382384
.collect::<Vec<_>>();
383-
let filter = doc! { "key": { "$in": commitment_str }};
385+
let filter = doc! { "_id": { "$in": commitment_str }};
384386
let update = doc! {"$set": { "status": "PendingCreation" }};
385387
self.database(DB)
386388
.collection::<CommitmentEntry>("commitments")
@@ -419,7 +421,7 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
419421
.collect::<Vec<_>>();
420422
let l1_hash = l1_hash.map(|h| h.encode_hex());
421423
let l2_blocknumber = l2_blocknumber.map(|b| b.encode_hex());
422-
let filter = doc! { "key": { "$in": commitment_str }};
424+
let filter = doc! { "_id": { "$in": commitment_str }};
423425
let update = doc! {"$set": { "status": "Unspent", "layer_1_transaction_hash": l1_hash, "layer_2_block_number": l2_blocknumber }};
424426
self.database(DB)
425427
.collection::<CommitmentEntry>("commitments")
@@ -431,7 +433,7 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
431433

432434
// we compute a nullifier for each spend commitment that we process.
433435
async fn add_nullifier(&self, key: &Fr254, nullifier: Fr254) -> Option<()> {
434-
let filter = doc! { "key": hex::encode(key.into_bigint().to_bytes_le())};
436+
let filter = doc! { "_id": hex::encode(key.into_bigint().to_bytes_le())};
435437
let update =
436438
doc! {"$set": { "nullifier": hex::encode(nullifier.into_bigint().to_bytes_le()) }};
437439

@@ -443,7 +445,10 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
443445
Some(())
444446
}
445447

446-
async fn store_commitment(&self, commitment: CommitmentEntry) -> Option<()> {
448+
async fn store_commitment(
449+
&self,
450+
commitment: CommitmentEntry
451+
) -> Option<()> {
447452
let result = self
448453
.database(DB)
449454
.collection::<CommitmentEntry>("commitments")
@@ -464,7 +469,7 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
464469
}
465470
}
466471

467-
/// function to store multiple commitments in the database, optionally ignoring duplicate key errors
472+
/// function to store multiple commitments in the database, optionally ignoring duplicate _id errors
468473
async fn store_commitments(
469474
&self,
470475
commitments: &[CommitmentEntry],
@@ -480,13 +485,13 @@ impl CommitmentDB<Fr254, CommitmentEntry> for Client {
480485
.await;
481486
match res {
482487
Ok(_) => Some(()),
483-
// unpack the Mongo error and check if it's a duplicate key error. If so, behave according to dup_key_check
488+
// unpack the Mongo error and check if it's a duplicate _id error. If so, behave according to dup_key_check
484489
Err(e) => {
485490
match e.kind.as_ref() {
486491
ErrorKind::Write(WriteError(write_error)) => {
487492
if write_error.code == 11000 && !dup_key_check {
488-
println!("Duplicate key error: {:?}", write_error);
489-
// duplicate key error but we don't care
493+
println!("Duplicate _id error: {:?}", write_error);
494+
// duplicate _id error but we don't care
490495
Some(())
491496
} else {
492497
None

nightfall_client/src/driven/event_handlers/nightfall_event.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -323,20 +323,12 @@ async fn process_propose_block_event<N: NightfallContract>(
323323
debug!("Commitment {} is not owned by us", commitment_hash);
324324
} else {
325325
info!("Received commitment owned by us, with hash {}", test_hash);
326-
// We can transfer to ourselves, so we need to check if we already have the commitment in our database
327-
let found_commitment = db.get_commitment(&commitment_hash).await;
328-
if found_commitment.is_some() {
329-
debug!("Commitment {} already in database", commitment_hash);
330-
// If we already have the commitment, we don't need to do anything
331-
continue;
332-
}
333326
// store our newly received commitment in our commitment db
334327
let nullifier = test_preimage
335328
.nullifier_hash(&nullifier_key)
336329
.map_err(|_| EventHandlerError::HashError)?;
337330
let commitment_entry = CommitmentEntry::new(
338331
test_preimage,
339-
commitment_hash,
340332
nullifier,
341333
CommitmentStatus::Unspent,
342334
);

nightfall_client/src/drivers/rest/client_nf_3.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@ pub async fn handle_deposit<N: NightfallContract>(
398398
let commitment_hash = preimage_value.hash().expect("Could not hash commitment");
399399
let commitment_entry = CommitmentEntry::new(
400400
preimage_value,
401-
commitment_hash,
402401
nullifier,
403402
CommitmentStatus::PendingCreation,
404403
);
@@ -432,7 +431,6 @@ pub async fn handle_deposit<N: NightfallContract>(
432431

433432
let commitment_entry = CommitmentEntry::new(
434433
preimage_fee,
435-
commitment_hash,
436434
nullifier,
437435
CommitmentStatus::PendingCreation,
438436
);

nightfall_client/src/drivers/rest/client_operation.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ where
8484
.expect("Nullifiers must be hashable");
8585
let commitment_entry = CommitmentEntry::new(
8686
commitment.get_preimage(),
87-
commitment_hash,
8887
nullifier,
8988
CommitmentStatus::PendingCreation,
9089
);

nightfall_client/src/ports/db.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ where
4141
}
4242

4343
pub trait CommitmentEntryDB: Commitment {
44-
fn new(preimage: Preimage, key: Fr254, nullifier: Fr254, status: CommitmentStatus) -> Self;
44+
fn new(preimage: Preimage, nullifier: Fr254, status: CommitmentStatus) -> Self;
4545
fn get_status(&self) -> CommitmentStatus;
4646
}
4747

0 commit comments

Comments
 (0)