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

Move abi types and implement piece size #283

Merged
merged 4 commits into from
Mar 17, 2020
Merged
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
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ members = [
"vm/runtime",
"vm/state_tree",
"vm/interpreter",
"vm/abi",
"node",
"node/clock",
"crypto",
Expand Down
5 changes: 3 additions & 2 deletions vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ num-bigint = { path = "../math/bigint", package = "forest_bigint" }
address = { package = "forest_address", path = "./address" }
encoding = { package = "forest_encoding", path = "../encoding" }
serde = { version = "1.0", features = ["derive"] }
cid = { package = "forest_cid", path = "../ipld/cid" }

cid = { package = "forest_cid", path = "../ipld/cid", features = ["serde_derive"] }
num-traits = "0.2"
num-derive = "0.2"
10 changes: 0 additions & 10 deletions vm/abi/Cargo.toml

This file was deleted.

8 changes: 0 additions & 8 deletions vm/abi/src/lib.rs

This file was deleted.

15 changes: 0 additions & 15 deletions vm/abi/src/piece.rs

This file was deleted.

1 change: 0 additions & 1 deletion vm/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2018"
vm = { path = "../../vm" }
crypto = { path = "../../crypto" }
address = { package = "forest_address", path = "../address" }
abi = { package = "forest_abi", path = "../abi" }
message = { package = "forest_message", path = "../message" }
cid = { package = "forest_cid", path = "../../ipld/cid" }
ipld_blockstore = { path = "../../ipld/blockstore" }
Expand Down
6 changes: 4 additions & 2 deletions vm/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ mod actor_code;

pub use self::actor_code::*;

use abi::{PieceInfo, PoStVerifyInfo, RegisteredProof, SealVerifyInfo};
use address::Address;
use cid::Cid;
use clock::ChainEpoch;
use crypto::{DomainSeparationTag, Signature};
use forest_encoding::Cbor;
use ipld_blockstore::BlockStore;
use message::UnsignedMessage;
use vm::{ExitCode, MethodNum, Serialized, TokenAmount};
use vm::{
ExitCode, MethodNum, PieceInfo, PoStVerifyInfo, RegisteredProof, SealVerifyInfo, Serialized,
TokenAmount,
};

pub struct Randomness; // TODO

Expand Down
4 changes: 4 additions & 0 deletions vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ mod code;
mod exit_code;
mod invoc;
mod method;
mod piece;
mod sector;
mod state_tree;
mod token;

Expand All @@ -14,5 +16,7 @@ pub use self::code::*;
pub use self::exit_code::*;
pub use self::invoc::*;
pub use self::method::*;
pub use self::piece::*;
pub use self::sector::*;
pub use self::state_tree::StateTree;
pub use self::token::*;
128 changes: 128 additions & 0 deletions vm/src/piece.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use cid::Cid;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// Size of a piece in bytes
#[derive(PartialEq, Debug, Eq, Clone, Copy)]
pub struct UnpaddedPieceSize(pub u64);

impl UnpaddedPieceSize {
/// Converts unpadded piece size into padded piece size
pub fn padded(self) -> PaddedPieceSize {
PaddedPieceSize(self.0 + (self.0 / 127))
}

/// Validates piece size
pub fn validate(self) -> Result<(), &'static str> {
if self.0 < 127 {
return Err("minimum piece size is 127 bytes");
}

// is 127 * 2^n
if self.0 >> self.0.trailing_zeros() != 127 {
return Err("unpadded piece size must be a power of 2 multiple of 127");
}

Ok(())
}
}

/// Size of a piece in bytes with padding
#[derive(PartialEq, Debug, Eq, Clone, Copy)]
pub struct PaddedPieceSize(pub u64);

impl PaddedPieceSize {
/// Converts padded piece size into an unpadded piece size
pub fn unpadded(self) -> UnpaddedPieceSize {
UnpaddedPieceSize(self.0 - (self.0 / 128))
}

/// Validates piece size
pub fn validate(self) -> Result<(), &'static str> {
if self.0 < 128 {
return Err("minimum piece size is 128 bytes");
}

if self.0.count_ones() != 1 {
return Err("padded piece size must be a power of 2");
}

Ok(())
}
}

impl Serialize for PaddedPieceSize {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(s)
}
}

impl<'de> Deserialize<'de> for PaddedPieceSize {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self(Deserialize::deserialize(deserializer)?))
}
}

// Piece information for part or a whole file
pub struct PieceInfo {
/// Size in nodes. For BLS12-381 (capacity 254 bits), must be >= 16. (16 * 8 = 128)
pub size: PaddedPieceSize,
/// Content identifier for piece
pub cid: Cid,
}

impl Serialize for PieceInfo {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
(&self.size, &self.cid).serialize(serializer)
}
}

impl<'de> Deserialize<'de> for PieceInfo {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let (size, cid) = Deserialize::deserialize(deserializer)?;
Ok(Self { size, cid })
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn round_trip_piece_size() {
let p_piece = PaddedPieceSize(0b10000000);
p_piece.validate().unwrap();
let up_piece = p_piece.unpadded();
up_piece.validate().unwrap();
assert_eq!(&up_piece, &UnpaddedPieceSize(127));
assert_eq!(&p_piece, &up_piece.padded());
}
#[test]
fn invalid_piece_checks() {
let p = PaddedPieceSize(127);
assert_eq!(p.validate(), Err("minimum piece size is 128 bytes"));
let p = UnpaddedPieceSize(126);
assert_eq!(p.validate(), Err("minimum piece size is 127 bytes"));
let p = PaddedPieceSize(0b10000001);
assert_eq!(p.validate(), Err("padded piece size must be a power of 2"));
assert_eq!(UnpaddedPieceSize(0b1111111000).validate(), Ok(()));
assert_eq!(
UnpaddedPieceSize(0b1110111000).validate(),
Err("unpadded piece size must be a power of 2 multiple of 127")
);
}
}
File renamed without changes.