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

fix: restore fname tests using custom signer #269

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ alloy-provider = "0.8.0"
alloy-rpc-types = "0.8.0"
alloy-primitives = "0.8.14"
alloy-contract = "0.8.0"
alloy-signer = "0.8.0"
alloy-signer-local = "0.8.0"
ed25519-dalek = "2.1.1"
pre-commit = "0.5.2"
rocksdb = {git = "https://github.com/rust-rocksdb/rust-rocksdb.git", rev="1cf906dc4087f06631820f13855e6b27bd21b972", features=["multi-threaded-cf"]}
Expand Down
8 changes: 4 additions & 4 deletions src/core/validations/validations_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ mod tests {
r#type: 1,
})
};
let result = validate_fname_transfer(transfer);
let result = validate_fname_transfer(transfer, None);
assert!(result.is_ok());
}

Expand All @@ -112,7 +112,7 @@ mod tests {
r#type: 1,
})
};
let result = validate_fname_transfer(transfer);
let result = validate_fname_transfer(transfer, None);
assert!(result.is_ok());
}

Expand All @@ -130,7 +130,7 @@ mod tests {
r#type: 1,
})
};
let result = validate_fname_transfer(transfer);
let result = validate_fname_transfer(transfer, None);
assert!(result.is_err());
assert_eq!(result.unwrap_err(), ValidationError::InvalidSignature);
}
Expand All @@ -149,7 +149,7 @@ mod tests {
r#type: 1,
})
};
let result = validate_fname_transfer(transfer);
let result = validate_fname_transfer(transfer, None);
assert!(result.is_err());
assert_eq!(result.unwrap_err(), ValidationError::InvalidSignature);
}
Expand Down
13 changes: 9 additions & 4 deletions src/core/validations/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fn eip_712_farcaster_verification_claim() -> Value {
})
}

fn eip_712_domain() -> Value {
pub fn eip_712_domain() -> Value {
json!({
"EIP712Domain": [
{
Expand Down Expand Up @@ -97,7 +97,7 @@ fn address_verification_domain() -> Value {
})
}

fn name_registry_domain() -> Value {
pub fn name_registry_domain() -> Value {
json!({
"name": "Farcaster name verification",
"version": "1",
Expand All @@ -106,7 +106,10 @@ fn name_registry_domain() -> Value {
})
}

pub fn validate_fname_transfer(transfer: &proto::FnameTransfer) -> Result<(), ValidationError> {
pub fn validate_fname_transfer(
transfer: &proto::FnameTransfer,
signer_address: Option<alloy_primitives::Address>,
) -> Result<(), ValidationError> {
let proof = transfer.proof.as_ref().unwrap();
let username = std::str::from_utf8(&proof.name);
if username.is_err() {
Expand Down Expand Up @@ -140,7 +143,9 @@ pub fn validate_fname_transfer(transfer: &proto::FnameTransfer) -> Result<(), Va
}

let hash = prehash.unwrap();
let fname_signer = alloy_primitives::address!("Bc5274eFc266311015793d89E9B591fa46294741");
let fname_signer = signer_address.unwrap_or(alloy_primitives::address!(
"Bc5274eFc266311015793d89E9B591fa46294741"
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's pull this out as a constant

));
let signature = alloy_primitives::PrimitiveSignature::from_bytes_and_parity(
&proof.signature[0..64],
proof.signature[64] != 0x1b && proof.signature[64] != 0x00,
Expand Down
1 change: 1 addition & 0 deletions src/network/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ impl MyHubService {
self.statsd_client.clone(),
100,
None,
None,
);
let result = readonly_engine.simulate_message(&message);

Expand Down
2 changes: 2 additions & 0 deletions src/network/server_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,13 @@ mod tests {
limits: Some(limits.clone()),
db_name: Some("db1.db".to_string()),
messages_request_tx: None,
fname_signer_address: None,
});
let (engine2, _) = test_helper::new_engine_with_options(test_helper::EngineOptions {
limits: Some(limits.clone()),
db_name: Some("db2.db".to_string()),
messages_request_tx: None,
fname_signer_address: None,
});
let db1 = engine1.db.clone();
let db2 = engine2.db.clone();
Expand Down
1 change: 1 addition & 0 deletions src/node/snapchain_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ impl SnapchainNode {
statsd_client.clone(),
config.max_messages_per_block,
Some(messages_request_tx.clone()),
None,
);

shard_senders.insert(shard_id, engine.get_senders());
Expand Down
1 change: 1 addition & 0 deletions src/perf/engine_only_perftest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub async fn run() -> Result<(), Box<dyn Error>> {
}),
db_name: None,
messages_request_tx: Some(messages_request_tx),
fname_signer_address: None,
});

let statsd_client = StatsdClientWrapper::new(
Expand Down
23 changes: 22 additions & 1 deletion src/storage/store/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ pub struct ShardEngine {
statsd_client: StatsdClientWrapper,
max_messages_per_block: u32,
messages_request_tx: Option<mpsc::Sender<MempoolMessagesRequest>>,
fname_signer_address: Option<alloy_primitives::Address>,
}

impl ShardEngine {
Expand All @@ -167,8 +168,24 @@ impl ShardEngine {
statsd_client: StatsdClientWrapper,
max_messages_per_block: u32,
messages_request_tx: Option<mpsc::Sender<MempoolMessagesRequest>>,
fname_signer_address: Option<String>,
) -> ShardEngine {
// TODO: adding the trie here introduces many calls that want to return errors. Rethink unwrap strategy.
let signer_address = match fname_signer_address {
Some(a) => match hex::decode(a.replace("0x", "")) {
Ok(address_hex) => {
if address_hex.len() == 20 {
Some(alloy_primitives::Address::new(
address_hex.try_into().unwrap(),
))
} else {
None
}
}
Err(_) => None,
},
None => None,
};
ShardEngine {
shard_id,
stores: Stores::new(db.clone(), trie, store_limits),
Expand All @@ -177,6 +194,7 @@ impl ShardEngine {
statsd_client,
max_messages_per_block,
messages_request_tx,
fname_signer_address: signer_address,
}
}

Expand Down Expand Up @@ -545,7 +563,10 @@ impl ShardEngine {
);
}
Some(proof) => {
match verification::validate_fname_transfer(fname_transfer) {
match verification::validate_fname_transfer(
fname_transfer,
self.fname_signer_address,
) {
Ok(_) => {
let event = UserDataStore::merge_username_proof(
&self.stores.user_data_store,
Expand Down
75 changes: 56 additions & 19 deletions src/storage/store/engine_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[cfg(test)]
mod tests {
use crate::core::types::FARCASTER_EPOCH;
use crate::core::util::{calculate_message_hash, from_farcaster_time};
use crate::proto::{self, ReactionType};
use crate::proto::{FnameTransfer, ShardChunk, UserNameProof};
Expand Down Expand Up @@ -1127,31 +1128,29 @@ mod tests {

#[tokio::test]
async fn test_merge_fname() {
let (mut engine, _tmpdir) = test_helper::new_engine();
let signer = alloy_signer_local::PrivateKeySigner::random();
let (mut engine, _tmpdir) =
test_helper::new_engine_with_fname_signer(Some(signer.address().to_string()));

test_helper::register_user(
FID_FOR_TEST,
test_helper::default_signer(),
hex::decode("711aa8ec273dae42e51732fe1be2b15ee53b00a4").unwrap(),
test_helper::default_custody_address(),
&mut engine,
)
.await;

let fname = &"acp".to_string();

let mut event_rx = engine.get_senders().events_tx.subscribe();
let fname_transfer = &FnameTransfer{
id: 1234,
from_fid: 0,
proof: Some(UserNameProof{
timestamp: 1660233642,
name: fname.as_bytes().to_vec(),
owner: hex::decode("711aa8ec273dae42e51732fe1be2b15ee53b00a4").unwrap(),
signature: hex::decode("ebd1b040a4961c5ea751e8ec867d4af6fdbf80ade6775d33dad94ab1c0423dc64a2f684d0e48b89f2958a2385b91743647161ade04e6628a166b5bd1579d86ff1b").unwrap(),
fid: 1234,
r#type: 1,
}),
};
let fname_transfer = username_factory::create_transfer(
FID_FOR_TEST,
fname,
Some(FARCASTER_EPOCH),
None,
Some(test_helper::default_custody_address()),
signer.clone(),
);

let state_change = engine.propose_state_change(
1,
Expand Down Expand Up @@ -1179,7 +1178,35 @@ mod tests {
assert!(proof.is_some());
assert_eq!(proof.unwrap().fid, FID_FOR_TEST);

// todo: alternate signer for fname server testing so we can verify transferring to 0 nukes the fname
let fname_transfer = username_factory::create_transfer(
0,
fname,
Some(FARCASTER_EPOCH + 1),
Some(FID_FOR_TEST),
Some(test_helper::default_custody_address()),
signer,
);

let state_change = engine.propose_state_change(
1,
vec![MempoolMessage::ValidatorMessage(ValidatorMessage {
on_chain_event: None,
fname_transfer: Some(fname_transfer.clone()),
})],
);
test_helper::validate_and_commit_state_change(&mut engine, &state_change);

let transfer_event = &event_rx.try_recv().unwrap();
assert_eq!(
transfer_event.r#type,
proto::HubEventType::MergeUsernameProof as i32
);

// don't insert an fname for fid 0 into the trie
assert!(!test_helper::key_exists_in_trie(
&mut engine,
&TrieKey::for_fname(0, fname)
));
}

#[tokio::test]
Expand Down Expand Up @@ -1219,11 +1246,11 @@ mod tests {
commit_message(&mut engine, &username_add).await;
}

// this test needs to be updated to use an actual transfer event since validation logic checks the fname signer signature
#[ignore]
#[tokio::test]
async fn test_username_revoked_when_proof_transferred() {
let (mut engine, _tmpdir) = test_helper::new_engine();
let signer = alloy_signer_local::PrivateKeySigner::random();
let (mut engine, _tmpdir) =
test_helper::new_engine_with_fname_signer(Some(signer.address().to_string()));

test_helper::register_user(
FID_FOR_TEST,
Expand All @@ -1234,7 +1261,15 @@ mod tests {
.await;

let fname = &"farcaster".to_string();
test_helper::register_fname(FID_FOR_TEST, fname, None, &mut engine).await;
test_helper::register_fname(
FID_FOR_TEST,
fname,
None,
Some(test_helper::default_custody_address()),
&mut engine,
signer.clone(),
)
.await;

let fid_username_msg = messages_factory::user_data::create_user_data_add(
FID_FOR_TEST,
Expand All @@ -1260,6 +1295,8 @@ mod tests {
fname,
Some(time::current_timestamp() as u64 + 10),
Some(FID_FOR_TEST),
Some(test_helper::default_custody_address()),
signer,
);
let state_change = engine.propose_state_change(
1,
Expand Down
23 changes: 22 additions & 1 deletion src/storage/store/test_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub struct EngineOptions {
pub limits: Option<StoreLimits>,
pub db_name: Option<String>,
pub messages_request_tx: Option<mpsc::Sender<MempoolMessagesRequest>>,
pub fname_signer_address: Option<String>,
}

pub fn new_engine_with_options(options: EngineOptions) -> (ShardEngine, tempfile::TempDir) {
Expand Down Expand Up @@ -125,6 +126,7 @@ pub fn new_engine_with_options(options: EngineOptions) -> (ShardEngine, tempfile
statsd_client,
256,
options.messages_request_tx,
options.fname_signer_address,
),
dir,
)
Expand All @@ -136,6 +138,19 @@ pub fn new_engine() -> (ShardEngine, tempfile::TempDir) {
limits: None,
db_name: None,
messages_request_tx: None,
fname_signer_address: None,
})
}

#[cfg(test)]
pub fn new_engine_with_fname_signer(
signer_address: Option<String>,
) -> (ShardEngine, tempfile::TempDir) {
new_engine_with_options(EngineOptions {
limits: None,
db_name: None,
messages_request_tx: None,
fname_signer_address: signer_address,
})
}

Expand Down Expand Up @@ -273,9 +288,15 @@ pub async fn register_fname(
fid: u64,
username: &String,
timestamp: Option<u64>,
owner: Option<Vec<u8>>,
engine: &mut ShardEngine,
signer: alloy_signer_local::PrivateKeySigner,
) {
let fname_transfer = username_factory::create_transfer(fid, username, timestamp, None);
use crate::core::validations::verification;

let fname_transfer =
username_factory::create_transfer(fid, username, timestamp, None, owner, signer.clone());
assert!(verification::validate_fname_transfer(&fname_transfer, Some(signer.address())).is_ok());
let state_change = engine.propose_state_change(
1,
vec![MempoolMessage::ValidatorMessage(proto::ValidatorMessage {
Expand Down
Loading