Fixing formatting
This commit is contained in:
parent
7e5de5f5c7
commit
1de64ec751
@ -239,118 +239,117 @@ impl Interpreter {
|
|||||||
mem: &mut Memory,
|
mem: &mut Memory,
|
||||||
stack: &Stack<U256>
|
stack: &Stack<U256>
|
||||||
) -> evm::Result {
|
) -> evm::Result {
|
||||||
|
let schedule = ext.schedule();
|
||||||
|
let info = instructions::get_info(instruction);
|
||||||
|
|
||||||
let schedule = ext.schedule();
|
if !schedule.have_delegate_call && instruction == instructions::DELEGATECALL {
|
||||||
let info = instructions::get_info(instruction);
|
return Err(evm::Error::BadInstruction);
|
||||||
|
}
|
||||||
|
if info.tier == instructions::GasPriceTier::InvalidTier {
|
||||||
|
return Err(evm::Error::BadInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
if !schedule.have_delegate_call && instruction == instructions::DELEGATECALL {
|
try!(self.verify_instructions_requirements(&info, schedule.stack_limit, stack));
|
||||||
return Err(evm::Error::BadInstruction);
|
|
||||||
}
|
let tier = instructions::get_tier_idx(info.tier);
|
||||||
if info.tier == instructions::GasPriceTier::InvalidTier {
|
let default_gas = U256::from(schedule.tier_step_gas[tier]);
|
||||||
return Err(evm::Error::BadInstruction);
|
|
||||||
}
|
let cost = match instruction {
|
||||||
|
instructions::SSTORE => {
|
||||||
try!(self.verify_instructions_requirements(&info, schedule.stack_limit, stack));
|
let address = H256::from(stack.peek(0));
|
||||||
|
let val = U256::from(ext.sload(&address).as_slice());
|
||||||
let tier = instructions::get_tier_idx(info.tier);
|
let gas = if self.is_zero(&val) && !self.is_zero(stack.peek(1)) {
|
||||||
let default_gas = U256::from(schedule.tier_step_gas[tier]);
|
schedule.sstore_set_gas
|
||||||
|
} else {
|
||||||
let cost = match instruction {
|
schedule.sstore_reset_gas
|
||||||
instructions::SSTORE => {
|
};
|
||||||
let address = H256::from(stack.peek(0));
|
InstructionCost::Gas(U256::from(gas))
|
||||||
let val = U256::from(ext.sload(&address).as_slice());
|
},
|
||||||
let gas = if self.is_zero(&val) && !self.is_zero(stack.peek(1)) {
|
instructions::SLOAD => {
|
||||||
schedule.sstore_set_gas
|
InstructionCost::Gas(U256::from(schedule.sload_gas))
|
||||||
} else {
|
},
|
||||||
schedule.sstore_reset_gas
|
instructions::MSTORE => {
|
||||||
};
|
InstructionCost::GasMem(default_gas, add_u256_usize(stack.peek(0), 32))
|
||||||
InstructionCost::Gas(U256::from(gas))
|
},
|
||||||
},
|
instructions::MLOAD => {
|
||||||
instructions::SLOAD => {
|
InstructionCost::GasMem(default_gas, add_u256_usize(stack.peek(0), 32))
|
||||||
InstructionCost::Gas(U256::from(schedule.sload_gas))
|
},
|
||||||
},
|
instructions::MSTORE8 => {
|
||||||
instructions::MSTORE => {
|
InstructionCost::GasMem(default_gas, add_u256_usize(stack.peek(0), 1))
|
||||||
InstructionCost::GasMem(default_gas, add_u256_usize(stack.peek(0), 32))
|
},
|
||||||
},
|
instructions::RETURN => {
|
||||||
instructions::MLOAD => {
|
InstructionCost::GasMem(default_gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
||||||
InstructionCost::GasMem(default_gas, add_u256_usize(stack.peek(0), 32))
|
},
|
||||||
},
|
instructions::SHA3 => {
|
||||||
instructions::MSTORE8 => {
|
let words = add_u256_usize(stack.peek(1), 31) / U256::from(32);
|
||||||
InstructionCost::GasMem(default_gas, add_u256_usize(stack.peek(0), 1))
|
let gas = U256::from(schedule.sha3_gas) + (U256::from(schedule.sha3_word_gas) * words);
|
||||||
},
|
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
||||||
instructions::RETURN => {
|
},
|
||||||
InstructionCost::GasMem(default_gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
instructions::CALLDATACOPY => {
|
||||||
},
|
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(0), stack.peek(2)), stack.peek(2).clone())
|
||||||
instructions::SHA3 => {
|
},
|
||||||
let words = add_u256_usize(stack.peek(1), 31) / U256::from(32);
|
instructions::CODECOPY => {
|
||||||
let gas = U256::from(schedule.sha3_gas) + (U256::from(schedule.sha3_word_gas) * words);
|
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(0), stack.peek(2)), stack.peek(2).clone())
|
||||||
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
},
|
||||||
},
|
instructions::EXTCODECOPY => {
|
||||||
instructions::CALLDATACOPY => {
|
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(1), stack.peek(3)), stack.peek(3).clone())
|
||||||
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(0), stack.peek(2)), stack.peek(2).clone())
|
},
|
||||||
},
|
instructions::JUMPDEST => {
|
||||||
instructions::CODECOPY => {
|
InstructionCost::Gas(U256::one())
|
||||||
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(0), stack.peek(2)), stack.peek(2).clone())
|
},
|
||||||
},
|
instructions::LOG0...instructions::LOG4 => {
|
||||||
instructions::EXTCODECOPY => {
|
let no_of_topics = instructions::get_log_topics(instruction);
|
||||||
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(1), stack.peek(3)), stack.peek(3).clone())
|
let log_gas = schedule.log_gas + schedule.log_topic_gas * no_of_topics;
|
||||||
},
|
let data_gas = stack.peek(1).clone() * U256::from(schedule.log_data_gas);
|
||||||
instructions::JUMPDEST => {
|
let gas = data_gas + U256::from(log_gas);
|
||||||
InstructionCost::Gas(U256::one())
|
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
||||||
},
|
},
|
||||||
instructions::LOG0...instructions::LOG4 => {
|
instructions::CALL | instructions::CALLCODE => {
|
||||||
let no_of_topics = instructions::get_log_topics(instruction);
|
let gas = add_u256_usize(stack.peek(0), schedule.call_gas + schedule.call_value_transfer_gas);
|
||||||
let log_gas = schedule.log_gas + schedule.log_topic_gas * no_of_topics;
|
let mem = cmp::max(
|
||||||
let data_gas = stack.peek(1).clone() * U256::from(schedule.log_data_gas);
|
self.mem_needed(stack.peek(5), stack.peek(6)),
|
||||||
let gas = data_gas + U256::from(log_gas);
|
self.mem_needed(stack.peek(3), stack.peek(4))
|
||||||
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
);
|
||||||
},
|
InstructionCost::GasMem(gas, mem)
|
||||||
instructions::CALL | instructions::CALLCODE => {
|
},
|
||||||
let gas = add_u256_usize(stack.peek(0), schedule.call_gas + schedule.call_value_transfer_gas);
|
instructions::DELEGATECALL => {
|
||||||
let mem = cmp::max(
|
let gas = add_u256_usize(stack.peek(0), schedule.call_gas);
|
||||||
self.mem_needed(stack.peek(5), stack.peek(6)),
|
let mem = cmp::max(
|
||||||
self.mem_needed(stack.peek(3), stack.peek(4))
|
self.mem_needed(stack.peek(4), stack.peek(5)),
|
||||||
);
|
self.mem_needed(stack.peek(2), stack.peek(3))
|
||||||
InstructionCost::GasMem(gas, mem)
|
);
|
||||||
},
|
InstructionCost::GasMem(gas, mem)
|
||||||
instructions::DELEGATECALL => {
|
},
|
||||||
let gas = add_u256_usize(stack.peek(0), schedule.call_gas);
|
instructions::CREATE => {
|
||||||
let mem = cmp::max(
|
let gas = U256::from(schedule.create_gas);
|
||||||
self.mem_needed(stack.peek(4), stack.peek(5)),
|
let mem = self.mem_needed(stack.peek(1), stack.peek(2));
|
||||||
self.mem_needed(stack.peek(2), stack.peek(3))
|
InstructionCost::GasMem(gas, mem)
|
||||||
);
|
},
|
||||||
InstructionCost::GasMem(gas, mem)
|
instructions::EXP => {
|
||||||
},
|
let expon = stack.peek(1);
|
||||||
instructions::CREATE => {
|
// TODO [todr] not sure how to calculate that
|
||||||
let gas = U256::from(schedule.create_gas);
|
let gas = U256::from(schedule.exp_gas);
|
||||||
let mem = self.mem_needed(stack.peek(1), stack.peek(2));
|
InstructionCost::Gas(gas)
|
||||||
InstructionCost::GasMem(gas, mem)
|
},
|
||||||
},
|
_ => InstructionCost::Gas(default_gas)
|
||||||
instructions::EXP => {
|
};
|
||||||
let expon = stack.peek(1);
|
|
||||||
// TODO [todr] not sure how to calculate that
|
match cost {
|
||||||
let gas = U256::from(schedule.exp_gas);
|
InstructionCost::Gas(gas) => {
|
||||||
InstructionCost::Gas(gas)
|
Ok(gas)
|
||||||
},
|
},
|
||||||
_ => InstructionCost::Gas(default_gas)
|
InstructionCost::GasMem(gas, mem_size) => {
|
||||||
};
|
mem.expand(mem_size);
|
||||||
|
let mem_gas = self.mem_gas_cost(schedule, mem.size(), &mem_size);
|
||||||
match cost {
|
Ok(gas + mem_gas)
|
||||||
InstructionCost::Gas(gas) => {
|
},
|
||||||
Ok(gas)
|
InstructionCost::GasMemCopy(gas, mem_size, copy) => {
|
||||||
},
|
mem.expand(mem_size);
|
||||||
InstructionCost::GasMem(gas, mem_size) => {
|
let mem_gas = self.mem_gas_cost(schedule, mem.size(), &mem_size);
|
||||||
mem.expand(mem_size);
|
let copy_gas = U256::from(schedule.copy_gas) * (add_u256_usize(©, 31) / U256::from(32));
|
||||||
let mem_gas = self.mem_gas_cost(schedule, mem.size(), &mem_size);
|
Ok(gas + copy_gas + mem_gas)
|
||||||
Ok(gas + mem_gas)
|
|
||||||
},
|
|
||||||
InstructionCost::GasMemCopy(gas, mem_size, copy) => {
|
|
||||||
mem.expand(mem_size);
|
|
||||||
let mem_gas = self.mem_gas_cost(schedule, mem.size(), &mem_size);
|
|
||||||
let copy_gas = U256::from(schedule.copy_gas) * (add_u256_usize(©, 31) / U256::from(32));
|
|
||||||
Ok(gas + copy_gas + mem_gas)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mem_gas_cost(&self, schedule: &evm::Schedule, current_mem_size: usize, mem_size: &U256) -> U256 {
|
fn mem_gas_cost(&self, schedule: &evm::Schedule, current_mem_size: usize, mem_size: &U256) -> U256 {
|
||||||
@ -380,14 +379,14 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exec_instruction(&self,
|
fn exec_instruction(&self,
|
||||||
gas: Gas,
|
gas: Gas,
|
||||||
params: &ActionParams,
|
params: &ActionParams,
|
||||||
ext: &mut evm::Ext,
|
ext: &mut evm::Ext,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
code: &mut CodeReader,
|
code: &mut CodeReader,
|
||||||
mem: &mut Memory,
|
mem: &mut Memory,
|
||||||
stack: &mut Stack<U256>
|
stack: &mut Stack<U256>
|
||||||
) -> Result<InstructionResult, evm::Error> {
|
) -> Result<InstructionResult, evm::Error> {
|
||||||
match instruction {
|
match instruction {
|
||||||
instructions::JUMP => {
|
instructions::JUMP => {
|
||||||
let jump = stack.pop_back();
|
let jump = stack.pop_back();
|
||||||
@ -446,13 +445,13 @@ impl Interpreter {
|
|||||||
let out_size = stack.pop_back();
|
let out_size = stack.pop_back();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
// we need to write and read from memory in the same time
|
// we need to write and read from memory in the same time
|
||||||
// and we don't want to copy
|
// and we don't want to copy
|
||||||
let input = unsafe { ::std::mem::transmute(mem.read_slice(in_off, in_size)) };
|
let input = unsafe { ::std::mem::transmute(mem.read_slice(in_off, in_size)) };
|
||||||
let output = mem.writeable_slice(out_off, out_size);
|
let output = mem.writeable_slice(out_off, out_size);
|
||||||
try!(
|
try!(
|
||||||
ext.call(&gas, &call_gas, address, &value, input, &code_address, output)
|
ext.call(&gas, &call_gas, address, &value, input, &code_address, output)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
return Ok(InstructionResult::AdditionalGasCost(
|
return Ok(InstructionResult::AdditionalGasCost(
|
||||||
gas - gas_left
|
gas - gas_left
|
||||||
@ -611,9 +610,9 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn copy_data_to_memory(&self,
|
fn copy_data_to_memory(&self,
|
||||||
mem: &mut Memory,
|
mem: &mut Memory,
|
||||||
stack: &mut Stack<U256>,
|
stack: &mut Stack<U256>,
|
||||||
data: &Bytes) {
|
data: &Bytes) {
|
||||||
let offset = stack.pop_back();
|
let offset = stack.pop_back();
|
||||||
let index = stack.pop_back().low_u64() as usize;
|
let index = stack.pop_back().low_u64() as usize;
|
||||||
let size = stack.pop_back().low_u64() as usize;
|
let size = stack.pop_back().low_u64() as usize;
|
||||||
@ -622,9 +621,9 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn verify_instructions_requirements(&self,
|
fn verify_instructions_requirements(&self,
|
||||||
info: &instructions::InstructionInfo,
|
info: &instructions::InstructionInfo,
|
||||||
stack_limit: usize,
|
stack_limit: usize,
|
||||||
stack: &Stack<U256>) -> Result<(), evm::Error> {
|
stack: &Stack<U256>) -> Result<(), evm::Error> {
|
||||||
if !stack.has(info.args) {
|
if !stack.has(info.args) {
|
||||||
Err(evm::Error::StackUnderflow {
|
Err(evm::Error::StackUnderflow {
|
||||||
instruction: info.name,
|
instruction: info.name,
|
||||||
@ -768,14 +767,14 @@ impl Interpreter {
|
|||||||
// TODO instructions::SIGNEXTEND => {},
|
// TODO instructions::SIGNEXTEND => {},
|
||||||
_ => panic!(format!("Unknown stack instruction: {:x}", instruction))
|
_ => panic!(format!("Unknown stack instruction: {:x}", instruction))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_jump_destinations(&self, code : &Bytes) -> HashSet<CodePosition> {
|
fn find_jump_destinations(&self, code : &Bytes) -> HashSet<CodePosition> {
|
||||||
let mut jump_dests = HashSet::new();
|
let mut jump_dests = HashSet::new();
|
||||||
let mut position = 0;
|
let mut position = 0;
|
||||||
|
|
||||||
while position < code.len() {
|
while position < code.len() {
|
||||||
let instruction = code[position];
|
let instruction = code[position];
|
||||||
|
|
||||||
if instruction == instructions::JUMPDEST {
|
if instruction == instructions::JUMPDEST {
|
||||||
jump_dests.insert(position);
|
jump_dests.insert(position);
|
||||||
@ -783,10 +782,10 @@ impl Interpreter {
|
|||||||
position += instructions::get_push_bytes(instruction);
|
position += instructions::get_push_bytes(instruction);
|
||||||
}
|
}
|
||||||
position += 1;
|
position += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return jump_dests;
|
return jump_dests;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user