Skip to content

Commit

Permalink
fix: verify tx valid_since remain flags must be empty
Browse files Browse the repository at this point in the history
  • Loading branch information
jjyr committed Apr 10, 2019
1 parent 823561d commit 045061f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
2 changes: 2 additions & 0 deletions verification/src/error.rs
Expand Up @@ -146,4 +146,6 @@ pub enum TransactionError {
Version,
/// Tx not satisfied valid_since condition
Immature,
/// Invalid ValidSince flags
InvalidValidSince,
}
27 changes: 27 additions & 0 deletions verification/src/tests/transaction_verifier.rs
Expand Up @@ -126,6 +126,33 @@ impl BlockMedianTimeContext for FakeMedianTime {

#[test]
pub fn test_valid_since() {
// use remain flags
let transaction = TransactionBuilder::default()
.inputs(vec![CellInput::new(
OutPoint::new(H256::from_trimmed_hex_str("1").unwrap(), 0),
0x2000_0000_0000_0000,
Default::default(),
)])
.build();

let rtx = ResolvedTransaction {
transaction,
dep_cells: Vec::new(),
input_cells: vec![CellStatus::Live(CellMeta {
cell_output: CellOutput::new(50, Vec::new(), Script::default(), None),
block_number: Some(1),
})],
};

let median_time_context = FakeMedianTime {
timestamps: vec![0; 11],
};
let verifier = ValidSinceVerifier::new(&rtx, &median_time_context, 5);
assert_eq!(
verifier.verify().err(),
Some(TransactionError::InvalidValidSince)
);

// absolute lock
let transaction = TransactionBuilder::default()
.inputs(vec![CellInput::new(
Expand Down
19 changes: 15 additions & 4 deletions verification/src/transaction_verifier.rs
Expand Up @@ -229,6 +229,7 @@ impl<'a> CapacityVerifier<'a> {
const LOCK_TYPE_FLAG: u64 = 1 << 63;
const TIME_TYPE_FLAG: u64 = 1 << 62;
const VALUE_MUSK: u64 = 0x00ff_ffff_ffff_ffff;
const REMAIN_FLAGS_BITS: u64 = 0x3f00_0000_0000_0000;

/// RFC 0017
#[derive(Copy, Clone, Debug)]
Expand All @@ -244,6 +245,10 @@ impl ValidSince {
!self.is_absolute()
}

pub fn remain_flags_is_empty(self) -> bool {
self.0 & REMAIN_FLAGS_BITS == 0
}

fn metric_type_is_number(self) -> bool {
self.0 & TIME_TYPE_FLAG == 0
}
Expand Down Expand Up @@ -368,16 +373,22 @@ where
.iter()
.zip(self.rtx.transaction.inputs())
{
let cell = match cell_status.get_live() {
Some(cell) => cell,
None => return Err(TransactionError::Conflict),
};
// ignore empty valid_since
if input.valid_since == 0 {
continue;
}
let valid_since = ValidSince(input.valid_since);
// check remain flags
if !valid_since.remain_flags_is_empty() {
return Err(TransactionError::InvalidValidSince);
}

// verify time lock
self.verify_absolute_lock(valid_since)?;
let cell = match cell_status.get_live() {
Some(cell) => cell,
None => return Err(TransactionError::Conflict),
};
self.verify_relative_lock(valid_since, cell)?;
}
Ok(())
Expand Down

0 comments on commit 045061f

Please sign in to comment.