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(())
}
}