Skip to content
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
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ RUN make test-integration
# Simulation tests
RUN make test-sim-benchmark-simulation
RUN make test-sim-full-app-fast
# Solidity tests
RUN make test-solidity

RUN touch /test.lock

Expand Down
7 changes: 7 additions & 0 deletions tests/solidity/init-node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,18 @@ USER3_MNEMONIC="will wear settle write dance topic tape sea glory hotel oppose r
USER4_KEY="user4"
USER4_MNEMONIC="doll midnight silk carpet brush boring pluck office gown inquiry duck chief aim exit gain never tennis crime fragile ship cloud surface exotic patch"

SOLIDITY_KEY="solidity"
SOLIDITY_MNEMONIC="exercise green picture marriage cause bike credit electric elephant someone march civil radio spoon sail vacant crime man fat save inject into grab drill"

# Import keys from mnemonics
echo "$VAL_MNEMONIC" | "$BINARY" keys add "$VAL_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR"
echo "$USER1_MNEMONIC" | "$BINARY" keys add "$USER1_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR"
echo "$USER2_MNEMONIC" | "$BINARY" keys add "$USER2_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR"
echo "$USER3_MNEMONIC" | "$BINARY" keys add "$USER3_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR"
echo "$USER4_MNEMONIC" | "$BINARY" keys add "$USER4_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR"
if ! "$BINARY" keys show "$SOLIDITY_KEY" --home "$CHAINDIR" >/dev/null 2>&1; then
echo "$SOLIDITY_MNEMONIC" | "$BINARY" keys add "$SOLIDITY_KEY" --recover --algo "$KEYALGO" --home "$CHAINDIR"
fi

# Set moniker and chain-id for Cosmos EVM (Moniker can be anything, chain-id must be an integer)
"$BINARY" init "$MONIKER" --chain-id "$CHAINID" --home "$CHAINDIR"
Expand Down Expand Up @@ -114,6 +120,7 @@ sed -i.bak 's/create_empty_blocks = true/create_empty_blocks = false/g' "$CONFIG
"$BINARY" add-genesis-account "$("$BINARY" keys show "$USER2_KEY" -a --keyring-backend "$KEYRING" --home "$CHAINDIR")" 1000000apoa,1000000000000000000000000000token --keyring-backend "$KEYRING" --home "$CHAINDIR"
"$BINARY" add-genesis-account "$("$BINARY" keys show "$USER3_KEY" -a --keyring-backend "$KEYRING" --home "$CHAINDIR")" 1000000apoa,1000000000000000000000000000token --keyring-backend "$KEYRING" --home "$CHAINDIR"
"$BINARY" add-genesis-account "$("$BINARY" keys show "$USER4_KEY" -a --keyring-backend "$KEYRING" --home "$CHAINDIR")" 1000000apoa,1000000000000000000000000000token --keyring-backend "$KEYRING" --home "$CHAINDIR"
"$BINARY" add-genesis-account "$("$BINARY" keys show "$SOLIDITY_KEY" -a --home "$CHAINDIR")" 1000000apoa,1000000000000000000000000000token --home "$CHAINDIR"

# set custom pruning settings
if [ "$PRUNING" = "custom" ]; then
Expand Down
56 changes: 56 additions & 0 deletions tests/solidity/suites/opcodes/contracts/CancunOpCodes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
pragma solidity >=0.8.24;

contract CancunOpCodes {

// Add a todo to the list
function test() public {

// blobbasefee
assembly { pop(blobbasefee()) }

// mcopy test
assembly {
// Allocate memory for source and destination
let src := mload(0x40)
let dest := add(src, 0x40)
// Store a value at src
mstore(src, 0x123456789abcdef0)
// mcopy(dest, src, 32)
mcopy(dest, src, 32)
// Check that the value was copied
if iszero(eq(mload(dest), 0x123456789abcdef0)) {
revert(0, 0)
}
}

// tstore and tload test (transient storage)
assembly {
let key := 0x42
let val := 0xdeadbeef
tstore(key, val)
let loaded := tload(key)
if iszero(eq(loaded, val)) {
revert(0, 0)
}
}
}

function test_revert() public {

//revert
assembly{ revert(0, 0) }
}

function test_invalid() public {

//revert
assembly{ invalid() }
}

function test_stop() public {

//revert
assembly{ stop() }
}

}
23 changes: 23 additions & 0 deletions tests/solidity/suites/opcodes/contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity >=0.8.24;

contract Migrations {
address public owner;
uint public last_completed_migration;

constructor() public {
owner = msg.sender;
}

modifier restricted() {
if (msg.sender == owner) _;
}

function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}

function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
77 changes: 77 additions & 0 deletions tests/solidity/suites/opcodes/contracts/PragueOpCodes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.24;

library BLS12381 {
address constant G1ADD = address(0x0b);
address constant G1MSM = address(0x0c);
address constant G2ADD = address(0x0d);
address constant G2MSM = address(0x0e);
address constant PAIRING = address(0x0f);
address constant MAP_G1 = address(0x10);
address constant MAP_G2 = address(0x11);

function _pcall(address precompile, bytes memory input, uint outSize)
private view returns (bool ok, bytes memory out)
{
out = new bytes(outSize);
assembly {
ok := staticcall(gas(), precompile, add(input, 0x20), mload(input), add(out, 0x20), outSize)
}
}

function mapToG1(bytes memory fp) internal view returns (bytes memory g1) {
(bool ok, bytes memory out) = _pcall(MAP_G1, fp, 128);
require(ok, "mapToG1 fail"); return out;
}

function g1Add(bytes memory a, bytes memory b) internal view returns (bytes memory sum) {
bytes memory inbuf = bytes.concat(a, b); // 128 + 128 = 256
(bool ok, bytes memory out) = _pcall(G1ADD, inbuf, 128);
require(ok, "g1Add fail"); return out;
}

function pairing(bytes memory inbuf) internal view returns (bool) {
(bool ok, bytes memory out) = _pcall(PAIRING, inbuf, 32);
require(ok, "pairing fail");
return out[31] == 0x01;
}
}

contract PragueOpCodes {
using BLS12381 for bytes;

// 64 zero bytes (a valid Fp element)
bytes constant FP_ZERO = hex"0000000000000000000000000000000000000000000000000000000000000000";

// 128 zero bytes (G1/G2 infinity encodings)
bytes constant G1_INFINITY = hex"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
bytes constant G2_INFINITY = hex"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; // 256B

function test() public {
// BLS12381
bytes memory P = BLS12381.mapToG1(FP_ZERO);
bytes memory S = BLS12381.g1Add(P, G1_INFINITY);
require(keccak256(S) == keccak256(P), "error");

bytes memory inbuf = bytes.concat(G1_INFINITY, G2_INFINITY);
require(BLS12381.pairing(inbuf), "error pairing");
}

function test_revert() public {

//revert
assembly{ revert(0, 0) }
}

function test_invalid() public {

//revert
assembly{ invalid() }
}

function test_stop() public {

//revert
assembly{ stop() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable no-undef */

const Migrations = artifacts.require('Migrations')

module.exports = function (deployer) {
deployer.deploy(Migrations)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* eslint-disable no-undef */

const CancunOpCodes = artifacts.require('./CancunOpCodes.sol')
const PragueOpCodes = artifacts.require('./PragueOpCodes.sol')

module.exports = async function (deployer) {
await deployer.deploy(CancunOpCodes)
await deployer.deploy(PragueOpCodes)
}
26 changes: 26 additions & 0 deletions tests/solidity/suites/opcodes/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "opcodes",
"version": "1.0.0",
"author": "Go Ethereum",
"license": "GPL-3.0-or-later",
"scripts": {
"test-ganache": "yarn truffle test",
"test-cosmos": "yarn truffle test --network cosmos"
},
"devDependencies": {
"truffle-assertions": "^0.9.2"
},
"standard": {
"globals": [
"artifacts",
"expect",
"contract",
"beforeEach",
"before",
"web3",
"it",
"assert",
"describe"
]
}
}
41 changes: 41 additions & 0 deletions tests/solidity/suites/opcodes/test/cancunOpCodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-disable no-undef */
/* eslint-disable no-unused-expressions */

const TodoList = artifacts.require('./CancunOpCodes.sol')
let contractInstance

contract('CancunOpCodes.sol', () => {
beforeEach(async () => {
contractInstance = await TodoList.deployed()
})
it('Should run the majority of opcodes without errors', async () => {
let error
try {
await contractInstance.test()
await contractInstance.test_stop()
} catch (err) {
error = err
}
expect(error).to.be.undefined
})

it('Should throw invalid op code', async () => {
let error
try {
await contractInstance.test_invalid()
} catch (err) {
error = err
}
expect(error).not.to.be.undefined
})

it('Should revert', async () => {
let error
try {
await contractInstance.test_revert()
} catch (err) {
error = err
}
expect(error).not.to.be.undefined
})
})
41 changes: 41 additions & 0 deletions tests/solidity/suites/opcodes/test/pragueOpCodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-disable no-undef */
/* eslint-disable no-unused-expressions */

const TodoList = artifacts.require('./PragueOpCodes.sol')
let contractInstance

contract('PragueOpCodes.sol', () => {
beforeEach(async () => {
contractInstance = await TodoList.deployed()
})
it('Should run the majority of opcodes without errors', async () => {
let error
try {
await contractInstance.test()
await contractInstance.test_stop()
} catch (err) {
error = err
}
expect(error).to.be.undefined
})

it('Should throw invalid op code', async () => {
let error
try {
await contractInstance.test_invalid()
} catch (err) {
error = err
}
expect(error).not.to.be.undefined
})

it('Should revert', async () => {
let error
try {
await contractInstance.test_revert()
} catch (err) {
error = err
}
expect(error).not.to.be.undefined
})
})
28 changes: 28 additions & 0 deletions tests/solidity/suites/opcodes/truffle-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
networks: {
// Development network is just left as truffle's default settings
cosmos: {
host: '127.0.0.1', // Localhost (default: none)
port: 8545, // Standard Ethereum port (default: none)
network_id: 1440002, // Any network (default: none)
gas: 8000000, // Increased gas limit for complex contracts
gasPrice: 0, // Set to 0 for test network
from: "0x5A7E818D849D4926CD2E2E05B8E934D05EE87A7C", // Address derived from the private key
accounts: [
"0x36DC1E881F351CFE35B79E3ED27C8EE737DFD7B48A9F2D43887E25D2F87625CB"
]
}
},
compilers: {
solc: {
version: '0.8.24',
settings: {
evmVersion: 'cancun',
optimizer: {
enabled: false
},
viaIR: false
}
}
}
}
8 changes: 8 additions & 0 deletions tests/solidity/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9400,6 +9400,14 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==

truffle-assertions@^0.9.2:
version "0.9.2"
resolved "https://registry.yarnpkg.com/truffle-assertions/-/truffle-assertions-0.9.2.tgz#0f8360f53ad92b6d8fdb8ceb5dce54c1fc392e23"
integrity sha512-9g2RhaxU2F8DeWhqoGQvL/bV8QVoSnQ6PY+ZPvYRP5eF7+/8LExb4mjLx/FeliLTjc3Tv1SABG05Gu5qQ/ErmA==
dependencies:
assertion-error "^1.1.0"
lodash.isequal "^4.5.0"

truffle@5.5.8:
version "5.5.8"
resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.5.8.tgz#79346b8478d87de1962b57c44dcd057658253716"
Expand Down
Loading