Skip to content

Commit 1d39626

Browse files
author
Seulgi Kim
committed
Make CreateWorld fail on invalid nonce
1 parent a45e14f commit 1d39626

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

state/src/impls/shard_level.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,18 @@ impl<B: Backend + ShardBackend> ShardLevelState<B> {
137137
}
138138
}
139139

140-
fn create_world(&mut self, shard_id: ShardId, _nonce: &u64, owners: &Vec<Address>) -> StateResult<()> {
140+
fn create_world(&mut self, shard_id: ShardId, nonce: &u64, owners: &Vec<Address>) -> StateResult<()> {
141141
let metadata_address = ShardMetadataAddress::new(shard_id);
142142
let mut metadata = self.require_metadata(&metadata_address, || unreachable!("Shard must have metadata"))?;
143143

144+
let current_nonce = *metadata.nonce();
145+
if *nonce != current_nonce {
146+
return Err(TransactionError::InvalidShardNonce(Mismatch {
147+
expected: current_nonce,
148+
found: *nonce,
149+
}).into())
150+
}
151+
144152
let world_id = *metadata.number_of_worlds();
145153
let world_address = WorldAddress::new(shard_id, world_id);
146154

@@ -569,6 +577,40 @@ mod tests {
569577
assert_eq!(Ok(Some(World::new(owners))), world);
570578
}
571579

580+
#[test]
581+
fn create_world_fail_if_nonce_is_not_matched() {
582+
let network_id = 0xDEADBEEF;
583+
let shard_id = 0xCAFE;
584+
let mut state = get_temp_shard_state(shard_id);
585+
586+
let nonce = 1;
587+
let owners = vec![];
588+
589+
let transaction = Transaction::CreateWorld {
590+
network_id,
591+
shard_id,
592+
nonce,
593+
owners: owners.clone(),
594+
};
595+
596+
let sender = address();
597+
let shard_owner = address();
598+
assert_eq!(
599+
Ok(TransactionInvoice::Fail(TransactionError::InvalidShardNonce(Mismatch {
600+
expected: 0,
601+
found: 1
602+
}))),
603+
state.apply(shard_id, &transaction, &sender, &shard_owner)
604+
);
605+
606+
let metadata = state.metadata();
607+
assert_eq!(Ok(Some(ShardMetadata::new_with_nonce(0, 0))), metadata);
608+
609+
let world_id = 0;
610+
let world = state.world(world_id);
611+
assert_eq!(Ok(None), world);
612+
}
613+
572614
#[test]
573615
fn mint_permissioned_asset() {
574616
let shard_id = 0;

types/src/transaction/error.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub enum Error {
4949
FailedToUnlock(H256),
5050
/// Returned when the sum of the transaction's inputs is different from the sum of outputs.
5151
InconsistentTransactionInOut,
52+
InvalidShardNonce(Mismatch<u64>),
5253
}
5354

5455
const ERROR_ID_INVALID_PAYMENT_SENDER: u8 = 1u8;
@@ -62,6 +63,7 @@ const ERROR_ID_SCRIPT_HASH_MISMATCH: u8 = 8u8;
6263
const ERROR_ID_INVALID_SCRIPT: u8 = 9u8;
6364
const ERROR_ID_FAILED_TO_UNLOCK: u8 = 10u8;
6465
const ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT: u8 = 11u8;
66+
const ERROR_ID_INVALID_SHARD_NONCE: u8 = 12u8;
6567

6668
impl Encodable for Error {
6769
fn rlp_append(&self, s: &mut RlpStream) {
@@ -91,6 +93,9 @@ impl Encodable for Error {
9193
Error::InvalidScript => s.begin_list(1).append(&ERROR_ID_INVALID_SCRIPT),
9294
Error::FailedToUnlock(hash) => s.begin_list(1).append(&ERROR_ID_FAILED_TO_UNLOCK).append(hash),
9395
Error::InconsistentTransactionInOut => s.begin_list(1).append(&ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT),
96+
Error::InvalidShardNonce(mismatch) => {
97+
s.begin_list(2).append(&ERROR_ID_INVALID_SHARD_NONCE).append(mismatch)
98+
}
9499
};
95100
}
96101
}
@@ -118,6 +123,12 @@ impl Decodable for Error {
118123
ERROR_ID_INVALID_SCRIPT => Error::InvalidScript,
119124
ERROR_ID_FAILED_TO_UNLOCK => Error::FailedToUnlock(rlp.val_at(1)?),
120125
ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT => Error::InconsistentTransactionInOut,
126+
ERROR_ID_INVALID_SHARD_NONCE => {
127+
if rlp.item_count()? != 2 {
128+
return Err(DecoderError::RlpInvalidLength)
129+
}
130+
Error::InvalidShardNonce(rlp.val_at(1)?)
131+
}
121132
_ => return Err(DecoderError::Custom("Invalid transaction error")),
122133
})
123134
}
@@ -153,6 +164,7 @@ impl Display for Error {
153164
Error::InconsistentTransactionInOut => {
154165
write!(f, "The sum of the transaction's inputs is different from the sum of the transaction's outputs")
155166
}
167+
Error::InvalidShardNonce(mismatch) => write!(f, "The shard nonce {}", mismatch),
156168
}
157169
}
158170
}

0 commit comments

Comments
 (0)