forked from wormhole-foundation/native-token-transfers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidated_transceiver_message.move
57 lines (53 loc) · 2.68 KB
/
validated_transceiver_message.move
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/// Inbound communication between transceivers and managers.
///
/// The transceiver validates the message, and constructs
/// a `ValidatedTransceiverMessage` value.
///
/// The `new` function requires authenticates the transceiver, and stores its
/// identity in a phantom type parameter.
/// Thus, when the manager receives a value of type
/// `ValidatedTransceiverMessage<SomeTransceiverAuth, A>`, it knows it was
/// created by the transceiver that defines the `SomeTransceiverAuth` type.
///
/// The manager will then consume this message using the `destruct_recipient_only`.
/// As the function's name suggests, only the intended manager can consume the message.
/// This guarantees that once the transceiver has validated the message, it will be seen by
/// the appropriate manager.
/// This is not a strict security requirement, as long as the transceiver
/// doesn't implement its internal replay protection, because then no denial of
/// service is possible by a malicious client "hijacking" a validation.
/// Nevertheless, we restrict the consumption in this way to provide a static
/// guarantee that the message will be sent to the right place.
module ntt_common::validated_transceiver_message {
use wormhole::external_address::{Self, ExternalAddress};
use ntt_common::transceiver_message_data::TransceiverMessageData;
use ntt_common::ntt_manager_message::NttManagerMessage;
#[error]
const EInvalidRecipientManager: vector<u8> =
b"Invalid recipient manager.";
public struct ValidatedTransceiverMessage<phantom Transceiver, A> {
from_chain: u16,
message: TransceiverMessageData<A>
}
public fun new<TransceiverAuth, A>(
auth: &TransceiverAuth, // only the transceiver can create it
from_chain: u16,
message: TransceiverMessageData<A>
): ValidatedTransceiverMessage<TransceiverAuth, A> {
ntt_common::contract_auth::assert_auth_type(auth);
ValidatedTransceiverMessage {
from_chain,
message
}
}
public fun destruct_recipient_only<TransceiverAuth, ManagerAuth, A>(
message: ValidatedTransceiverMessage<TransceiverAuth, A>,
auth: &ManagerAuth, // only the recipient mangaer can destruct
): (u16, ExternalAddress, NttManagerMessage<A>) {
let ValidatedTransceiverMessage { from_chain, message } = message;
let (source_ntt_manager, recipient_ntt_manager, ntt_manager_message) = message.destruct();
let caller_manager = ntt_common::contract_auth::assert_auth_type(auth);
assert!(external_address::from_address(caller_manager) == recipient_ntt_manager, EInvalidRecipientManager);
(from_chain, source_ntt_manager, ntt_manager_message)
}
}