Skip to content
This repository has been archived by the owner on May 4, 2023. It is now read-only.

Feature/enable tests #43

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
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
3,609 changes: 2,190 additions & 1,419 deletions Cargo.lock

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,15 @@ Solidity Smart Contracts unit test harness written in Rust using the native Pari
+ Differences in EVM implementations
- Subtle differences in various EVM implementations _*may*_ lead to different behavior (which would lead to consensus bugs)
- Validating Parity's EVM interpreter implementation is a separate and important project
- Other tools, like Hive and KEVM are better suited for benchmarking/testing EVM implementations
- Other tools, like Hive and KEVM are better suited for benchmarking/testing EVM implementations

## Tools compatibility

+ Solaris can be built and has been tested with the following tools
- Rustc 1.41.0 (5e1a79984 2020-01-27)
- Solidity 0.5.17+commit.d19bba13.Emscripten.clang
- OpenEthereum EVM rev: 4b5e9ddfa66e0e5082281034b148546278c2a315

## Known Issue

- https://github.com/openethereum/openethereum/issues/11631
8 changes: 4 additions & 4 deletions example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ version = "0.1.0"
authors = ["Tomasz Drwięga <[email protected]>"]

[dependencies]
ethabi = { git = "https://github.com/paritytech/ethabi.git" }
ethabi-derive = { git = "https://github.com/paritytech/ethabi.git" }
ethabi-contract = { git = "https://github.com/paritytech/ethabi.git" }
ethabi = "12.0.0"
ethabi-derive = "12.0.0"
ethabi-contract = "11.0.0"
solaris = { path = "../solaris", version = "0.1" }
ethereum-types = "0.3"
ethereum-types = "0.9.0"
rustc-hex = "1.0"

[build-dependencies]
Expand Down
30 changes: 15 additions & 15 deletions example/res/BadgeReg.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! By Gav Wood (Ethcore), 2016.
//! Released under the Apache Licence 2.

pragma solidity ^0.4.17;
pragma solidity ^0.5.17;

import "Owned.sol";

Expand Down Expand Up @@ -33,12 +33,12 @@ contract BadgeReg is Owned {
badges.push(Badge(_addr, _name, _owner));
mapFromAddress[_addr] = badges.length;
mapFromName[_name] = badges.length;
Registered(_name, badges.length - 1, _addr);
emit Registered(_name, badges.length - 1, _addr);
return true;
}

function unregister(uint _id) only_owner public {
Unregistered(badges[_id].name, _id);
emit Unregistered(badges[_id].name, _id);
delete mapFromAddress[badges[_id].addr];
delete mapFromName[badges[_id].name];
delete badges[_id];
Expand All @@ -48,48 +48,48 @@ contract BadgeReg is Owned {
fee = _fee;
}

function badgeCount() constant public returns (uint) { return badges.length; }
function badgeCount() view public returns (uint) { return badges.length; }

function badge(uint _id) constant public returns (address addr, bytes32 name, address owner) {
var t = badges[_id];
function badge(uint _id) view public returns (address addr, bytes32 name, address owner) {
Badge memory t = badges[_id];
addr = t.addr;
name = t.name;
owner = t.owner;
}

function fromAddress(address _addr) constant public returns (uint id, bytes32 name, address owner) {
function fromAddress(address _addr) view public returns (uint id, bytes32 name, address owner) {
id = mapFromAddress[_addr] - 1;
var t = badges[id];
Badge memory t = badges[id];
name = t.name;
owner = t.owner;
}

function fromName(bytes32 _name) constant public returns (uint id, address addr, address owner) {
function fromName(bytes32 _name) view public returns (uint id, address addr, address owner) {
id = mapFromName[_name] - 1;
var t = badges[id];
Badge memory t = badges[id];
addr = t.addr;
owner = t.owner;
}

function meta(uint _id, bytes32 _key) constant public returns (bytes32) {
function meta(uint _id, bytes32 _key) view public returns (bytes32) {
return badges[_id].meta[_key];
}

function setAddress(uint _id, address _newAddr) only_badge_owner(_id) when_address_free(_newAddr) public {
var oldAddr = badges[_id].addr;
address oldAddr = badges[_id].addr;
badges[_id].addr = _newAddr;
mapFromAddress[oldAddr] = 0;
mapFromAddress[_newAddr] = _id;
AddressChanged(_id, _newAddr);
emit AddressChanged(_id, _newAddr);
}

function setMeta(uint _id, bytes32 _key, bytes32 _value) only_badge_owner(_id) public {
badges[_id].meta[_key] = _value;
MetaChanged(_id, _key, _value);
emit MetaChanged(_id, _key, _value);
}

function drain() only_owner public {
msg.sender.transfer(this.balance);
msg.sender.transfer(address(this).balance);
}

mapping (address => uint) mapFromAddress;
Expand Down
4 changes: 2 additions & 2 deletions example/res/Owned.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
//! By Gav Wood, 2016.
//! Released under the Apache Licence 2.

pragma solidity ^0.4.17;
pragma solidity ^0.5.17;

contract Owned {
modifier only_owner { require(msg.sender == owner); _; }

event NewOwner(address indexed old, address indexed current);

function setOwner(address _new) only_owner public { NewOwner(owner, _new); owner = _new; }
function setOwner(address _new) only_owner public { emit NewOwner(owner, _new); owner = _new; }

address public owner = msg.sender;
}
75 changes: 45 additions & 30 deletions example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,26 @@
extern crate ethabi;
#[macro_use]
extern crate ethabi_contract;
#[macro_use]
extern crate ethabi_derive;
extern crate ethereum_types as types;
extern crate ethereum_types;
extern crate rustc_hex;
extern crate solaris;

fn main() {
solaris::main(include_bytes!("../res/BadgeReg_sol_BadgeReg.abi"));
solaris::main(include_bytes!("../res/BadgeReg.abi"));
}

use_contract!(badgereg, "BadgeReg", "res/BadgeReg_sol_BadgeReg.abi");
use_contract!(badgereg, "res/BadgeReg.abi");

#[cfg(test)]
fn setup() -> (solaris::evm::Evm, badgereg::BadgeReg) {
let contract = badgereg::BadgeReg::default();
let code = include_str!("../res/BadgeReg_sol_BadgeReg.bin");
fn setup() -> solaris::evm::Evm {
let code = include_str!("../res/BadgeReg.bin");
let mut evm = solaris::evm();

let owner = 3.into();
let owner = Address::from_low_u64_be(3);
let _address = evm.with_sender(owner).deploy(&code.from_hex().unwrap());

(evm, contract)
evm
}

#[cfg(test)]
Expand All @@ -49,66 +47,83 @@ use solaris::convert;
use solaris::wei;

#[cfg(test)]
use types::{Address, H256, U256};
use ethereum_types::{Address, U256};

#[test]
fn badge_reg_test_fee() {
let (mut evm, contract) = setup();
let mut evm = setup();

use badgereg::functions;

let result_data = evm.call(functions::fee::encode_input(), None).unwrap();
// Initial fee is 1 ETH
assert_eq!(
evm.call(contract.functions().fee()).unwrap(),
functions::fee::decode_output(&result_data).unwrap(),
wei::from_ether(1)
);

// The owner should be able to set the fee
evm.call(contract.functions().set_fee(wei::from_gwei(10)))
.unwrap();

evm.transact(functions::set_fee::encode_input(wei::from_gwei(10)), None).unwrap();

let result_data = evm.call(functions::fee::encode_input(), None).unwrap();
// Fee should be updated
assert_eq!(
evm.call(contract.functions().fee()).unwrap(),
functions::fee::decode_output(&result_data).unwrap(),
wei::from_gwei(10)
);

// Other address should not be allowed to change the fee
evm.with_sender(10.into())
.transact(contract.functions().set_fee(wei::from_gwei(10)))
evm.with_sender(Address::from_low_u64_be(10))
.transact(functions::set_fee::encode_input(wei::from_gwei(15)), None)
.unwrap();

let result_data = evm.call(functions::fee::encode_input(), None).unwrap();
// Fee should not be updated
assert_eq!(
functions::fee::decode_output(&result_data).unwrap(),
wei::from_gwei(10)
);
}

#[test]
fn anyone_should_be_able_to_register_a_badge() {
let (mut evm, contract) = setup();
let mut evm = setup();

use badgereg::functions;

evm.with_value(wei::from_ether(2))
.with_sender(5.into())
.with_sender(Address::from_low_u64_be(5))
.ensure_funds()
.transact(
contract
.functions()
.register(Address::from(10), convert::bytes32("test")),
functions::register::encode_input(Address::from_low_u64_be(10), convert::bytes32("test")),
None
)
.unwrap();

use badgereg::events;

let registerd_logs: Vec<badgereg::logs::Registered> = evm.raw_logs()
.iter()
.filter_map(|log| events::registered::parse_log(log.clone()).ok())
.collect();

assert_eq!(
evm.logs_for_event(badgereg::events::Registered::default())
.len(),
registerd_logs.len(),
1
);

// TODO [ToDr] Perhaps `with_` should not be persistent?
let output = evm.with_value(0.into())
.call(contract.functions().from_name(convert::bytes32("test")))
let result_data = evm.with_value(0.into())
.call(functions::from_name::encode_input(convert::bytes32("test")), None)
.unwrap();

// Test that it was registered correctly
assert_eq!(
output,
functions::from_name::decode_output(&result_data).unwrap(),
(
U256::from(0).into(),
Address::from(10).into(),
Address::from(5).into()
Address::from_low_u64_be(10).into(),
Address::from_low_u64_be(5).into()
)
);
}
18 changes: 10 additions & 8 deletions solaris/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ version = "0.1.0"
authors = ["Tomasz Drwięga <[email protected]>"]

[dependencies]
ethabi = { git = "https://github.com/paritytech/ethabi.git" }
ethcore = { git = "https://github.com/paritytech/parity.git" }
ethcore-transaction = { git = "https://github.com/paritytech/parity.git" }
ethcore-bytes = { git = "https://github.com/paritytech/parity.git" }
ethereum-types = "0.3"
evm = { git = "https://github.com/paritytech/parity.git" }
ethabi = "12.0.0"
ethcore = { git = "https://github.com/openethereum/openethereum.git", rev = "4b5e9ddfa66e0e5082281034b148546278c2a315", features = ["test-helpers"]}
common-types = { git = "https://github.com/openethereum/openethereum.git", rev = "4b5e9ddfa66e0e5082281034b148546278c2a315" }
trace = { git = "https://github.com/openethereum/openethereum.git", rev = "4b5e9ddfa66e0e5082281034b148546278c2a315" }
spec = { git = "https://github.com/openethereum/openethereum.git", rev = "4b5e9ddfa66e0e5082281034b148546278c2a315" }
parity-bytes = "0.1"
ethereum-types = "0.9.0"
evm = { git = "https://github.com/openethereum/openethereum.git", rev = "4b5e9ddfa66e0e5082281034b148546278c2a315" }
lazy_static = "0.2"
vm = { git = "https://github.com/paritytech/parity.git" }
error-chain = "0.11.0"
vm = { git = "https://github.com/openethereum/openethereum.git", rev = "4b5e9ddfa66e0e5082281034b148546278c2a315" }
error-chain = "0.12.0"
4 changes: 1 addition & 3 deletions solaris/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use ethabi;
use ethcore::client::EvmTestError;
use evm;
use ethcore::test_helpers::EvmTestError;

error_chain! {
types {
Expand All @@ -25,7 +24,6 @@ error_chain! {

foreign_links {
Ethabi(ethabi::Error);
TransactError(evm::TransactError);
}

errors {
Expand Down
Loading