Skip to content

Add FAIL, SUCCESS opcode #378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion spec/CodeChain-Virtual-Machine.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Leading zeros must be truncated. Note that it is allowed to decode value with le
## Special instructions
* NOP(0x00): Do nothing
* BURN(0x01): Stop script execution, and return `BURN` as result.
* SUCCESS(0x02): Stop script execution, and return `SUCCESS` as result.
* FAIL(0x03): Stop script execution, and return `FAIL` as result.

## Boolean computation
* NOT(0x10): Pop one value from stack as boolean, and push negated value.
Expand Down Expand Up @@ -84,4 +86,4 @@ Leading zeros must be truncated. Note that it is allowed to decode value with le
* KECCAK256(0x93): Pop one value from stack, and push keccak-256 hash of it.

## Environment
* BLKNUM(0xa0): Push block number specified in parcel to stack as integer. If there's no specified block number, machine must fail immediately.
* BLKNUM(0xa0): Push block number specified in parcel to stack as integer. If there's no specified block number, machine must fail immediately.
2 changes: 2 additions & 0 deletions vm/src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub fn decode(bytes: &[u8]) -> Result<Vec<Instruction>, DecoderError> {
match *b {
opcode::NOP => result.push(Instruction::Nop),
opcode::BURN => result.push(Instruction::Burn),
opcode::SUCCESS => result.push(Instruction::Success),
opcode::FAIL => result.push(Instruction::Fail),
opcode::NOT => result.push(Instruction::Not),
opcode::EQ => result.push(Instruction::Eq),
opcode::JMP => {
Expand Down
2 changes: 2 additions & 0 deletions vm/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ pub fn execute(
match &script[pc] {
Instruction::Nop => {}
Instruction::Burn => return Ok(ScriptResult::Burnt),
Instruction::Success => return Ok(ScriptResult::Unlocked),
Instruction::Fail => return Ok(ScriptResult::Fail),
Instruction::Not => {
let value: bool = stack.pop()?.into();
stack.push(Item::from(!value))?;
Expand Down
2 changes: 2 additions & 0 deletions vm/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
pub enum Instruction {
Nop,
Burn,
Success,
Fail,
Not,
Eq,
Jmp(u8),
Expand Down
2 changes: 2 additions & 0 deletions vm/src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

pub const NOP: u8 = 0x00;
pub const BURN: u8 = 0x01;
pub const SUCCESS: u8 = 0x02;
pub const FAIL: u8 = 0x03;
pub const NOT: u8 = 0x10;
pub const EQ: u8 = 0x11;
pub const JMP: u8 = 0x20;
Expand Down
2 changes: 2 additions & 0 deletions vm/src/tests/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ macro_rules! test_one_argument_opcode {

test_no_argument_opcode!(NOP, Nop);
test_no_argument_opcode!(BURN, Burn);
test_no_argument_opcode!(SUCCESS, Success);
test_no_argument_opcode!(FAIL, Fail);
test_no_argument_opcode!(NOT, Not);
test_no_argument_opcode!(EQ, Eq);
test_one_argument_opcode!(JMP, Jmp);
Expand Down
8 changes: 7 additions & 1 deletion vm/src/tests/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ use instruction::Instruction;
#[test]
fn simple_success() {
assert_eq!(
execute(&[Instruction::Push(1)], &[], &[], H256::default(), Config::default()),
execute(&[], &[], &[Instruction::Push(1)], H256::default(), Config::default()),
Ok(ScriptResult::Unlocked)
);

assert_eq!(
execute(&[], &[], &[Instruction::Success], H256::default(), Config::default()),
Ok(ScriptResult::Unlocked)
);
}

#[test]
fn simple_failure() {
assert_eq!(execute(&[Instruction::Push(0)], &[], &[], H256::default(), Config::default()), Ok(ScriptResult::Fail));
assert_eq!(execute(&[], &[], &[Instruction::Fail], H256::default(), Config::default()), Ok(ScriptResult::Fail));
}

#[test]
Expand Down