() => {
{
let tx_len = byte_utils::slice_to_be64(read_bytes!(8));
- let tx: Transaction = unwrap_obj!(serialize::deserialize(read_bytes!(tx_len)));
+ let tx_ser = read_bytes!(tx_len);
+ let tx: Transaction = unwrap_obj!(serialize::deserialize(tx_ser));
+ if serialize::serialize(&tx).unwrap() != tx_ser {
+ // We check that the tx re-serializes to the same form to ensure there is
+ // no extra data, and as rust-bitcoin doesn't handle the 0-input ambiguity
+ // all that well.
+ return None;
+ }
let revocation_key = unwrap_obj!(PublicKey::from_slice(&secp_ctx, read_bytes!(33)));
let a_htlc_key = unwrap_obj!(PublicKey::from_slice(&secp_ctx, read_bytes!(33)));
let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers!
let per_commitment_option = self.remote_claimable_outpoints.get(&commitment_txid);
- let commitment_number = (((tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor;
+ let commitment_number = 0xffffffffffff - ((((tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor);
if commitment_number >= self.get_min_seen_secret() {
let secret = self.get_secret(commitment_number).unwrap();
let per_commitment_key = ignore_error!(SecretKey::from_slice(&self.secp_ctx, &secret));