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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use raiden_blockchain::keys::PrivateKey;
use raiden_primitives::{
	deserializers::u64_from_str,
	traits::ToBytes,
	types::{
		MessageIdentifier,
		Signature,
	},
};
use raiden_state_machine::types::SendProcessed;
use serde::{
	Deserialize,
	Serialize,
};
use web3::signing::SigningError;

use super::{
	CmdId,
	SignedMessage,
};

/// Used by the recipient when a message which has to be validated against
/// blockchain data was successfully processed.
///
/// This message is only used to confirm the processing of messages which have
/// some blockchain related data, where receiving the message is not
/// sufficient. Consider the following scenario:
///
/// - Node A starts a deposit of 5 tokens.
/// - Node A sees the deposit, and starts a transfer.
/// - Node B receives the transfer, however it has not seen the deposit, therefore the transfer is
///   rejected.
///
/// Second scenario:
///
/// - Node A has a lock which has expired, and sends the RemoveExpiredLock message.
/// - Node B receives the message, but from its perspective the block at which the lock expires has
///   not been confirmed yet, meaning that a reorg is possible and the secret can be registered
///   on-chain.
///
/// For both scenarios A has to keep retrying until B accepts the message.
///
/// Notes:
///     - This message is required even if the transport guarantees durability of the data.
///     - This message provides a stronger guarantee then a Delivered, therefore it can replace it.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
pub struct Processed {
	#[serde(deserialize_with = "u64_from_str")]
	#[serde(skip_serializing)]
	pub message_identifier: MessageIdentifier,
	pub signature: Signature,
}

impl From<SendProcessed> for Processed {
	fn from(event: SendProcessed) -> Self {
		Self { message_identifier: event.message_identifier, signature: Signature::default() }
	}
}

impl SignedMessage for Processed {
	fn bytes_to_sign(&self) -> Vec<u8> {
		let cmd_id: [u8; 1] = CmdId::Processed.into();

		let mut bytes = vec![];
		bytes.extend_from_slice(&cmd_id);
		bytes.extend_from_slice(&[0, 0, 0]);
		bytes.extend_from_slice(&self.message_identifier.to_be_bytes());
		bytes
	}

	fn sign(&mut self, key: PrivateKey) -> Result<(), SigningError> {
		self.signature = self.sign_message(key)?.to_bytes().into();
		Ok(())
	}
}

/// Informs the sender that the message was received *and* persisted.
///
/// Notes:
///     - This message provides a weaker guarantee in respect to the Processed message. It can be
///       emulated by a transport layer that guarantees persistence, or it can be sent by the
///       recipient before the received message is processed (therefore it does not matter if the
///       message was successfully processed or not).
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
pub struct Delivered {
	#[serde(deserialize_with = "u64_from_str")]
	pub delivered_message_identifier: MessageIdentifier,
	pub signature: Signature,
}

impl SignedMessage for Delivered {
	fn bytes_to_sign(&self) -> Vec<u8> {
		let cmd_id: [u8; 1] = CmdId::Delivered.into();

		let mut bytes = vec![];
		bytes.extend_from_slice(&cmd_id);
		bytes.extend_from_slice(&[0, 0, 0]);
		bytes.extend_from_slice(&self.delivered_message_identifier.to_be_bytes());
		bytes
	}

	fn sign(&mut self, key: PrivateKey) -> Result<(), SigningError> {
		self.signature = self.sign_message(key)?.to_bytes().into();
		Ok(())
	}
}