Skip to content

Commit

Permalink
fix: cleanup tipset timestamp/cid (#934)
Browse files Browse the repository at this point in the history
fixes #927

- Use the ChainEpoch type where appropriate.
- Use Result instead of Option for incorrect epochs, and use a
  descriptive error.
- Take the epoch instead of an offset in tipset_cid.
- Docs, all the docs.
- Fill in some todos
- Add a TODOs/issues for missing things.
  • Loading branch information
Stebalien authored Oct 7, 2022
1 parent c6df794 commit a9d6dd8
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 23 deletions.
15 changes: 7 additions & 8 deletions fvm/src/kernel/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,20 +676,19 @@ where
self.call_manager.context().network_context.timestamp
}

fn tipset_cid(&self, epoch: i64) -> Result<Option<Cid>> {
fn tipset_cid(&self, epoch: ChainEpoch) -> Result<Cid> {
if epoch < 0 {
return Err(syscall_error!(IllegalArgument; "epoch is negative").into());
}
if epoch >= 900 {
return Err(syscall_error!(IllegalArgument; "epoch out of finality range").into());
let offset = self.call_manager.context().network_context.epoch - epoch;
if offset < 0 {
return Err(syscall_error!(IllegalArgument; "epoch is in the future").into());
}

let tipsets = &self.call_manager.context().network_context.tipsets;
if (epoch as usize) < tipsets.len() {
return Ok(Some(tipsets[epoch as usize]));
if offset >= tipsets.len() as i64 {
return Err(syscall_error!(LimitExceeded; "tipset lookback exceeded limit").into());
}

Ok(None)
Ok(tipsets[offset as usize])
}
}

Expand Down
6 changes: 3 additions & 3 deletions fvm/src/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ pub trait NetworkOps {
/// The current base-fee (constant).
fn network_base_fee(&self) -> &TokenAmount;

/// current tipset timestamp
/// The current tipset timestamp (seconds since the unix epoch).
fn tipset_timestamp(&self) -> u64;

/// epoch tipset cid
fn tipset_cid(&self, epoch: i64) -> Result<Option<Cid>>;
/// The CID of the tipset at the specified epoch.
fn tipset_cid(&self, epoch: ChainEpoch) -> Result<Cid>;
}

/// Accessors to query attributes of the incoming message.
Expand Down
1 change: 1 addition & 0 deletions fvm/src/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ impl NetworkConfig {
network: self.clone(),
network_context: NetworkContext {
epoch,
// TODO #933
timestamp: 0,
tipsets: vec![],
base_fee: TokenAmount::zero(),
Expand Down
7 changes: 2 additions & 5 deletions fvm/src/syscalls/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ pub fn tipset_cid(
// We always check arguments _first_, before we do anything else.
context.memory.check_bounds(obuf_off, obuf_len)?;

if let Some(cid) = context.kernel.tipset_cid(epoch)? {
context.memory.write_cid(&cid, obuf_off, obuf_len)
} else {
Ok(0)
}
let cid = context.kernel.tipset_cid(epoch)?;
context.memory.write_cid(&cid, obuf_off, obuf_len)
}
8 changes: 8 additions & 0 deletions sdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,11 @@ pub enum ActorDeleteError {
#[error("deletion beneficiary does not exist")]
BeneficiaryDoesNotExist,
}

#[derive(Copy, Clone, Debug, Error)]
pub enum EpochBoundsError {
#[error("the requested epoch isn't valid")]
Invalid,
#[error("the requested epoch exceeds the maximum lookback")]
ExceedsLookback,
}
11 changes: 8 additions & 3 deletions sdk/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use fvm_shared::error::ErrorNumber;
use fvm_shared::version::NetworkVersion;
use fvm_shared::MAX_CID_LEN;

use crate::error::EpochBoundsError;
use crate::sys;
use crate::vm::INVOCATION_CONTEXT;

Expand Down Expand Up @@ -37,17 +38,21 @@ pub fn total_fil_circ_supply() -> TokenAmount {
}
}

/// Returns the current block time in seconds since the EPOCH.
pub fn tipset_timestamp() -> u64 {
unsafe { sys::network::tipset_timestamp() }.expect("failed to get timestamp")
}

pub fn tipset_cid(epoch: i64) -> Option<Cid> {
/// Returns the tipset CID of the specified epoch, if available. Allows querying from now up to
/// finality (900 epochs).
pub fn tipset_cid(epoch: ChainEpoch) -> Result<Cid, EpochBoundsError> {
let mut buf = [0u8; MAX_CID_LEN];

unsafe {
match sys::network::tipset_cid(epoch, buf.as_mut_ptr(), MAX_CID_LEN as u32) {
Ok(len) => Some(Cid::read_bytes(&buf[..len as usize]).expect("invalid cid")),
Err(ErrorNumber::NotFound) => None,
Ok(len) => Ok(Cid::read_bytes(&buf[..len as usize]).expect("invalid cid")),
Err(ErrorNumber::IllegalArgument) => Err(EpochBoundsError::Invalid),
Err(ErrorNumber::LimitExceeded) => Err(EpochBoundsError::ExceedsLookback),
Err(other) => panic!("unexpected cid resolution failure: {}", other),
}
}
Expand Down
19 changes: 18 additions & 1 deletion sdk/src/sys/network.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
//! Syscalls for network metadata.

// for documentation links
#[cfg(doc)]
use crate::sys::ErrorNumber::*;

super::fvm_syscalls! {
module = "network";

Expand All @@ -26,9 +30,22 @@ super::fvm_syscalls! {

/// Retrieves a tipset's CID within the last finality, if available
///
/// # Arguments
///
/// - `epoch` the epoch being queried.
/// - `ret_off` and `ret_len` specify the location and length of the buffer into which the
/// tipset CID will be written.
///
/// # Returns
///
/// Returns the length of the CID written to the output buffer.
///
/// # Errors
///
/// IllegalArgument -- raised when the epoch is negative or greater/equal than finality.
/// | Error | Reason |
/// |---------------------|----------------------------------------------|
/// | [`IllegalArgument`] | specified epoch is negative or in the future |
/// | [`LimitExceeded`] | specified epoch exceeds finality |
pub fn tipset_cid(
epoch: i64,
ret_off: *mut u8,
Expand Down
6 changes: 3 additions & 3 deletions testing/conformance/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,11 +605,11 @@ where
}

fn tipset_timestamp(&self) -> u64 {
todo!()
self.0.tipset_timestamp()
}

fn tipset_cid(&self, _epoch: i64) -> Result<Option<Cid>> {
todo!()
fn tipset_cid(&self, epoch: ChainEpoch) -> Result<Cid> {
self.0.tipset_cid(epoch)
}
}

Expand Down

0 comments on commit a9d6dd8

Please sign in to comment.