Skip to content

Commit

Permalink
verifreg events and itest harness
Browse files Browse the repository at this point in the history
  • Loading branch information
aarshkshah1992 committed Jan 2, 2024
1 parent 1d85ec5 commit f522274
Show file tree
Hide file tree
Showing 10 changed files with 529 additions and 125 deletions.
98 changes: 98 additions & 0 deletions actors/verifreg/src/emit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// A namespace for helpers that build and emit verified registry events.

use crate::{ActorError, AllocationID};
use crate::{ClaimID, DataCap};
use fil_actors_runtime::runtime::Runtime;
use fil_actors_runtime::EventBuilder;
use fvm_shared::ActorID;

/// Indicates a new value for a verifier's datacap balance.
/// Note that receiving this event does not necessarily mean the balance has changed.
/// The value is in datacap whole units (not TokenAmount).
pub fn verifier_balance(
rt: &impl Runtime,
verifier: ActorID,
new_balance: &DataCap,
) -> Result<(), ActorError> {
rt.emit_event(
&EventBuilder::new()
.typ("verifier-balance")
.field_indexed("verifier", &verifier)
.field("balance", new_balance)
.build()?,
)
}

/// Indicates a new allocation has been made.
pub fn allocation(
rt: &impl Runtime,
id: AllocationID,
client: ActorID,
provider: ActorID,
) -> Result<(), ActorError> {
rt.emit_event(
&EventBuilder::new().typ("allocation").with_parties(id, client, provider).build()?,
)
}

/// Indicates an expired allocation has been removed.
pub fn allocation_removed(
rt: &impl Runtime,
id: AllocationID,
client: ActorID,
provider: ActorID,
) -> Result<(), ActorError> {
rt.emit_event(
&EventBuilder::new()
.typ("allocation-removed")
.with_parties(id, client, provider)
.build()?,
)
}

/// Indicates an allocation has been claimed.
pub fn claim(
rt: &impl Runtime,
id: ClaimID,
client: ActorID,
provider: ActorID,
) -> Result<(), ActorError> {
rt.emit_event(&EventBuilder::new().typ("claim").with_parties(id, client, provider).build()?)
}

/// Indicates an existing claim has been updated (e.g. with a longer term).
pub fn claim_updated(
rt: &impl Runtime,
id: ClaimID,
client: ActorID,
provider: ActorID,
) -> Result<(), ActorError> {
rt.emit_event(
&EventBuilder::new().typ("claim-updated").with_parties(id, client, provider).build()?,
)
}

/// Indicates an expired claim has been removed.
pub fn claim_removed(
rt: &impl Runtime,
id: ClaimID,
client: ActorID,
provider: ActorID,
) -> Result<(), ActorError> {
rt.emit_event(
&EventBuilder::new().typ("claim-removed").with_parties(id, client, provider).build()?,
)
}

// Private helpers //
trait WithParties {
fn with_parties(self, id: AllocationID, client: ActorID, provider: ActorID) -> EventBuilder;
}

impl WithParties for EventBuilder {
fn with_parties(self, id: AllocationID, client: ActorID, provider: ActorID) -> EventBuilder {
self.field_indexed("id", &id)
.field_indexed("client", &client)
.field_indexed("provider", &provider)
}
}
75 changes: 52 additions & 23 deletions actors/verifreg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub use self::types::*;
#[cfg(feature = "fil-actor")]
fil_actors_runtime::wasm_trampoline!(Actor);

pub mod emit;
pub mod expiration;
pub mod ext;
pub mod state;
Expand Down Expand Up @@ -103,44 +104,48 @@ impl Actor {
}

let verifier = resolve_to_actor_id(rt, &params.address, true)?;
let verifier = Address::new_id(verifier);
let verifier_addr = Address::new_id(verifier);

let st: State = rt.state()?;
rt.validate_immediate_caller_is(std::iter::once(&st.root_key))?;

// Disallow root as a verifier.
if verifier == st.root_key {
if verifier_addr == st.root_key {
return Err(actor_error!(illegal_argument, "Rootkey cannot be added as verifier"));
}

// Disallow existing clients as verifiers.
let token_balance = balance(rt, &verifier)?;
let token_balance = balance(rt, &verifier_addr)?;
if token_balance.is_positive() {
return Err(actor_error!(
illegal_argument,
"verified client {} cannot become a verifier",
verifier
verifier_addr
));
}

// Store the new verifier and allowance (over-writing).
rt.transaction(|st: &mut State, rt| {
st.put_verifier(rt.store(), &verifier, &params.allowance)
st.put_verifier(rt.store(), &verifier_addr, &params.allowance)
.context("failed to add verifier")
})
})?;

emit::verifier_balance(rt, verifier, &params.allowance)
}

pub fn remove_verifier(
rt: &impl Runtime,
params: RemoveVerifierParams,
) -> Result<(), ActorError> {
let verifier = resolve_to_actor_id(rt, &params.verifier, false)?;
let verifier = Address::new_id(verifier);
let verifier_addr = Address::new_id(verifier);

rt.transaction(|st: &mut State, rt| {
rt.validate_immediate_caller_is(std::iter::once(&st.root_key))?;
st.remove_verifier(rt.store(), &verifier).context("failed to remove verifier")
})
st.remove_verifier(rt.store(), &verifier_addr).context("failed to remove verifier")
})?;

emit::verifier_balance(rt, verifier, &DataCap::zero())
}

pub fn add_verified_client(
Expand Down Expand Up @@ -168,10 +173,10 @@ impl Actor {
}

// Validate caller is one of the verifiers, i.e. has an allowance (even if zero).
let verifier = rt.message().caller();
let verifier_addr = rt.message().caller();
let verifier_cap = st
.get_verifier_cap(rt.store(), &verifier)?
.ok_or_else(|| actor_error!(not_found, "caller {} is not a verifier", verifier))?;
.get_verifier_cap(rt.store(), &verifier_addr)?
.ok_or_else(|| actor_error!(not_found, "caller {} is not a verifier", verifier_addr))?;

// Disallow existing verifiers as clients.
if st.get_verifier_cap(rt.store(), &client)?.is_some() {
Expand All @@ -194,8 +199,10 @@ impl Actor {

// Reduce verifier's cap.
let new_verifier_cap = verifier_cap - &params.allowance;
st.put_verifier(rt.store(), &verifier, &new_verifier_cap)
.context("failed to update verifier allowance")
st.put_verifier(rt.store(), &verifier_addr, &new_verifier_cap)
.context("failed to update verifier allowance")?;

emit::verifier_balance(rt, verifier_addr.id().unwrap(), &new_verifier_cap)
})?;

// Credit client token allowance.
Expand Down Expand Up @@ -331,9 +338,12 @@ impl Actor {
let existing = allocs.remove(params.client, *id).context_code(
ExitCode::USR_ILLEGAL_STATE,
format!("failed to remove allocation {}", id),
)?;
)?.unwrap(); // Unwrapping here as both paths to here should ensure the allocation exists.

emit::allocation_removed(rt, *id, existing.client, existing.provider)?;

// Unwrapping here as both paths to here should ensure the allocation exists.
recovered_datacap += existing.unwrap().size.0;
recovered_datacap += existing.size.0;
}

st.save_allocs(&mut allocs)?;
Expand Down Expand Up @@ -432,6 +442,9 @@ impl Actor {
if !inserted {
return Err(actor_error!(illegal_argument, "claim {} already exists", id));
}

emit::claim(rt, id, new_claim.client, new_claim.provider)?;

allocs.remove(new_claim.client, id).context_code(
ExitCode::USR_ILLEGAL_STATE,
format!("failed to remove allocation {}", id),
Expand Down Expand Up @@ -542,11 +555,12 @@ impl Actor {
}

let new_claim = Claim { term_max: term.term_max, ..*claim };
st_claims.put(term.provider, term.claim_id, new_claim).context_code(
st_claims.put(term.provider, term.claim_id, new_claim.clone()).context_code(
ExitCode::USR_ILLEGAL_STATE,
"HAMT put failure storing new claims",
)?;
batch_gen.add_success();
emit::claim_updated(rt, term.claim_id, new_claim.client, new_claim.provider)?;
} else {
batch_gen.add_fail(ExitCode::USR_NOT_FOUND);
info!("no claim {} for provider {}", term.claim_id, term.provider);
Expand Down Expand Up @@ -590,10 +604,15 @@ impl Actor {
}

for id in to_remove {
claims.remove(params.provider, *id).context_code(
ExitCode::USR_ILLEGAL_STATE,
format!("failed to remove claim {}", id),
)?;
let removed = claims
.remove(params.provider, *id)
.context_code(
ExitCode::USR_ILLEGAL_STATE,
format!("failed to remove claim {}", id),
)?
.unwrap();

emit::claim_removed(rt, *id, removed.client, removed.provider)?;
}

st.save_claims(&mut claims)?;
Expand Down Expand Up @@ -690,8 +709,18 @@ impl Actor {

// Save new allocations and updated claims.
let ids = rt.transaction(|st: &mut State, rt| {
let ids = st.insert_allocations(rt.store(), client, new_allocs)?;
st.put_claims(rt.store(), updated_claims)?;
let ids = st.insert_allocations(rt.store(), client, new_allocs.clone())?;

for (id, alloc) in ids.iter().zip(new_allocs.iter()) {
emit::allocation(rt, *id, alloc.client, alloc.provider)?;
}

st.put_claims(rt.store(), updated_claims.clone())?;

for (id, claim) in updated_claims {
emit::claim_updated(rt, id, claim.client, claim.provider)?;
}

Ok(ids)
})?;

Expand Down
Loading

0 comments on commit f522274

Please sign in to comment.