4
4
use fvm_ipld_blockstore:: Blockstore ;
5
5
use fvm_ipld_encoding:: RawBytes ;
6
6
use fvm_shared:: address:: { Address , Protocol } ;
7
+ use fvm_shared:: crypto:: signature:: SignatureType :: { Secp256k1 , BLS } ;
8
+ use fvm_shared:: crypto:: signature:: { Signature , SignatureType } ;
9
+ use fvm_shared:: error:: ExitCode ;
7
10
use fvm_shared:: { MethodNum , METHOD_CONSTRUCTOR } ;
8
11
use num_derive:: FromPrimitive ;
9
12
use num_traits:: FromPrimitive ;
10
13
14
+ use crate :: types:: AuthenticateMessageParams ;
11
15
use fil_actors_runtime:: builtin:: singletons:: SYSTEM_ACTOR_ADDR ;
12
- use fil_actors_runtime:: cbor;
13
16
use fil_actors_runtime:: runtime:: { ActorCode , Runtime } ;
14
17
use fil_actors_runtime:: { actor_error, ActorError } ;
18
+ use fil_actors_runtime:: { cbor, ActorDowncast } ;
15
19
16
20
pub use self :: state:: State ;
17
21
18
22
mod state;
19
23
pub mod testing;
24
+ pub mod types;
20
25
21
26
#[ cfg( feature = "fil-actor" ) ]
22
27
fil_actors_runtime:: wasm_trampoline!( Actor ) ;
@@ -29,10 +34,12 @@ fil_actors_runtime::wasm_trampoline!(Actor);
29
34
pub enum Method {
30
35
Constructor = METHOD_CONSTRUCTOR ,
31
36
PubkeyAddress = 2 ,
37
+ AuthenticateMessage = 3 ,
32
38
}
33
39
34
40
/// Account Actor
35
41
pub struct Actor ;
42
+
36
43
impl Actor {
37
44
/// Constructor for Account actor
38
45
pub fn constructor < BS , RT > ( rt : & mut RT , address : Address ) -> Result < ( ) , ActorError >
@@ -52,7 +59,7 @@ impl Actor {
52
59
Ok ( ( ) )
53
60
}
54
61
55
- // Fetches the pubkey-type address from this actor.
62
+ /// Fetches the pubkey-type address from this actor.
56
63
pub fn pubkey_address < BS , RT > ( rt : & mut RT ) -> Result < Address , ActorError >
57
64
where
58
65
BS : Blockstore ,
@@ -62,6 +69,39 @@ impl Actor {
62
69
let st: State = rt. state ( ) ?;
63
70
Ok ( st. address )
64
71
}
72
+
73
+ /// Authenticates whether the provided signature is valid for the provided message.
74
+ /// Should be called with the raw bytes of a signature, NOT a serialized Signature object that includes a SignatureType.
75
+ /// Errors with USR_ILLEGAL_ARGUMENT if the authentication is invalid.
76
+ pub fn authenticate_message < BS , RT > (
77
+ rt : & mut RT ,
78
+ params : AuthenticateMessageParams ,
79
+ ) -> Result < ( ) , ActorError >
80
+ where
81
+ BS : Blockstore ,
82
+ RT : Runtime < BS > ,
83
+ {
84
+ rt. validate_immediate_caller_accept_any ( ) ?;
85
+ let st: State = rt. state ( ) ?;
86
+ let address = st. address ;
87
+ let sig_type: SignatureType = match address. protocol ( ) {
88
+ Protocol :: Secp256k1 => Secp256k1 ,
89
+ Protocol :: BLS => BLS ,
90
+ protocol => {
91
+ return Err ( actor_error ! ( illegal_state;
92
+ "account address must use BLS or SECP protocol, got {}" , protocol) ) ;
93
+ }
94
+ } ;
95
+ let sig = Signature { sig_type, bytes : params. signature } ;
96
+ rt. verify_signature ( & sig, & address, & params. message ) . map_err ( |e| {
97
+ e. downcast_default (
98
+ ExitCode :: USR_ILLEGAL_ARGUMENT ,
99
+ "failed to authenticate message, signature invalid" ,
100
+ )
101
+ } ) ?;
102
+
103
+ Ok ( ( ) )
104
+ }
65
105
}
66
106
67
107
impl ActorCode for Actor {
@@ -83,6 +123,10 @@ impl ActorCode for Actor {
83
123
let addr = Self :: pubkey_address ( rt) ?;
84
124
Ok ( RawBytes :: serialize ( addr) ?)
85
125
}
126
+ Some ( Method :: AuthenticateMessage ) => {
127
+ Self :: authenticate_message ( rt, cbor:: deserialize_params ( params) ?) ?;
128
+ Ok ( RawBytes :: default ( ) )
129
+ }
86
130
None => Err ( actor_error ! ( unhandled_message; "Invalid method" ) ) ,
87
131
}
88
132
}
0 commit comments