Skip to content

Commit

Permalink
Fix storing bug
Browse files Browse the repository at this point in the history
This bug would sometimes appear in the revaultd functional tests.
The problem was that we would check if the signature was in the db,
then if it wasn't there, try to insert it. The problem with this is
that between the check and the insertion someone else might have
inserted the signature.
Here we remove the second check altoghether, and recognize if there
were any duplicates from the eventual error at insertion.
  • Loading branch information
danielabrozzoni committed Feb 7, 2022
1 parent c14d400 commit b5d7cb5
Showing 1 changed file with 20 additions and 14 deletions.
34 changes: 20 additions & 14 deletions src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use schema::SCHEMA;

use std::{collections::BTreeMap, fmt};

use tokio_postgres::{types::Type, Client, NoTls};
use tokio_postgres::{error::SqlState, types::Type, Client, NoTls};

pub const DB_VERSION: i32 = 0;

Expand Down Expand Up @@ -90,30 +90,36 @@ pub async fn store_sig(
let client = establish_connection(config).await?;
let sig = signature.serialize_der();

// Make sure it's not here already
let statement = client
.prepare_typed(
"SELECT signature FROM signatures WHERE signature = $1",
&[Type::BYTEA],
)
.await?;
if !client.query(&statement, &[&sig.as_ref()]).await?.is_empty() {
return Err(DbError::Duplicate);
}

let statement = client
.prepare_typed(
"INSERT INTO signatures (txid, pubkey, signature) VALUES ($1, $2, $3) \
ON CONFLICT(txid, pubkey) DO UPDATE SET signature=$3",
&[Type::BYTEA, Type::BYTEA, Type::BYTEA],
)
.await?;
client

if let Err(e) = client
.execute(
&statement,
&[&txid.as_ref(), &pubkey.serialize().as_ref(), &sig.as_ref()],
)
.await?;
.await
{
log::debug!("We have a statement error in store_sig: {:?}", e);
if let Some(e) = e.as_db_error() {
log::debug!(
"We have a db error {:?} with code {:?}",
e.clone(),
e.clone().code()
);
if *e.code() == SqlState::UNIQUE_VIOLATION {
// Ah, it was trying to insert a signature that was there already.
// Alright.
return Err(DbError::Duplicate);
}
}
return Err(e.into());
}

Ok(())
}
Expand Down

0 comments on commit b5d7cb5

Please sign in to comment.