Skip to content

Commit b7946d5

Browse files
committed
additional tests
1 parent 5f62b23 commit b7946d5

1 file changed

Lines changed: 179 additions & 20 deletions

File tree

crates/core/src/dutydb/memory.rs

Lines changed: 179 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,26 +1227,6 @@ mod tests {
12271227
);
12281228
}
12291229

1230-
#[tokio::test]
1231-
async fn mem_db_clashing_blocks() {
1232-
const SLOT: u64 = 123;
1233-
let db = make_db();
1234-
let pubkey = random_core_pub_key();
1235-
let duty = Duty::new(SlotNumber::new(SLOT), DutyType::Proposer);
1236-
1237-
let block1 = phase0_proposal(SLOT, 1);
1238-
let block2 = phase0_proposal(SLOT, 2);
1239-
1240-
let mut set1 = UnsignedDataSet::new();
1241-
set1.insert(pubkey, UnsignedDutyData::Proposal(Box::new(block1)));
1242-
db.store(duty.clone(), set1).await.unwrap();
1243-
1244-
let mut set2 = UnsignedDataSet::new();
1245-
set2.insert(pubkey, UnsignedDutyData::Proposal(Box::new(block2)));
1246-
let err = db.store(duty, set2).await.unwrap_err();
1247-
assert!(err.to_string().contains("clashing blocks"), "got: {err}");
1248-
}
1249-
12501230
#[tokio::test]
12511231
async fn mem_db_clash_proposer() {
12521232
const SLOT: u64 = 123;
@@ -1311,4 +1291,183 @@ mod tests {
13111291
// Should no longer be findable.
13121292
assert!(db.pub_key_by_attestation(SLOT, 0, 0).await.is_err());
13131293
}
1294+
1295+
#[tokio::test]
1296+
async fn agg_attestation_two_roots_same_slot() {
1297+
const SLOT: u64 = 300;
1298+
let db = make_db();
1299+
1300+
// Two aggregations at the same slot but different committee indices
1301+
// produce different tree-hash roots and must coexist.
1302+
let agg_a = agg_attestation_fixture(SLOT, 1, 0);
1303+
let agg_b = agg_attestation_fixture(SLOT, 2, 0);
1304+
let root_a = agg_a.data().unwrap().tree_hash_root().0;
1305+
let root_b = agg_b.data().unwrap().tree_hash_root().0;
1306+
assert_ne!(root_a, root_b);
1307+
1308+
let duty = Duty::new(SlotNumber::new(SLOT), DutyType::Aggregator);
1309+
let mut set = UnsignedDataSet::new();
1310+
set.insert(
1311+
random_core_pub_key(),
1312+
UnsignedDutyData::AggAttestation(agg_a),
1313+
);
1314+
set.insert(
1315+
random_core_pub_key(),
1316+
UnsignedDutyData::AggAttestation(agg_b),
1317+
);
1318+
db.store(duty, set).await.unwrap();
1319+
1320+
let att_a = db.await_agg_attestation(root_a).await.unwrap();
1321+
assert_eq!(att_a.attestation.unwrap().data().slot, SLOT);
1322+
1323+
let att_b = db.await_agg_attestation(root_b).await.unwrap();
1324+
assert_eq!(att_b.attestation.unwrap().data().slot, SLOT);
1325+
}
1326+
1327+
#[tokio::test]
1328+
async fn concurrent_attestation_waiters() {
1329+
const SLOT: u64 = 400;
1330+
const COMM_IDX: u64 = 5;
1331+
const N: usize = 100;
1332+
1333+
let db = Arc::new(make_db());
1334+
let handles: Vec<_> = (0..N)
1335+
.map(|_| {
1336+
let db = Arc::clone(&db);
1337+
tokio::spawn(async move { db.await_attestation(SLOT, COMM_IDX).await })
1338+
})
1339+
.collect();
1340+
1341+
tokio::task::yield_now().await;
1342+
1343+
let att = att_data(SLOT, COMM_IDX, 0);
1344+
let mut set = UnsignedDataSet::new();
1345+
set.insert(random_core_pub_key(), UnsignedDutyData::Attestation(att));
1346+
db.store(Duty::new(SlotNumber::new(SLOT), DutyType::Attester), set)
1347+
.await
1348+
.unwrap();
1349+
1350+
for handle in handles {
1351+
let data = handle.await.unwrap().unwrap();
1352+
assert_eq!(data.slot, SLOT);
1353+
assert_eq!(data.index, COMM_IDX);
1354+
}
1355+
}
1356+
1357+
#[tokio::test]
1358+
async fn await_attestation_before_store() {
1359+
const SLOT: u64 = 500;
1360+
const COMM_IDX: u64 = 2;
1361+
1362+
let db = Arc::new(make_db());
1363+
let handles: Vec<_> = (0..3)
1364+
.map(|_| {
1365+
let db = Arc::clone(&db);
1366+
tokio::spawn(async move { db.await_attestation(SLOT, COMM_IDX).await })
1367+
})
1368+
.collect();
1369+
1370+
tokio::task::yield_now().await;
1371+
1372+
let att = att_data(SLOT, COMM_IDX, 0);
1373+
let mut set = UnsignedDataSet::new();
1374+
set.insert(random_core_pub_key(), UnsignedDutyData::Attestation(att));
1375+
db.store(Duty::new(SlotNumber::new(SLOT), DutyType::Attester), set)
1376+
.await
1377+
.unwrap();
1378+
1379+
for handle in handles {
1380+
handle.await.unwrap().unwrap();
1381+
}
1382+
}
1383+
1384+
#[tokio::test]
1385+
async fn await_before_shutdown() {
1386+
let db = Arc::new(make_db());
1387+
1388+
let db_clone = Arc::clone(&db);
1389+
let waiter = tokio::spawn(async move { db_clone.await_attestation(9999, 0).await });
1390+
1391+
tokio::task::yield_now().await;
1392+
db.shutdown();
1393+
1394+
let err = waiter.await.unwrap().unwrap_err();
1395+
assert!(
1396+
err.to_string().contains("shutdown"),
1397+
"expected shutdown error, got: {err}"
1398+
);
1399+
}
1400+
1401+
#[tokio::test]
1402+
async fn shutdown_wakes_await_attestation() {
1403+
let db = make_db();
1404+
db.shutdown();
1405+
1406+
let err = db.await_attestation(0, 0).await.unwrap_err();
1407+
assert!(err.to_string().contains("shutdown"), "got: {err}");
1408+
}
1409+
1410+
#[tokio::test]
1411+
async fn shutdown_wakes_await_agg_attestation() {
1412+
let db = make_db();
1413+
db.shutdown();
1414+
1415+
let err = db.await_agg_attestation([0u8; 32]).await.unwrap_err();
1416+
assert!(err.to_string().contains("shutdown"), "got: {err}");
1417+
}
1418+
1419+
#[tokio::test]
1420+
async fn invalid_unsigned_type_proposer() {
1421+
let db = make_db();
1422+
let duty = Duty::new(SlotNumber::new(1), DutyType::Proposer);
1423+
let mut set = UnsignedDataSet::new();
1424+
set.insert(
1425+
random_core_pub_key(),
1426+
UnsignedDutyData::Attestation(att_data(1, 0, 0)),
1427+
);
1428+
let err = db.store(duty, set).await.unwrap_err();
1429+
assert!(matches!(err, Error::InvalidVersionedProposal), "got: {err}");
1430+
}
1431+
1432+
#[tokio::test]
1433+
async fn invalid_unsigned_type_attester() {
1434+
let db = make_db();
1435+
let duty = Duty::new(SlotNumber::new(1), DutyType::Attester);
1436+
let mut set = UnsignedDataSet::new();
1437+
set.insert(
1438+
random_core_pub_key(),
1439+
UnsignedDutyData::Proposal(Box::new(phase0_proposal(1, 0))),
1440+
);
1441+
let err = db.store(duty, set).await.unwrap_err();
1442+
assert!(matches!(err, Error::InvalidAttestationData), "got: {err}");
1443+
}
1444+
1445+
#[tokio::test]
1446+
async fn invalid_unsigned_type_aggregator() {
1447+
let db = make_db();
1448+
let duty = Duty::new(SlotNumber::new(1), DutyType::Aggregator);
1449+
let mut set = UnsignedDataSet::new();
1450+
set.insert(
1451+
random_core_pub_key(),
1452+
UnsignedDutyData::Attestation(att_data(1, 0, 0)),
1453+
);
1454+
let err = db.store(duty, set).await.unwrap_err();
1455+
assert!(
1456+
matches!(err, Error::InvalidAggregatedAttestation),
1457+
"got: {err}"
1458+
);
1459+
}
1460+
1461+
#[tokio::test]
1462+
async fn invalid_unsigned_type_sync_contribution() {
1463+
let db = make_db();
1464+
let duty = Duty::new(SlotNumber::new(1), DutyType::SyncContribution);
1465+
let mut set = UnsignedDataSet::new();
1466+
set.insert(
1467+
random_core_pub_key(),
1468+
UnsignedDutyData::Attestation(att_data(1, 0, 0)),
1469+
);
1470+
let err = db.store(duty, set).await.unwrap_err();
1471+
assert!(matches!(err, Error::InvalidSyncContribution), "got: {err}");
1472+
}
13141473
}

0 commit comments

Comments
 (0)