Skip to content

Commit

Permalink
Merge branch 'main' into remove_wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
dirvine authored Dec 31, 2024
2 parents 6f78922 + cc90c70 commit 3f96717
Show file tree
Hide file tree
Showing 44 changed files with 9,101 additions and 78 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Deploy Documentation
on:
push:
branches:
- main
- data_further_refactor
pull_request:
branches:
- main

permissions:
contents: write

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mkdocs-material mkdocstrings mkdocstrings-python mkdocs-git-revision-date-localized-plugin
- name: Deploy Documentation
run: |
git config --global user.name "github-actions"
git config --global user.email "[email protected]"
mkdocs gh-deploy --force
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ uv.lock
*.swp

/vendor/


# Node.js
node_modules/

# MkDocs
site/
63 changes: 40 additions & 23 deletions ant-evm/src/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ impl FromStr for AttoTokens {
EvmError::FailedToParseAttoToken("Can't parse token units".to_string())
})?;

// Check if the units part is too large before multiplication
if units > Amount::from(u64::MAX) {
return Err(EvmError::ExcessiveValue);
}

units
.checked_mul(Amount::from(TOKEN_TO_RAW_CONVERSION))
.ok_or(EvmError::ExcessiveValue)?
Expand All @@ -114,6 +119,9 @@ impl FromStr for AttoTokens {
let remainder_conversion = TOKEN_TO_RAW_POWER_OF_10_CONVERSION
.checked_sub(remainder_str.len() as u64)
.ok_or(EvmError::LossOfPrecision)?;
if remainder_conversion > 32 {
return Err(EvmError::LossOfPrecision);
}
parsed_remainder * Amount::from(10).pow(Amount::from(remainder_conversion))
}
};
Expand All @@ -126,7 +134,7 @@ impl Display for AttoTokens {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
let unit = self.0 / Amount::from(TOKEN_TO_RAW_CONVERSION);
let remainder = self.0 % Amount::from(TOKEN_TO_RAW_CONVERSION);
write!(formatter, "{unit}.{remainder:09}")
write!(formatter, "{unit}.{remainder:032}")
}
}

Expand Down Expand Up @@ -160,24 +168,28 @@ mod tests {
AttoTokens::from_str("1.000000000000000001")?
);
assert_eq!(
AttoTokens::from_u64(1_100_000_000),
AttoTokens::from_u64(1_100_000_000_000_000_000),
AttoTokens::from_str("1.1")?
);
assert_eq!(
AttoTokens::from_u64(1_100_000_000_000_000_001),
AttoTokens::from_str("1.100000000000000001")?
);
assert_eq!(
AttoTokens::from_u128(4_294_967_295_000_000_000_000_000_000u128),
AttoTokens::from_str("4294967295")?
AttoTokens::from_u128(4_294_967_295_000_000_000_000_000u128),
AttoTokens::from_str("4294967.295")?
);
assert_eq!(
AttoTokens::from_u128(4_294_967_295_999_999_999_000_000u128),
AttoTokens::from_str("4294967.295999999999")?,
);
assert_eq!(
AttoTokens::from_u128(4_294_967_295_999_999_999_000_000_000_000_000u128),
AttoTokens::from_str("4294967295.999999999")?,
AttoTokens::from_u128(4_294_967_295_999_999_999_000_000u128),
AttoTokens::from_str("4294967.2959999999990000")?,
);
assert_eq!(
AttoTokens::from_u128(4_294_967_295_999_999_999_000_000_000_000_000u128),
AttoTokens::from_str("4294967295.9999999990000")?,
AttoTokens::from_u128(18_446_744_074_000_000_000_000_000_000u128),
AttoTokens::from_str("18446744074")?
);

assert_eq!(
Expand All @@ -200,30 +212,39 @@ mod tests {
);
assert_eq!(
Err(EvmError::LossOfPrecision),
AttoTokens::from_str("0.0000000009")
AttoTokens::from_str("0.0000000000000000001")
);
assert_eq!(
Err(EvmError::ExcessiveValue),
AttoTokens::from_str("18446744074")
AttoTokens::from_str("340282366920938463463374607431768211455")
);
Ok(())
}

#[test]
fn display() {
assert_eq!("0.000000000", format!("{}", AttoTokens::from_u64(0)));
assert_eq!("0.000000001", format!("{}", AttoTokens::from_u64(1)));
assert_eq!("0.000000010", format!("{}", AttoTokens::from_u64(10)));
assert_eq!(
"1.000000000",
"0.00000000000000000000000000000000",
format!("{}", AttoTokens::from_u64(0))
);
assert_eq!(
"0.00000000000000000000000000000001",
format!("{}", AttoTokens::from_u64(1))
);
assert_eq!(
"0.00000000000000000000000000000010",
format!("{}", AttoTokens::from_u64(10))
);
assert_eq!(
"1.00000000000000000000000000000000",
format!("{}", AttoTokens::from_u64(1_000_000_000_000_000_000))
);
assert_eq!(
"1.000000001",
"1.00000000000000000000000000000001",
format!("{}", AttoTokens::from_u64(1_000_000_000_000_000_001))
);
assert_eq!(
"4294967295.000000000",
"4.00000000000000294967295000000000",
format!("{}", AttoTokens::from_u64(4_294_967_295_000_000_000))
);
}
Expand All @@ -235,11 +256,11 @@ mod tests {
AttoTokens::from_u64(1).checked_add(AttoTokens::from_u64(2))
);
assert_eq!(
None,
Some(AttoTokens::from_u128(u64::MAX as u128 + 1)),
AttoTokens::from_u64(u64::MAX).checked_add(AttoTokens::from_u64(1))
);
assert_eq!(
None,
Some(AttoTokens::from_u128(u64::MAX as u128 * 2)),
AttoTokens::from_u64(u64::MAX).checked_add(AttoTokens::from_u64(u64::MAX))
);

Expand All @@ -249,11 +270,7 @@ mod tests {
);
assert_eq!(
None,
AttoTokens::from_u64(0).checked_sub(AttoTokens::from_u64(u64::MAX))
);
assert_eq!(
None,
AttoTokens::from_u64(10).checked_sub(AttoTokens::from_u64(11))
AttoTokens::from_u64(0).checked_sub(AttoTokens::from_u64(1))
);
}
}
1 change: 0 additions & 1 deletion ant-networking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ version = "0.3.1"

[features]
default = []
encrypt-records = []
local = ["libp2p/mdns"]
loud = []
open-metrics = ["libp2p/metrics", "prometheus-client", "hyper", "sysinfo"]
Expand Down
97 changes: 47 additions & 50 deletions ant-networking/src/record_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,24 +434,17 @@ impl NodeRecordStore {
key: &Key,
encryption_details: &(Aes256GcmSiv, [u8; 4]),
) -> Option<Cow<'a, Record>> {
let mut record = Record {
key: key.clone(),
value: bytes,
publisher: None,
expires: None,
};

// if we're not encrypting, lets just return the record
if !cfg!(feature = "encrypt-records") {
return Some(Cow::Owned(record));
}

let (cipher, nonce_starter) = encryption_details;
let nonce = generate_nonce_for_record(nonce_starter, key);

match cipher.decrypt(&nonce, record.value.as_ref()) {
match cipher.decrypt(&nonce, bytes.as_slice()) {
Ok(value) => {
record.value = value;
let record = Record {
key: key.clone(),
value,
publisher: None,
expires: None,
};
Some(Cow::Owned(record))
}
Err(error) => {
Expand Down Expand Up @@ -630,15 +623,11 @@ impl NodeRecordStore {
}

/// Prepare record bytes for storage
/// If feats are enabled, this will eg, encrypt the record for storage
/// This will encrypt the record for storage
fn prepare_record_bytes(
record: Record,
encryption_details: (Aes256GcmSiv, [u8; 4]),
) -> Option<Vec<u8>> {
if !cfg!(feature = "encrypt-records") {
return Some(record.value);
}

let (cipher, nonce_starter) = encryption_details;
let nonce = generate_nonce_for_record(&nonce_starter, &record.key);

Expand Down Expand Up @@ -1144,8 +1133,10 @@ mod tests {
..Default::default()
};
let self_id = PeerId::random();
let (network_event_sender, _) = mpsc::channel(1);
let (swarm_cmd_sender, _) = mpsc::channel(1);

// Create channels with proper receivers
let (network_event_sender, _network_event_receiver) = mpsc::channel(1);
let (swarm_cmd_sender, mut swarm_cmd_receiver) = mpsc::channel(1);

let mut store = NodeRecordStore::with_config(
self_id,
Expand All @@ -1172,31 +1163,46 @@ mod tests {
.put_verified(record.clone(), RecordType::Chunk)
.is_ok());

// Mark as stored (simulating the CompletedWrite event)
store.mark_as_stored(record.key.clone(), RecordType::Chunk);
// Wait for the async write operation to complete
if let Some(cmd) = swarm_cmd_receiver.recv().await {
match cmd {
LocalSwarmCmd::AddLocalRecordAsStored { key, record_type } => {
store.mark_as_stored(key, record_type);
}
_ => panic!("Unexpected command received"),
}
}

// Verify the chunk is stored
let stored_record = store.get(&record.key);
assert!(stored_record.is_some(), "Chunk should be stored");
assert!(stored_record.is_some(), "Chunk should be stored initially");

// Sleep a while to let OS completes the flush to disk
sleep(Duration::from_secs(5)).await;
sleep(Duration::from_secs(1)).await;

// Restart the store with same encrypt_seed
// Create new channels for the restarted store
let (new_network_event_sender, _new_network_event_receiver) = mpsc::channel(1);
let (new_swarm_cmd_sender, _new_swarm_cmd_receiver) = mpsc::channel(1);

// Restart the store with same encrypt_seed but new channels
drop(store);
let store = NodeRecordStore::with_config(
self_id,
store_config,
network_event_sender.clone(),
swarm_cmd_sender.clone(),
new_network_event_sender,
new_swarm_cmd_sender,
);

// Sleep a lit bit to let OS completes restoring
sleep(Duration::from_secs(1)).await;

// Verify the record still exists
let stored_record = store.get(&record.key);
assert!(stored_record.is_some(), "Chunk should be stored");
assert!(
stored_record.is_some(),
"Chunk should be stored after restart with same key"
);

// Create new channels for the different seed test
let (diff_network_event_sender, _diff_network_event_receiver) = mpsc::channel(1);
let (diff_swarm_cmd_sender, _diff_swarm_cmd_receiver) = mpsc::channel(1);

// Restart the store with different encrypt_seed
let self_id_diff = PeerId::random();
Expand All @@ -1208,25 +1214,16 @@ mod tests {
let store_diff = NodeRecordStore::with_config(
self_id_diff,
store_config_diff,
network_event_sender,
swarm_cmd_sender,
diff_network_event_sender,
diff_swarm_cmd_sender,
);

// Sleep a lit bit to let OS completes restoring (if has)
sleep(Duration::from_secs(1)).await;

// Verify the record existence, shall get removed when encryption enabled
if cfg!(feature = "encrypt-records") {
assert!(
store_diff.get(&record.key).is_none(),
"Chunk should be gone"
);
} else {
assert!(
store_diff.get(&record.key).is_some(),
"Chunk shall persists without encryption"
);
}
// When encryption is enabled, the record should be gone because it can't be decrypted
// with the different encryption seed
assert!(
store_diff.get(&record.key).is_none(),
"Chunk should be gone with different encryption key"
);

Ok(())
}
Expand Down Expand Up @@ -1557,7 +1554,7 @@ mod tests {
// via NetworkEvent::CompletedWrite)
store.mark_as_stored(record_key.clone(), RecordType::Chunk);

stored_records.push(record_key);
stored_records.push(record_key.clone());
stored_records.sort_by(|a, b| {
let a = NetworkAddress::from_record_key(a);
let b = NetworkAddress::from_record_key(b);
Expand Down
14 changes: 10 additions & 4 deletions ant-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ name = "antnode"
path = "src/bin/antnode/main.rs"

[features]
default = ["metrics", "upnp", "open-metrics", "encrypt-records"]
encrypt-records = ["ant-networking/encrypt-records"]
default = ["metrics", "upnp", "open-metrics"]
extension-module = ["pyo3/extension-module"]
local = ["ant-networking/local", "ant-evm/local", "ant-bootstrap/local", "ant-logging/process-metrics"]
local = [
"ant-networking/local",
"ant-evm/local",
"ant-bootstrap/local",
"ant-logging/process-metrics",
]
loud = ["ant-networking/loud"] # loud mode: print important messages to console
metrics = []
nightly = []
Expand Down Expand Up @@ -83,7 +87,9 @@ walkdir = "~2.5.0"
xor_name = "5.0.0"

[dev-dependencies]
ant-protocol = { path = "../ant-protocol", version = "0.3.1", features = ["rpc"] }
ant-protocol = { path = "../ant-protocol", version = "0.3.1", features = [
"rpc",
] }
assert_fs = "1.0.0"
evmlib = { path = "../evmlib", version = "0.1.6" }
autonomi = { path = "../autonomi", version = "0.3.1", features = ["registers"] }
Expand Down
Loading

0 comments on commit 3f96717

Please sign in to comment.