Skip to content

Commit aaf1837

Browse files
committed
Paych actor: Drop account req, use AuthenticateMessage to verify sigs
1 parent ad4f69b commit aaf1837

File tree

4 files changed

+214
-257
lines changed

4 files changed

+214
-257
lines changed

actors/paych/src/ext.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use fvm_ipld_encoding::serde_bytes;
2+
use fvm_ipld_encoding::tuple::*;
3+
4+
pub mod account {
5+
use super::*;
6+
7+
pub const AUTHENTICATE_MESSAGE_METHOD: u64 = 3;
8+
9+
#[derive(Serialize_tuple, Deserialize_tuple)]
10+
pub struct AuthenticateMessageParams {
11+
#[serde(with = "serde_bytes")]
12+
pub signature: Vec<u8>,
13+
#[serde(with = "serde_bytes")]
14+
pub message: Vec<u8>,
15+
}
16+
}

actors/paych/src/lib.rs

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use fil_actors_runtime::runtime::builtins::Type;
55
use fil_actors_runtime::runtime::{ActorCode, Runtime};
66
use fil_actors_runtime::{
7-
actor_error, cbor, resolve_to_actor_id, restrict_internal_api, ActorDowncast, ActorError, Array,
7+
actor_error, cbor, restrict_internal_api, ActorDowncast, ActorError, Array, AsActorError,
88
};
99
use fvm_ipld_blockstore::Blockstore;
1010
use fvm_ipld_encoding::RawBytes;
@@ -22,6 +22,7 @@ pub use self::types::*;
2222
#[cfg(feature = "fil-actor")]
2323
fil_actors_runtime::wasm_trampoline!(Actor);
2424

25+
pub mod ext;
2526
mod state;
2627
pub mod testing;
2728
mod types;
@@ -42,17 +43,25 @@ pub const ERR_CHANNEL_STATE_UPDATE_AFTER_SETTLED: ExitCode = ExitCode::new(32);
4243

4344
/// Payment Channel actor
4445
pub struct Actor;
46+
4547
impl Actor {
4648
/// Constructor for Payment channel actor
4749
pub fn constructor(rt: &mut impl Runtime, params: ConstructorParams) -> Result<(), ActorError> {
4850
// Only InitActor can create a payment channel actor. It creates the actor on
4951
// behalf of the payer/payee.
5052
rt.validate_immediate_caller_type(std::iter::once(&Type::Init))?;
5153

52-
// Check both parties are capable of signing vouchers
53-
let to = Self::resolve_account(rt, &params.to)?;
54+
// Resolve both parties if necessary.
55+
// Note that this does NOT guarantee that the parties exist in state yet.
56+
let to =
57+
rt.resolve_address(&params.to).with_context_code(ExitCode::USR_NOT_FOUND, || {
58+
format!("to address not found {}", params.to)
59+
})?;
5460

55-
let from = Self::resolve_account(rt, &params.from)?;
61+
let from =
62+
rt.resolve_address(&params.from).with_context_code(ExitCode::USR_NOT_FOUND, || {
63+
format!("to address not found {}", params.to)
64+
})?;
5665

5766
let empty_arr_cid =
5867
Array::<(), _>::new_with_bit_width(rt.store(), LANE_STATES_AMT_BITWIDTH)
@@ -65,28 +74,6 @@ impl Actor {
6574
Ok(())
6675
}
6776

68-
/// Resolves an address to a canonical ID address and requires it to address an account actor.
69-
fn resolve_account(rt: &mut impl Runtime, raw: &Address) -> Result<Address, ActorError> {
70-
let resolved = resolve_to_actor_id(rt, raw)?;
71-
72-
let code_cid = rt
73-
.get_actor_code_cid(&resolved)
74-
.ok_or_else(|| actor_error!(illegal_argument, "no code for address {}", resolved))?;
75-
76-
let typ = rt.resolve_builtin_actor_type(&code_cid);
77-
if typ != Some(Type::Account) {
78-
Err(actor_error!(
79-
forbidden,
80-
"actor {} must be an account, was {} ({:?})",
81-
raw,
82-
code_cid,
83-
typ
84-
))
85-
} else {
86-
Ok(Address::new_id(resolved))
87-
}
88-
}
89-
9077
pub fn update_channel_state(
9178
rt: &mut impl Runtime,
9279
params: UpdateChannelStateParams,
@@ -98,10 +85,11 @@ impl Actor {
9885
let sv = params.sv;
9986

10087
// Pull signature from signed voucher
101-
let sig = sv
88+
let sig = &sv
10289
.signature
10390
.as_ref()
104-
.ok_or_else(|| actor_error!(illegal_argument, "voucher has no signature"))?;
91+
.ok_or_else(|| actor_error!(illegal_argument, "voucher has no signature"))?
92+
.bytes;
10593

10694
if st.settling_at != 0 && rt.curr_epoch() >= st.settling_at {
10795
return Err(ActorError::unchecked(
@@ -120,9 +108,17 @@ impl Actor {
120108
})?;
121109

122110
// Validate signature
123-
rt.verify_signature(sig, &signer, &sv_bz).map_err(|e| {
124-
e.downcast_default(ExitCode::USR_ILLEGAL_ARGUMENT, "voucher signature invalid")
125-
})?;
111+
112+
rt.send(
113+
&signer,
114+
ext::account::AUTHENTICATE_MESSAGE_METHOD,
115+
RawBytes::serialize(ext::account::AuthenticateMessageParams {
116+
signature: sig.to_vec(),
117+
message: sv_bz,
118+
})?,
119+
TokenAmount::zero(),
120+
)
121+
.map_err(|e| e.wrap("voucher sig authentication failed"))?;
126122

127123
let pch_addr = rt.message().receiver();
128124
let svpch_id = rt.resolve_address(&sv.channel_addr).ok_or_else(|| {

actors/paych/src/state.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use cid::Cid;
55
use fvm_ipld_encoding::tuple::*;
66
use fvm_ipld_encoding::Cbor;
77
use fvm_shared::address::Address;
8+
use fvm_shared::ActorID;
89

910
use fvm_shared::clock::ChainEpoch;
1011
use fvm_shared::econ::TokenAmount;
@@ -29,10 +30,10 @@ pub struct State {
2930
}
3031

3132
impl State {
32-
pub fn new(from: Address, to: Address, empty_arr_cid: Cid) -> Self {
33+
pub fn new(from: ActorID, to: ActorID, empty_arr_cid: Cid) -> Self {
3334
Self {
34-
from,
35-
to,
35+
from: Address::new_id(from),
36+
to: Address::new_id(to),
3637
to_send: Default::default(),
3738
settling_at: 0,
3839
min_settle_height: 0,

0 commit comments

Comments
 (0)