use fuels::{
crypto::Message,
types::ContractId,
};
use sha2::{
Digest,
Sha256,
};
const FORCE_CLOSE_COSIGN_TAG: u8 = 0x05;
fn force_close_preimage(
chain_id: u64,
pool: ContractId,
account: ContractId,
session_id: u64,
) -> [u8; 81] {
let mut bytes = [0; 81];
bytes[0] = FORCE_CLOSE_COSIGN_TAG;
bytes[1..9].copy_from_slice(&chain_id.to_be_bytes());
bytes[9..41].copy_from_slice(pool.as_slice());
bytes[41..73].copy_from_slice(account.as_slice());
bytes[73..81].copy_from_slice(&session_id.to_be_bytes());
bytes
}
pub fn generate_pool_force_close_digest(
chain_id: u64,
pool: ContractId,
account: ContractId,
session_id: u64,
) -> [u8; 32] {
Sha256::digest(force_close_preimage(chain_id, pool, account, session_id)).into()
}
pub fn generate_pool_force_close_signing_payload(
chain_id: u64,
pool: ContractId,
account: ContractId,
session_id: u64,
) -> Message {
Message::from_bytes(generate_pool_force_close_digest(
chain_id, pool, account, session_id,
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encoding_and_signable_message_match_the_sway_vector() {
let chain = 0x0102_0304_0506_0708;
let pool = ContractId::new([0x11; 32]);
let account = ContractId::new([0x22; 32]);
let session = 0x1122_3344_5566_7788;
let bytes = force_close_preimage(chain, pool, account, session);
assert_eq!(bytes.len(), 81);
assert_eq!(&bytes[..9], &[5, 1, 2, 3, 4, 5, 6, 7, 8]);
assert_eq!(&bytes[9..41], &[0x11; 32]);
assert_eq!(&bytes[41..73], &[0x22; 32]);
assert_eq!(
&bytes[73..],
&[0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]
);
let expected = [
0x69, 0xca, 0x8d, 0x56, 0x99, 0x2a, 0x1b, 0xbc, 0xdd, 0xce, 0xc7, 0x3a, 0xb2,
0x9c, 0x71, 0xcd, 0x9b, 0x99, 0xaf, 0xea, 0xe1, 0x92, 0x01, 0xbf, 0x97, 0x5a,
0xcb, 0x5d, 0xee, 0x56, 0x7c, 0x36,
];
assert_eq!(
generate_pool_force_close_digest(chain, pool, account, session),
expected
);
assert_eq!(
generate_pool_force_close_signing_payload(chain, pool, account, session),
Message::from_bytes(expected)
);
}
}